Calls
Speech To Text
Speech To Text is the transcript NUACOM produces from a call recording, together with the analysis built on it: summary, topics, action items, sentiment per utterance and talk time per party. This group holds the transcript endpoint, a search-and-highlight variant and, under Speech To Text / Subscription, the endpoints that manage the AI Analysis add-on that enables transcription. Call AI returns a condensed view of the same data; the audio is in Call Recording and the call ids come from Call Logs.
Workflow (what the portal does)
- Check the subscription:
GET /v2/speech-to-text/activereturns the active AI Analysis add-on asaddon_id,addon_name,addon_price,added_dateandqty, or{"addon_id": 0}when there is none. - Open a transcript: from a
GET /v2/call-logrow withrecording: true(the list'shas_transcriptionsfilter narrows it to transcribed calls), callGET /v2/speech-to-text/{callUniqueId}with the row'scall_id. The document is described below. - Search inside it:
POST /v2/speech-to-text/{callUniqueId}/highlightwith{"search": "invoice"}answers the same document only when it matches, with every match wrapped in<span class='qmatch'>…</span>insidesummary,topics,actionItemsand the utterances. The query syntax is below. - Change the subscription (admins): see Subscription.
curl -X POST 'https://api.api-nuacom.com/v2/speech-to-text/svr13-core2-1753839825.12345/highlight' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"search": "\"invoice\" + \"refund\""}'
Reading a transcript
| Field | Content |
|---|---|
combinedRecognizedPhrases |
One entry whose display is the whole transcript as plain text. |
recognizedPhrases |
One entry per utterance: channel and speaker, offset and duration as ISO 8601 durations (PT12.5S), offsetInTicks and durationInTicks (one tick is 100 ns, 10,000,000 per second), and nBest with display (the text), words (each with its own offset and duration) and sentiment (sentiment and confidence). |
summary |
A few sentences describing the call, or the placeholder Unable to summarize. Recording is too short or lacks conversational content.. |
topics, conversationTopics |
Labels for what was discussed. Some transcripts fill only conversationTopics; read both. |
actionItems |
Follow-ups extracted from the conversation, as a list of strings; "" when none were extracted. |
sentiment |
positive, neutral or negative for the whole call; unknown when none was computed. |
talkTime |
One entry per channel with channel, talkTimeDurationInTicks and percentage, the integer share of the speaking time; null when not computed. |
balance |
The account's AI allowance: null without an AI Analysis add-on, 1 with a paid one, otherwise the remaining free allowance, 0 or less once it is used up. |
doc |
Unused, always []. |
A call that has no transcript answers 200 with the empty defaults (summary "", lists [], sentiment "unknown", talkTime null) and balance still filled. It is not a 404.
Search syntax
| Query | Matches |
|---|---|
invoice |
Plain text is matched as a phrase, case-insensitively, allowing up to two words between the terms. |
"late payment" |
A quoted phrase, same rules. |
"invoice" + "refund" |
Both phrases. |
"invoice" | "refund" |
Either phrase. |
-"refund" |
The phrase must be absent. |
"invoice" + (-"refund") |
The first phrase present and the second absent. |
Operators only work on double-quoted terms; a +, | or - next to an unquoted word is searched as text. A term matches in any of summary, the utterances, topics or actionItems.
When a call is transcribed
A recording is transcribed when the account has an active AI Analysis add-on:
- Unlimited AI Call Analysis, a paid add-on: every recorded call.
- Free AI Call Analysis: an allowance of minutes, reset monthly. The duration of each transcribed call is deducted from it; once the allowance is used up new calls are no longer transcribed, while existing transcripts stay readable.
Transcription starts in the background once the recording is stored and takes a while, so a row that already shows recording: true can still have no transcript. The transcript is produced in the language configured for the account: English unless an admin set a default call language or per-number overrides with POST /v2/account-language-config (where enabled for the account; GET /v2/language-options lists the choices). The summary, topics, action items and sentiment are generated from that transcript.
Subscription
Two AI Analysis add-ons exist: Free AI Call Analysis (addon_id 1124, no charge, a monthly allowance of minutes) and Unlimited AI Call Analysis (addon_id 1128, a monthly price per extension). Only one is active at a time; activating one cancels the other.
Subscription states:
stateDiagram-v2
[*] --> None: no AI Analysis add-on
None --> Free: upgrade addon_id 1124 (no charge)
None --> Unlimited: upgrade addon_id 1128 (charged pro-rata)
Free --> Unlimited: upgrade addon_id 1128
Unlimited --> Free: downgrade addon_id 1124 (no charge)
Free --> None: DELETE /v2/speech-to-text/deactivate
Unlimited --> None: DELETE /v2/speech-to-text/deactivate
GET /v2/speech-to-text/calculate/{addonId}prices an activation from today to the end of the month:unitPrice(the monthly price),cleanAmount(the pro-rata part for the remaining days; the full price on the 1st),extensionsCount(the account's extensions),subTotal(cleanAmount×extensionsCount),accountVatRate,vatAmount(VAT oncleanAmount),total(subTotalplus VAT),billingPeriodStart,billingPeriodEnd,billingCurrency,addonName,transactionNameandisNextMonth(false). An id that is not an AI Analysis add-on offered to your account answers400{"message": "Addon not found"}.POST /v2/speech-to-text/upgradewithaddon_idand, for a paid add-on on a pre-pay account,paymentMethod(the id of one of the account's saved payment methods). It cancels the current AI add-on and its pending charges, activates the new one, sets the free allowance when the add-on has one, and charges the pro-rata amount at once when it has a price: a pre-pay account's payment method is charged immediately, a bill-pay account is billed for it.204.POST /v2/speech-to-text/downgradewithaddon_idmakes the same switch without a charge.204.DELETE /v2/speech-to-text/deactivatecancels every active AI Analysis add-on and any upcoming charge.204.
upgrade and downgrade answer 422 with errors when addon_id is not an AI Analysis add-on (Wrong addon type.), is already active (This addon is already active.) or, on a pre-pay account activating a paid add-on, when paymentMethod is missing or unknown (Invalid payment method.). An addon_id that does not exist, or that is not offered to your account, answers 404. A declined card answers 400 with an error_code.
Roles and access
- Transcript and highlight: any authenticated user who may listen to the recording. Account admins always may; other users need the Call Recording Access setting on their user, and the call must be visible to them (own extension, or the numbers, extensions and queues granted to them; call-log permission "all" covers every call). Otherwise
403, also for an id that does not exist; the highlight endpoint saysYou are not authorized to access information about this call.. Accounts with the No Recordings add-on get403for every call. active: any authenticated user; the answer includes the add-on's price.calculate,upgrade,downgradeanddeactivate: account admins only; anyone else gets403"Forbidden".
Pitfalls
{callUniqueId}is the call-log row'scall_id, the telephony id shared by the legs of one call;call_unique_idfinds nothing.- Nothing distinguishes "not transcribed yet" from "never will be": both answer
200with empty fields. TestrecognizedPhrasesrather than the status code, and treat the placeholder summary as "no summary". - The highlight markup is inside the strings (
<span class='qmatch'>…</span>): strip it before reuse.balanceis always0in that response. upgradecharges without a preview: callcalculatefirst and show thetotalto the user. Switching to the Free add-on resets its allowance to the monthly amount.deactivatetakes effect at once: transcription stops for new calls, existing transcripts stay readable.added_dateinactiveis a plainY-m-d H:i:sstring unless the account has the ISO dates option, which renders it in ISO 8601 in the requested timezone.