Skip to main content
Beta. Forced alignment takes a recording and the text that is spoken in it, and returns a timestamp for every word. Use it for subtitles and captions, karaoke-style highlighting, audiobook read-along, and cutting audio at word boundaries.
You already have the transcript, so nothing is transcribed: Chariot only works out when each word is said. Send up to 90 seconds of audio to POST /v1/forced-alignment and the timings come back in the same response, in seconds from the start of the audio, one entry per word of your text, in order.

Align a recording

Send multipart/form-data with the audio file, the transcript as text, and the language code. Create an API key in the Dashboard and keep it on your server.
The response:

What you get back

array
One entry per whitespace-separated word of your text, in the same order, so you can map results back by index. text is the word exactly as you sent it, punctuation included. A word that is only punctuation (for example a lone -) gets start equal to end, at the end of the word before it.
number | null
How unsure the aligner is about this word. Lower is better. A word with a much higher loss than the words around it usually means the audio does not say it: a typo in the transcript, a skipped or repeated word, or noise. Use it to flag lines for review.
number | null
The average loss over the transcript. A high value for the whole file usually means the transcript or the language does not match the audio.
integer
What the request cost. See Pricing.
Character-level timings are not returned yet. If your workspace uses data retention, the alignment also has content_expires_at. After it, words, text and filename read as null when you fetch the alignment again, has_audio is false, and the audio endpoint returns 410.

Write a good transcript

  • Send the words that are spoken, as plain text. Speaker labels, timestamps, and markup are aligned as if they were words.
  • Every word in your text gets a timing, even if the audio skips it, so make sure the text matches what is said. Check words with a high loss first.
  • Write numbers and abbreviations the way they are spoken.
  • Send the language that is spoken.

Languages

Pass an ISO 639-1 code as language. The default is hi. GET /v1/forced-alignment/options returns the current list. Any other language is refused with a 422.
Accuracy is highest for Hindi. The other languages are in beta.

Limits

Audio longer than 90 seconds, or shorter than 0.1 seconds, is refused with a 422 before you are charged. Split longer recordings and align each part. An upload well over 50 MB is refused with a 413 while it is still uploading; a file just over 50 MB is refused with a 422. Neither is charged.

Pricing

Forced alignment costs 1 credit per second of audio, rounded up per request, for every language. A 90-second clip, the longest supported, costs 90 credits. Chariot measures the duration from the decoded audio; that measured duration is what you are billed for. The cost is charged before alignment starts. If the alignment fails, the credits are refunded and credits_used becomes 0. See Credits and pricing.

Errors

Errors use the standard error format, except 413, whose body is {"detail": "Request is too large: the file limit is 50 MB"}. Read message, and fall back to detail.

Past alignments

Every charged alignment is recorded, failed ones included. Requests refused before the charge (402, 403, 413, 429 and input errors) are not. Chariot keeps the audio file and the transcript you send with it, under your workspace’s data retention.
  • GET /v1/forced-alignment/{alignment_id} returns one alignment with its transcript as text, and its words if it completed.
  • GET /v1/forced-alignment/{alignment_id}/audio returns a short-lived signed link (about 15 minutes) to the audio you sent, in the format you uploaded. Pass redirect=true to be redirected to it. The audio is stored just after the alignment is created, and has_audio on the alignment says when it is available. The endpoint returns 404 when the audio is not stored (or not stored yet), and 410 once the content has expired.
  • Reuse a link until its url_expires_at instead of asking again. The audio endpoint allows 10 link requests per alignment per minute, and 600 per workspace per minute. Over either, it returns 429.
  • GET /v1/forced-alignment lists your workspace’s alignments, newest first, without their transcripts or words; pass next_before from one page as before to get the next.
A failed alignment’s error.code is one of: Every failed alignment is refunded in full, and its credits_used reads 0.