Options
Options are set for a project on the cabinet's "Settings" tab and apply to every recording. For one recording they can be changed: in the cabinet in the "Transcription options" block, in the API with the settings field of the upload. The keys are the same.
| Key | Option (and the cabinet's own label) | Tariff |
|---|---|---|
formatting | Punctuation and capitals | ×1 |
itn | Numbers, dates and amounts as digits | ×1 |
stereo_channels_as_speakers | Stereo channels are the parties | ×1 |
diarization, max_speakers | Speaker separation — "Speaker separation" | ×1 |
gender | Voice gender — "Voice gender" | ×1 |
language_detection | Spoken language — "Spoken language" | ×1 |
call_outcome | Call outcome — "Call outcome" | ×1 |
speaker_roles, call_direction | Client and manager — "Client and agent" | ×1 |
speaker_identification | Recognise by voice — "Recognise by voice" | ×1 |
voice_events | Emotions: laughter, dissatisfaction and energy (beta) — "Emotions" | ×1.2 |
summary | Call summary — "Call summary" | ×1.3 |
word_timestamps | Time of every word | ×1 |
webhook_url | Address notified when a job finishes | ×1 |
pii | Personal data — "Personal data" | ×1.2 |
emotion | Removed: accepted, returns a stub | ×1 |
A new project has everything on, the paid options included. Until Personal data is switched off, every recording runs at ×1.2. Switch it off on the "Settings" tab of the cabinet, or pass "pii": false in the project settings or in a single request.
The cabinet does not show the first three: formatting, itn and stereo_channels_as_speakers are always on, because there is almost never a reason to turn them off — they cost nothing and do not spoil the text. If you do need to, it is the API's settings field only.
Punctuation and capitals
A separate model places full stops, commas and question marks and capitalises the first letter of sentences and names. The recognised words do not change.
In the result: segments[].formatted_text and the overall text. Without the option the text is lower-case with no punctuation.
Numbers, dates and amounts as digits
"ikki ming yigirma olti" becomes "2026", "besh yuz ming so'm" becomes "500 000 so'm". Rule-based, in strict mode: when a rule is unsure the words stay words. Applied after punctuation.
Stereo channels are the parties
For two-channel recordings where the sides are already split between the channels — usually telephony: the left channel is one side, the right the other. Each channel is recognised on its own and gets speaker number 0 or 1. More accurate than any separation by voice, because telephony already separated the sides.
Changes nothing for mono recordings. The result carries stereo_parties: true.
Speaker separation
For mono recordings with several voices. The model listens to the whole recording, divides the speech between voices by timbre, and every utterance gets a speaker number: 0, 1, 2, 3. Up to four voices.
max_speakers tells the model how many voices to look for. If you know it is a conversation of two, set 2: the model will not find extra ones. Default 0, the model decides.
Two-channel recordings do not need it: the channels are the two parties already. stereo_channels_as_speakers is always on and is not shown in the cabinet; it can only be turned off through the API, for a single request.
Voice gender
By timbre, in 8-second windows of each speaker's speech. With little speech or a borderline voice the answer is "unknown", not a guess.
In the result: speaker_info[].gender = {"label": "female" | "male" | "unknown", "confidence": 0.93}.
Spoken language
An audio model listens to the speech, not the text, and names the language of every utterance. The recording's main language is the one that holds the most speaking time, with the share of the others beside it: a call that is one third Russian stays Uzbek, and share shows "ru": 0.33. Each speaker's language is judged over all of their speech. Utterances under a second are not judged, and a recording with less than two seconds of judged speech gets no language.
Language codes are ISO 639-1: uz, ru, en, kk, ky, tg, tk and so on. The model tells apart more than a hundred languages; one it does not know gets the closest one it does.
Two codes mark speech that transcription handles noticeably worse than ordinary Uzbek: kaa is Karakalpak and uz-khorezm the Khorezm dialect of Uzbek. Such recordings are worth checking. Khorezm speech is recognised reliably in businesses whose calls the model learned from; in others it is still recognised rarely. uz-khorezm is a BCP 47 tag: its primary subtag is uz.
In the result: language = {"code", "confidence", "speech_seconds", "share", "posterior"}, speaker_info[].language = {"code", "confidence", "seconds"} and segments[].language = {"code", "confidence"}. The cabinet shows the recording's language in the result summary, and tags an utterance only when its language differs from the main one.
Call outcome
Telephony and CRM often call a call missed when it was answered, or answered when a voice menu or an answering machine picked up, and many recordings start before anyone answers. This option decides from the recording itself:
outcome | What was in the recording |
|---|---|
conversation | A live person on the other end picked up and spoke, however briefly: a single "allo" or "I'm busy, call me later" counts |
no_answer | Ringing, a busy tone, silence, or a file too short to hold a call |
operator_message | The network's announcement ("the subscriber is unavailable", "switched off") or an answering machine |
ivr | A voice menu or queue that no person picked up |
reached is true only for conversation. A call with reached: false can skip further analysis; a call with reached: true is worth analysing even where telephony says it was missed. answer_at is the second the other side answered: on outbound calls the recording often starts with ringing. It is null when nobody was reached.
An audio model listens to the opening of the call (ringing, music, recorded and live voices), and the transcript adds what the words show: a recorded prompt repeats word for word and uses a menu's vocabulary, a conversation goes back and forth, and ringing that goes on under people's voices means they are talking in the office while the line rings, not that anyone answered. The option leans towards "reached" when unsure, so that a real conversation is not skipped. On 961 calls of 12 businesses the model had not seen, it called none of the 485 conversations "not reached" and recognised 440 of the 476 calls without one; the reference was an automatic review of each recording, checked against a person listening to 20 difficult calls. Without speakers (a mono recording with speaker separation off) it called 4 of the 485 conversations "not reached" and recognised 436 of the 476.
In the result: call_outcome = {"outcome", "reached", "confidence", "probabilities", "answer_at", "seconds"}, where seconds is how much of the recording was listened to (its opening, up to ten minutes).
Client and manager
From the text of the conversation: who greets first, who introduces a company, who asks and who answers. It needs the speakers: stereo channels or speaker separation. With roles on and no max_speakers given, speaker separation looks for up to three voices: the two parties and, often, a voice menu.
Speech from before a live person picked up does not count: a voice menu, a network announcement. That moment comes from the call outcome model, which runs for roles even when call_outcome is off (it then stays out of the result and costs nothing). A voice heard mostly before that moment is machine. Of the voices left, the two with the most speech are the client and the manager, and any further voice is other. When only one live voice is heard, its words first say whether it is likely one person: a short call without an exchange is, while a longer one with greetings and pauses is usually two people that speaker separation heard as one. A voice that is likely one person gets a role, read from its words and the call direction, and the status says the role was inferred; otherwise the status is diarization_failed and the voice gets no role, rather than one person's role for both. When nobody picked up, there are no roles, and a menu or announcement voice is machine.
call_direction is passed per request and improves accuracy: "inbound" for an incoming call, "outbound" for an outgoing one, empty when it is not a call or unknown. In the cabinet it is the "What this recording is" choice at upload.
In the result: speaker_info[].role is "client", "manager", "machine", "other" or "unknown", and options_report.roles says how the roles were decided:
| Field | What it is |
|---|---|
status | ok: two live voices got roles. inferred_single_speaker: one live voice, its role inferred from its words and the direction. diarization_failed: one live voice that is most likely two people speaker separation did not tell apart; it gets no role (reason: voices_not_separated). ambiguous: the model could not choose, both are unknown. not_applicable: no roles, and reason says why: no_live_conversation (nobody picked up), no_speech_after_answer or no_speakers_with_text |
score | The probability, from 0.5 to 1, that the client and the manager are the right way round; for inferred_single_speaker, that the voice is one person and its role is right, which can be below 0.5. No score with diarization_failed |
roles | Role per speaker number, as in speaker_info |
parties | The speakers who got the client and manager roles |
one_voice | With one live voice: the probability that it is one person, not two people heard as one |
first_speaker | The party who spoke first once the call was answered |
answer_at, outcome | The call outcome as the roles used it; null when it could not be computed |
direction | The call direction the model used |
margin, margin_speaker | The model's raw margin and the speaker it refers to. Diagnostics: the scale changes with the model |
source, voice, text | Only with known_speakers: what decided the roles (voice, text or none); the voice's view (decided, with the line's external_id, which voice of it and both scores, or abstained and why); the text model's own roles and status, and whether it agrees with the voice |
How far score can be trusted. It was calibrated on 1,294 two-party calls of 90 businesses against a language model's reading of each call, not a person's; each business was left out of the fit that scored its calls. Of the 749 calls with score 0.95 or more, 731 had the client and the manager the right way round; of the 80 between 0.5 and 0.7, 47. On a mono recording a single voice is often two people the speaker separation could not tell apart. On 1,508 two-party calls recorded in stereo and mixed down to mono, so that the speaker of every word is known, 211 came out as one live voice and 94 of those held both people; now 15 of the 94 keep a role and the rest get diarization_failed, as do 49 calls that were mostly one person's speech. Lone voices that keep a role score 0.67 on average, and in 70 % of them at least four fifths of the words have the right role. On the same calls, recordings left without roles went from 116 of 1,200 to 26, and among 390 inbound calls that open with a voice menu, the menu held the manager's or the client's role in 9 instead of 41.
Until runner 1.12.0, score held a speaker number ("0" or "1"), not a score.
Recognise by voice
A voice print is computed from each speaker's speech and compared with the project's voices. A known voice gets its permanent number and its name, if one was given. A new voice with 10 seconds of speech or more in the recording is registered on its own and is recognised in later recordings from then on.
In the result: voices[] linking "speaker of this recording → project voice number", and speaker_info[].identity. Naming voices, merging them and marking utterances as one person: Voices and speakers.
An integrator serving several businesses from one project sends tenant with each recording, so that each business's voices are compared only with each other, and known_speakers to recognise only the business's staff, never storing a client's voice: Several businesses in one project. known_speakers turn voice recognition and roles on by themselves.
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 integrations that send it do not break. It costs nothing, and the result keeps the old fields with a stub in them: segments[].emotion = {"label": null, "reason": "removed"}, speaker_info[].emotion with the same keys set to null (mood_share empty), and options_report.emotion = {"status": "removed"}. The key will be removed later: drop it from your requests.
Emotions: laughter, dissatisfaction and energy (beta)
An audio model listens to each speaker's speech in windows of 2 to 12 seconds and marks the windows where that person laughs. It compares every window with the same speaker's other windows, so it needs speakers — a stereo call (one party per channel) or Speaker separation on a mono recording — and at least three windows of 2–12 seconds from a speaker. A speaker who said less is not checked.
What we measured on 970 MetaSell call-centre calls the model had never heard: of the 70 windows it marked, a listener heard laughter in 54 — 77 % (95 % interval 66–85 %). It finds only about one laugh in three: two laughs out of three go unmarked. So a marked window is usually laughter, while a call without events may still have had some. Use it to find calls with laughter, not to count laughs or to show that there were none.
start and end are the window that holds the laugh, not the laugh itself. score is how far the model leans to laughter over neutral speech: events start at 3.5 and a higher score is a surer one; it is not a probability. Only laughter is reported. On a stereo call each channel is checked on its own; the measurement above was made on calls mixed into one channel.
Dissatisfaction. The model reads the whole conversation — the transcript with the manager and client roles — and marks the turns where a speaker is dissatisfied; it also listens to the voice of the most suspicious ones. Levels: dissatisfied and very_dissatisfied. In a blind check on 400 new MetaSell calls a listener heard 27 of 30 marked turns as dissatisfied (90 %, 95 % interval 74–97 %), and 2 of 30 turns the model took as calm. Only the clearest moments are marked, about 0.4 % of turns: mild dissatisfaction often goes unmarked, and the very-dissatisfied level is still provisional. Here score is the model's confidence: dissatisfaction starts at 1.5, very at 2.4; it is not a probability. A dissatisfaction event names its turn (segment).
Voice energy. For every turn of at least two seconds we measure how loud it is, the pitch and how lively the intonation, and the pace (syllables per second), and compare each with the same speaker's own usual in this call, so the line's volume or a naturally loud or high voice does not count. A turn clearly livelier than that usual is energy_high, clearly flatter energy_low; most turns get neither. Shorter turns are left out: with a few syllables the measure is mostly noise, and the bar is a little higher for turns of two or three seconds than for long ones. A speaker needs at least eight such turns for a usual of their own. In a blind check, of 30 pairs of one speaker's most and least energetic turns a listener chose a side in 24 and agreed with the mark in 23. It shows where a person livened up or flagged, not how energetic one speaker is next to another. Here score is the distance from the speaker's usual (marks start at ±1.0); it is not a probability. An energy event names its turn (segment). It is signal analysis, not a model, and adds no GPU time.
In the result: voice_events = [{"type": "laughter" | "dissatisfied" | "very_dissatisfied" | "energy_high" | "energy_low", "start", "end", "speaker", "score", "segment"}] (laughter has no segment) and options_report.voice_events = {"status", "windows", "speakers", "dissatisfaction": {"status", "read_lines", "candidates", "scored"}, "energy": {"status", "speakers", "turns", "high", "low"}}. status is ok, no_speakers (nobody to compare a window with: a mono recording without Speaker separation) or too_little_speech (no speaker has three windows).
Price: +20 % (×1.2).
Call summary
Our language model reads the whole transcript — with the manager and client roles when they could be told — and writes a short summary in Uzbek: 2–3 sentences on what the call was about and how it ended. It was trained on the summaries of more than a hundred thousand calls, but it can miss a detail or get a fact wrong: check the transcript before an important decision. The first 150 turns of a call are read.
In the result: summary = {"text", "lines", "read_lines"} — the summary, how many turns the call has and how many the model read.
Price: +30 % (×1.3). Off by default in every project: send "summary": true with a request or turn it on in the project settings.
Personal data
The model marks names, phone numbers, addresses, document and card numbers and dates in the text. Each utterance gets a list of what was found with positions in the text, and a version of the text where the data is replaced by [NAME], [PHONE] and so on. The cabinet has a "hide personal data" switch.
In the result: segments[].pii = {"entities": [{"label": "PHONE", "start": 12, "end": 24}], "redacted_text": "…"}.
Price: seconds of audio are multiplied by 1.2.
How the price is computed
The tariff is a multiplier on the length of the recording: 1 without paid options, 1.2 with Personal data. Only the length counts, not the number of options: three free options cost the same as none. The cabinet shows the tariff beside the options, and GET /v1/usage gives what is left. The unit is g: Balance and payment.