Elevenlabs Forced Alignment API Documentation
Playground
Try it on WaveSpeedAI!ElevenLabs Forced Alignment aligns an existing transcript with an audio recording and returns character-level and word-level timestamps as structured JSON for subtitles, captions, dubbing, localization, and transcript synchronization workflows. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.
Features
ElevenLabs Forced Alignment aligns an existing transcript with an audio recording. Provide an audio file and the transcript spoken in that audio, and the endpoint returns structured alignment data with character-level and word-level timestamps.
This endpoint does not generate a new audio file and does not create an automatic transcript. The prompt is the existing transcript to align.
Why Choose This?
-
Transcript alignment
Align existing text with spoken audio. -
Character-level timing
Receive timestamp data for individual characters. -
Word-level timing
Retrieve word entries with start time, end time, and alignment loss. -
Long audio support
Supports audio inputs up to10hours, subject to validation. -
Structured JSON output
Use the returned alignment object for captions, subtitles, transcript viewers, or audio-text synchronization workflows.
Parameters
| Parameter | Required | Description |
|---|---|---|
| audio | Yes | Audio recording URL or uploaded audio file. Supports up to 10 hours and 3 GB, subject to validation. |
| prompt | Yes | Existing transcript spoken in the audio. This is the text to align, not a generation instruction. |
How to Use
- Upload audio — Provide the audio recording you want to align.
- Enter the transcript — Add the existing transcript spoken in the audio.
- Submit — Run the alignment request.
- Read the alignment JSON — Retrieve the structured alignment object from json.
Pricing
Pricing is based on input audio duration.
Billing is calculated per started hour. Audio duration is rounded up to the next whole hour, with a minimum charge of 1 hour and a maximum billed duration of 10 hours.
| Billing Unit | Cost |
|---|---|
| Per started hour | $0.30 |
Example Costs
| Audio Duration | Billed Hours | Cost |
|---|---|---|
| 5 seconds | 1 | $0.30 |
| 30 minutes | 1 | $0.30 |
| 60 minutes | 1 | $0.30 |
| 61 minutes | 2 | $0.60 |
| 120 minutes | 2 | $0.60 |
| 10 hours | 10 | $3.00 |
Billing uses the measured duration of the input audio, not transcript length or the timestamp of the last aligned word.
Best Use Cases
- Subtitle timing — Align transcript text with audio for subtitle or caption workflows.
- Transcript viewers — Build word-level or character-level synchronized transcript interfaces.
- Audio-text synchronization — Match spoken audio with existing text for playback highlighting.
- Dataset preparation — Prepare timestamped transcript data for speech or media workflows.
- Long-form audio alignment — Align interviews, podcasts, recordings, or narrated content.
Pro Tips
- Use a transcript that closely matches the spoken audio.
- Keep the transcript clean and ordered for better alignment.
- Use the measured input audio duration to estimate billing.
- Read alignment data from
data.outputs[0]. - Use word-level timestamps for subtitles and character-level timestamps for more precise highlighting.
- Split very long audio when your workflow needs smaller alignment segments.
Notes
audioandpromptare required.promptmust contain the existing transcript, not an instruction to generate text.- The endpoint returns structured alignment JSON only.
- No voice ID is required.
- The supported input limit is
10hours. - Billing is rounded up to the next started hour and capped at
10billed hours.
Authentication
For authentication details, please refer to the Authentication Guide.
API Endpoints
Submit Task & Query Result
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
REQUEST_BODY=$(cat <<'JSON'
{
"audio": "https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3",
"prompt": "A cinematic ocean wave at sunrise, highly detailed"
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/elevenlabs/forced-alignment" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}")
TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body \
"${RESULT_URL}" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}")
RESULT=$(printf '%s' "${RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout|deleted) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
*) sleep 2 ;;
esac
doneParameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| audio | string | Yes | - | 1 ~ unlimited characters | Public URL of the audio recording to align. Supply a URL or upload an audio file. Maximum input: 10 hours and 3 GB. |
| prompt | string | Yes | 1 ~ unlimited characters · pattern: \S | The existing transcript spoken in the audio, not a generation instruction. Provide the text to align with the recording. |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data.id | string | Unique identifier for the prediction, Task Id |
| data.model | string | Model ID used for the prediction |
| data.outputs | array | Output values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed) |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Task status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses. |
| data.created_at | string | ISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”) |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |
Result Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Task ID |
Result Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data | object | The prediction data object containing all details |
| data.id | string | Unique identifier for the prediction |
| data.model | string | Model ID used for the prediction |
| data.outputs | array<string | object> | Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model. |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Status: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses |
| data.created_at | string | ISO timestamp of when the request was created |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |