Skip to content

SPEV: turn decisions up to 36% sooner. Details →

Timestamps

Get word and segment start and end times from a transcript, or a rendered srt or vtt caption file.

Overview

Request the verbose response and the transcript comes back with start and end times in seconds at two granularities: a words array with one entry per word, and a segments array with one entry per phrase-length block. Use word timings when each word needs its own moment, such as karaoke-style highlighting or jumping to a word in a recording. Use segment timings when you want caption blocks, since each segment is already a displayable line with a time range.

When captions are the end product, skip the assembly entirely: response_format=srt or vtt returns a rendered cue file as the response body.

Timestamps follow the OpenAI verbose_json shape, so a client written against OpenAI's transcriptions API reads them unchanged.

Request

Send response_format=verbose_json. It is the only field you need: both timing arrays come back without a granularity list.

curl https://api.sprag.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $SPRAG_API_KEY" \
  -F [email protected] \
  -F model=rhythm \
  -F response_format=verbose_json
FieldTypeNotes
response_formatstringverbose_json for structured timings; srt or vtt for a rendered caption file.
timestamp_granularities[]arrayOptional. word, segment, or both. Omit word from the list and the words array is left out.

Response

The verbose response carries the transcript, the audio duration, and both timing arrays.

{
  "text": "Thanks, everyone, for joining.",
  "task": "transcribe",
  "duration": 1.7,
  "segments": [
    { "id": 0, "start": 0.0, "end": 1.7, "text": "Thanks, everyone, for joining." }
  ],
  "words": [
    { "word": "Thanks", "start": 0.0, "end": 0.42 },
    { "word": "everyone", "start": 0.48, "end": 0.96 },
    { "word": "for", "start": 1.02, "end": 1.18 },
    { "word": "joining", "start": 1.2, "end": 1.7 }
  ],
  "usage": { "input": { "audio": { "duration": "2" } } }
}

Each words entry is a TranscriptionWord.

FieldTypeNotes
wordstringThe word token.
startnumberWord start time in seconds.
endnumberWord end time in seconds.
speakerinteger0-indexed speaker label. Present only where diarization attributed the word. See diarization.

Each segments entry is a TranscriptionSegment.

FieldTypeNotes
idintegerSegment index, starting at 0.
startnumberSegment start time in seconds.
endnumberSegment end time in seconds.
textstringThe text of the segment.

A segment also carries the other fields of the OpenAI segment shape, so a client written against OpenAI's transcriptions API reads it unchanged.

Times are seconds from the beginning of the submitted audio, as floats. They are absolute within the file you sent, so if you sliced a longer recording before uploading, add your own offset back.

Timestamps and speaker labels

speaker lives on the word object, so diarization and word timings share a payload. Send verbose_json with speaker_labels=true to get words carrying both. Diarization covers that path.

Realtime

Word timings are available over REST. A realtime transcription session delivers text through conversation.item.input_audio_transcription delta and completed events. If you need timings for live audio, keep the captured audio and transcribe it over REST once the turn is done.