Output and Add-ons
A completed job returns its transcript as JSON with timestamped segments, or as SRT or WebVTT subtitles. The output is the same whether it reaches you in a webhook, through Get a Job, or in a stream. Add-ons add fields to each segment and cost extra per minute.
JSON Output
The output object holds the audio duration in seconds, the request options the job ran with, and the transcribed segments. This example was created with can_label_audio, can_parse_speakers, and can_parse_words enabled. Its words arrays are shortened.
{
"id": "00000000-1111-7222-b333-444444444444-sic",
"output": {
"duration": 1246.679375,
"request": {
"can_label_audio": true,
"can_parse_speakers": true,
"can_parse_words": true,
"can_stream_output": false,
"input_url": "https://example.com/audio-file.m4a",
"is_split_channel": false,
"language": null,
"minimum_confidence": 0.5,
"segment_duration": 30
},
"segments": [
{
"confidence": 0.988,
"end": 7.296,
"id": 1,
"label": "speech",
"language": "en (99.60%)",
"processing_duration_in_s": 0.029,
"speaker_id": "B",
"start": 0,
"text": "Imagine staring at um just a massive hard drive filled with gigabytes of raw video files.",
"words": [
{ "end": 0.8, "start": 0.16, "text": "Imagine" },
{ "end": 1.44, "start": 0.8, "text": "staring" },
{ "end": 7.06, "start": 6.96, "text": "files." }
]
},
{
"confidence": 0.903,
"end": 12.032,
"id": 2,
"label": "speech",
"language": "en (99.80%)",
"processing_duration_in_s": 0.024,
"speaker_id": "B",
"start": 7.92,
"text": "or like a folder stuffed with hundreds of hours of meet and recording.",
"words": [
{ "end": 8.48, "start": 8.24, "text": "or" },
{ "end": 11.78, "start": 11.68, "text": "recording." }
]
}
]
},
"status": "COMPLETED"
}
request repeats the options the job ran with, but not webhook_url, output_format, is_private, or user_agent. For a private job, request.input_url is https://speechischeap.com/redacted.
Segment Fields
Each segment has these fields:
| Field | Description |
|---|---|
id | The segment's position in the transcript, starting at 1. |
start, end | The segment's boundaries in seconds. |
text | The transcribed text. Empty for non-speech segments. |
confidence | The confidence from 0 to 1. For non-speech segments, it's the confidence of the audio label. |
language | The detected language and its probability, such as en (99.60%). When you set the language parameter, the probability is always 100.00%. null for non-speech segments. |
processing_duration_in_s | The time the API spent transcribing the segment, in seconds. |
words | With can_parse_words, the words of the segment. Otherwise an empty array. |
speaker_id | With can_parse_speakers or is_split_channel, the speaker, such as A or B. Only segments with speech have it. |
label | With can_label_audio, speech, silence, or the name of a sound, such as music. |
Punctuation and Casing
Transcripts include punctuation and capitalization, and there's no option to turn them off. Text is verbatim, so filler words such as "um" are kept. A segment can start in lowercase when it continues a sentence from the previous segment, and punctuation stays attached to words, as in files..
Minimum Confidence
The API drops a segment whose confidence is below minimum_confidence. Segment id values stay consecutive, so a dropped segment shows up as a gap in the timestamps, not in the IDs. With can_label_audio, the API doesn't drop the segment. It returns the segment with label set to silence, an empty text, and a confidence of 1.
SRT and VTT Output
You can get a transcript as SRT or VTT subtitles instead of JSON:
- Get a Job returns a completed job as SRT or VTT when you add the
output_formatquery parameter. The response hasContent-Type: application/x-subripfor SRT andtext/vttfor VTT. - The
output_formatparameter of Create a Job from a URL sets the format of the webhook body and of the stream. It doesn't change what Get a Job returns.
output_format takes srt, vtt, or webvtt, which is an alias for vtt.
An SRT transcript:
1
00:00:01,234 --> 00:00:12,345
This is an example of some transcribed text output.
2
00:00:13,000 --> 00:00:15,000
[music]
A VTT transcript:
WEBVTT
1
00:00:01.234 --> 00:00:12.345
This is an example of some transcribed text output.
2
00:00:13.000 --> 00:00:15.000
[music]
- Each segment is one cue, numbered from 1.
- A cue has the text and the timing only. Speaker IDs and words aren't included.
- With
can_label_audio, a segment labeled with a sound other thanspeechorsilenceappears as its label in square brackets, such as[music]. Asilencesegment has an empty cue. - A job without segments returns an empty SRT, or a VTT that has only the
WEBVTTheader.
Add-ons
Each add-on adds fields to the segments in the JSON output and costs extra per minute. Turn them on with can_label_audio, can_parse_speakers, and can_parse_words when you create a job. See pricing for the prices and Billing for how charges work.
Label Audio
can_label_audio adds a label to every segment. The segments then cover the whole recording. A segment with speech is labeled speech. Other segments get the name of a sound, such as music, or silence. A non-speech segment has an empty text, a language of null, and no speaker_id.
{
"confidence": 0.91,
"end": 15.2,
"id": 3,
"label": "music",
"language": null,
"processing_duration_in_s": 0.012,
"start": 12.032,
"text": "",
"words": []
}
In SRT and VTT output, a labeled sound appears in square brackets. See SRT and VTT Output.
Parse Speakers
can_parse_speakers turns on speaker diarization: it tells speakers apart by their voices and adds a speaker_id to each segment with speech. Speakers are named A, B, and so on.
{ "speaker_id": "A" }
Parse Words
can_parse_words adds word-level timestamps: it fills words in each segment with the start time, end time, and text of each word.
{
"words": [
{
"start": 2.345,
"end": 2.567,
"text": "hi"
}
]
}
Split Channels
is_split_channel is for recordings that have one speaker on each channel, such as multi-track recordings. It works with any number of channels the file carries, not just stereo. The API transcribes each channel separately, merges the segments in time order, and gives each channel its own speaker_id, starting with A. It works without can_parse_speakers. With both turned on, the API also tells apart the speakers within each channel.