Skip to content

Result format ​

GET /v1/jobs/{id}/result returns JSON. A shortened example for a stereo call with every option on:

json
{
  "schema_version": "gapi_task_result.v0",
  "audio_seconds": 282.7,
  "speech_seconds": 230.4,
  "channels": 2,
  "stereo_parties": true,
  "speakers": 2,
  "vocabulary_terms": 4,
  "vocabulary_dropped": false,
  "text": "Assalomu alaykum, Metasell kompaniyasi. …",
  "language": {"code": "uz", "confidence": 0.97, "speech_seconds": 230.4, "share": {"uz": 0.91, "ru": 0.09}, "posterior": {"uz": 0.97, "ru": 0.03}},
  "call_outcome": {"outcome": "conversation", "reached": true, "confidence": 0.99, "probabilities": {"conversation": 0.99, "no_answer": 0.004, "operator_message": 0.003, "ivr": 0.003}, "answer_at": 11.4, "seconds": 180.0},
  "segments": [
    {
      "index": 0,
      "start": 0.42,
      "end": 3.9,
      "speaker": 1,
      "text": "Assalomu alaykum, Metasell kompaniyasi.",
      "raw_asr_text": "assalomu alaykum metasell kompaniyasi",
      "formatted_text": "Assalomu alaykum, Metasell kompaniyasi.",
      "pii": {"entities": [], "redacted_text": "Assalomu alaykum, Metasell kompaniyasi."},
      "language": {"code": "uz", "confidence": 0.99}
    }
  ],
  "speaker_info": [
    {
      "index": 0,
      "speech_seconds": 149.2,
      "gender": {"label": "male", "confidence": 0.97},
      "role": "client",
      "identity": {"status": "new", "voice_id": 100, "speaker_id": "e3db…", "name": null},
      "has_voiceprint": true,
      "clarity": {"scored_words": 412, "low_confidence_share": 0.071, "estimated_error_share": 0.118, "speech_rate": 5.6,
                  "line_quality": {"snr_db": 31.5, "clipping_share": 0.0, "bandwidth_hz": 3850, "band": "telephone"}}
    }
  ],
  "voices": [
    {"label": "SPEAKER_1", "speaker": 0, "voice_id": 100, "name": null, "status": "new"},
    {"label": "SPEAKER_2", "speaker": 1, "voice_id": 101, "name": "Azimbek", "status": "matched", "score": 0.97}
  ],
  "options_report": {"requested": ["gender", "speaker_roles", "speaker_identification", "pii", "language_detection", "call_outcome"], "errors": {}, "seconds": 1.8},
  "timing": {"decode_seconds": 0.3, "vad_seconds": 0.4, "stt_seconds": 2.1, "total_seconds": 4.9}
}

The text comes in Latin script: the model is trained on Latin-script Uzbek, and every option (punctuation, numbers, personal data) works on it. There is no Cyrillic output.

Top level ​

FieldWhat it is
audio_secondsLength of the recording; the charge in g is worked out from it
speech_secondsHow much of it is speech
channels, stereo_partiesChannels in the file; true when the sides are separated by channel
speakersHow many voices speaker separation found
textAll text in a row
segmentsUtterances in order
speaker_infoA summary per speaker of the recording: what the options found, and clarity whenever the speakers are known
languageThe recording's main spoken language and the share of each language, with Spoken language; see Options
call_outcomeWhether a live conversation took place and, if not, what played instead; the second the other side answered. With Call outcome; see Options
voice_eventsLaughter, dissatisfaction and voice energy: `[{"type": "laughter"
summaryA short summary of the call: {"text", "lines", "read_lines"}, with "Call summary"; see Options
voicesPermanent project voice numbers, with "Recognise by voice"
optionsThe settings the recording was actually run with: the project plus the request's settings. Every key from the Options page is here — stereo_channels_as_speakers, max_speakers, call_direction and fuzzy_itn (loose number normalisation, off by default) included
tenantThe integrator's business the recording belongs to, when the job named one; see Tenants
vocabulary_terms, vocabulary_droppedHow many vocabulary terms the job took; the second is true when the cleaning left none
diarization_errortrue when speaker separation did not work: the recording will carry no speaker numbers. When it worked, the field is there and is null
options_reportWhich options were requested, which were not computed and why
segment_voiceprintsWhich utterances have a voice print: {"dims", "format", "min_seconds", "segments": [indexes]}. The prints themselves never leave the gateway — this is the list of utterances a voice can be enrolled from with POST /v1/speakers/{id}/enroll and segment_indexes
timingHow many seconds processing took: decode_seconds, vad_seconds, stt_seconds, format_seconds, diarization_seconds, total_seconds. We measure ourselves by these, not you

options_report shows what was requested (requested), what could not be computed and why (errors), and how many seconds the options took (seconds). When roles were requested it also carries roles: the status, a calibrated score (the probability that the roles are assigned the right way round) and the fields described under Client and manager. Take each speaker's role from speaker_info[].role.

Alongside them sit diagnostic fields — word_timing, formatting, partial. They are there for looking into our own tickets: what they hold may change, so do not build logic on them.

Utterance ​

FieldWhat it is
indexOrdinal, from 0
start, endSeconds from the start of the recording
speakerSpeaker number of the recording, or null
textFinal text with the options applied
raw_asr_textWhat the model heard: lower-case, no punctuation
formatted_textWith punctuation and capitals
wordsWords with timing, with word_timestamps; see below
speaker_shareWhat share of the utterance's speech speaker separation itself placed with this speaker, 0 to 1; the rest was carried over from neighbouring words. Present only where speakers were computed
contextual_textThe text after the vocabulary, before punctuation and numbers: between raw_asr_text and formatted_text
duration_bucket_secondsA length bucket for our own telemetry
emotionOnly when the request sends the removed emotion key: always {"label": null, "reason": "removed"}; see Emotions (removed)
pii{"entities", "redacted_text"}, with Personal data
language{"code", "confidence"}, with Spoken language; an utterance under a second carries {"code": null, "reason": "too_short"}

pii labels: NAME, PHONE, ADDRESS, DATE, DOCUMENT_ID, CARD_NUMBER.

A word ​

json
{"text": "kredit", "raw": "kredit", "formatted": "kredit", "start": 12.40, "end": 12.81, "speaker": 0, "aligned": "exact", "confidence": 0.93}
{"text": "Uzum", "raw": "uzim", "formatted": "Uzum", "start": 4.12, "end": 4.51, "speaker": 1, "aligned": "term", "confidence": null}
FieldWhat it is
textThe word after the vocabulary, before punctuation
rawWhat the model heard in its place; an inserted word has no such field
formattedThe same with capitals and punctuation, once the utterance is formatted
start, endSeconds from the start of the recording
speakerSpeaker number, where speakers were computed
alignedWhere the word's timing came from
confidenceThe probability, from 0 to 1, that the word was transcribed correctly; null when it is not the model's own word (see below)

aligned is worth reading: exact — the model's own frames for that very word; term — the word came from the vocabulary and is timed by the term spotter's frames, which is direct evidence that the term was applied; span — its share of the raw words that were rewritten; chunk — the bundle gave no usable words for that piece, so the whole piece shares its timing; none — inserted with no acoustic evidence, zero length.

Word confidence. confidence is the probability, from 0 to 1, that the word was transcribed correctly. It is calibrated on human-checked call recordings: of all words marked 0.8, about eight in ten are right. Only the model's own words carry one (aligned: exact). A word that the corrector or your vocabulary put in place of what was heard (span, term), one inserted with no acoustic evidence (none) and a piece with no usable words (chunk) have confidence: null, because there is no acoustic score for them. Words the corrector rewrote are right noticeably less often than the model's own, so a null is worth a look too.

What confidence measures. It measures how sure the recognizer was about what it heard, not how well the person spoke. A narrow phone line, noise, a quiet or clipping microphone, crosstalk, rare names and words switched into Russian or English all lower it, just as unclear speech does. A high share of low-confidence words on one call means that speaker's transcript is less reliable. On its own, it is not evidence of poor diction.

Speaker of the recording ​

FieldWhat it is
indexSpeaker number, the same as in utterances
speech_secondsHow long they spoke
gender{"label": "female" | "male" | "unknown", "confidence", "reason", "windows", "speech_seconds", "probabilities"}. With unknown, confidence is null and reason says why
role"client", "manager", "machine" (a voice heard only before a live person picked up: a voice menu, a network announcement), "other" (a live voice beyond the two parties) or "unknown". See Client and manager
identity{"status", "voice_id", "speaker_id", "name", "score", "threshold", "runner_up", "kind"}
has_voiceprintThe speaker spoke enough for a voice print: this one can be enrolled, see Voices and speakers. The print itself never leaves the gateway
emotionOnly with the removed emotion key: {"dominant_mood": null, "mood_share": {}, "valence": null, "arousal": null, "dominance": null, "reason": "removed"}
language{"code", "confidence", "seconds"}, the language over all of the speaker's speech; under two seconds of speech gives {"code": null, "reason": "insufficient_speech"}
clarityHow sure the recognizer was of this speaker's words, beside the quality of the line they came over; see Clarity

identity.status answers one question: was this person recognised, and if not, why not.

StatusWhat happenedIs there a voice_id
matchedThe print matched a voice of the projectyes, the number of the known voice
newNo match, but there was enough speech: the voice was registered by this recording and will be recognised from now onyes, a new number
unknownNo match, and under 10 seconds of speech — registering a voice on a print that short is unreliableno
insufficient_speechNo print could be computed at all: there is next to no speechno
no_enrolled_voicesThe project has no voices yet, so there is nothing to compare againstno

The difference between unknown and insufficient_speech is that the first has a print and the comparison ran — the person is simply not known and the speech is too short to register them; in the second there was nothing to compute from.

matched and unknown carry score, the closeness to the nearest voice from 0 to 1, and threshold, the point from which a match counts. If score sits just under the threshold again and again, the voice is short of prints: add another from a good recording.

With known_speakers (staff only) identity speaks of the tenant's staff lines: status is matched, not_matched, not_enrolled (the named line has no voice yet) or insufficient_speech; a match carries external_id, role, voice (which of the line's people, 1–4) and expected, threshold is 0.65, and runner_up is the other speaker of the call against the same line. Nobody but staff gets a voice_id, and has_voiceprint is absent: no print of such a recording is kept.

Beside them is runner_up, the closeness to the second most similar voice (-1 when there was nothing to compare with). A match counts only when the first beat the second by a margin: two similar voices must not win against each other by chance. matched and new also carry kind — what sort of voice this is in the project: candidate, recurring or named, see Voices and speakers.

Clarity: recognition certainty per speaker ​

speaker_info[].clarity is computed for every recording whose speakers are known — a stereo call with the parties on separate channels, or a mono one with speaker separation on — whatever options are on, at no extra charge.

json
"clarity": {
  "scored_words": 412,
  "low_confidence_share": 0.071,
  "estimated_error_share": 0.118,
  "speech_rate": 5.6,
  "line_quality": {"snr_db": 31.5, "clipping_share": 0.0, "bandwidth_hz": 3850, "band": "telephone"}
}
FieldWhat it is
scored_wordsThe speaker's words that carry a confidence
low_confidence_shareThe share of them below 0.5, that is, more likely wrong than right
estimated_error_shareThe mean of 1 - confidence over them: the share of them expected to be wrong
reasoninsufficient_words when there are fewer than 40 of them; both shares are then null
speech_rateSyllables (vowel letters) per second of the speaker's own speech
line_quality.snr_dbHow much louder the speech peaks are than the pauses between words within the speaker's turns, in dB
line_quality.clipping_shareThe share of the speaker's speech with samples at full scale: an overloaded microphone or line
line_quality.bandwidth_hzHow high in frequency the speaker's voice reaches on this line
line_quality.bandnarrow below 3,800 Hz, telephone from 3,800 to 4,500 Hz, wide from 4,500 Hz

Everything is measured over the speaker's own turns across the whole recording, leaving out the moments when someone else speaks at the same time. On a stereo call each party's line is their own channel. With under a second of such speech, line_quality and speech_rate are null.

Separating the line from the speaker. The shares stand next to line_quality, measured from the same speaker's audio. We do not subtract the line from them: in our measurements it explains little of them. The line property that mattered most was bandwidth: speakers on a narrow line had nearly twice the low-confidence share of the others. Across the noise levels found in ordinary calls, the noise level made no visible difference. Nearly half of the variation between speakers is shared by both people on the same call, so it belongs to the call, not the person. Compare people on the same band. Judge a person over many calls, not one, and against the other party of the same calls. A speaker who is clearly above the person they talk to, call after call, on the same kind of line, is the case worth attention.

Limits. Shares are not given under 40 scored words, and they stay noisy up to about 100: plus or minus 4 points at 40 words, 2.5 at 100. In mono recordings, speaker separation puts about one word in twenty on the wrong person; stereo recordings with one party per channel do not have this problem. Speech rate is counted from recognised words, so it reads low where recognition failed. The calibration is for Uzbek call audio and the current version of the recognizer, and it is redone whenever the recognizer changes.

Emotions (removed) ​

The Emotions option was removed on 10 October 2026: demand for it was low, and emotions in calls proved hard to detect reliably. The emotion key is still accepted so that integrations do not break, and it costs nothing. A request that sends it gets a stub in the old fields: {"label": null, "reason": "removed"} on every utterance, the speaker summary with null values and an empty mood_share in speaker_info[].emotion, and options_report.emotion = {"status": "removed"}. The key will be removed later; see Options.

Before the job is done ​

GET /v1/jobs/{id}/result answers only for a finished job; while it runs you get 409 result_not_ready. Utterances as they are finished come from GET /v1/jobs/{id}/events: see API.