Speech to text / Long recordingsSign inGet an API key

Long recordings

Upload audio straight to storage, start a transcription, then poll or wait for a webhook. Works for anything up to two hours.

The asynchronous flow has four steps. The SDKs wrap them in one call (transcribe_file / transcribeFile).

1. Create an upload

Tell the API how large the file is. Including its SHA-256 lets the API prove the stored bytes are exactly yours.

curl
curl "$TWENTYSIX_BASE_URL/v1/uploads" \
  -H "Authorization: Bearer $TWENTYSIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"bytes\": $(stat -f%z meeting.m4a), \"sha256\": \"$(shasum -a 256 meeting.m4a | cut -d' ' -f1)\"}"

The response holds a short-lived, signed upload instruction:

JSON
{
  "id": "upl_…",
  "object": "upload",
  "state": "allocated",
  "bytes": 48213904,
  "upload": { "method": "PUT", "url": "https://…", "headers": { "x-upsert": "false" } },
  "expires_in": 3600
}

2. Send the bytes

Send the file with the given method, URL and headers. The audio goes directly to storage in your project's region, without passing through the API servers.

curl
curl -X PUT "$UPLOAD_URL" -H "x-upsert: false" --data-binary @meeting.m4a

Files above 50 MB can use the resumable_upload instructions in the same response instead (the tus protocol, 6 MB chunks). An interrupted resumable upload continues from where it stopped. The SDKs switch to it automatically.

3. Complete the upload

curl
curl -X POST "$TWENTYSIX_BASE_URL/v1/uploads/$UPLOAD_ID/complete" \
  -H "Authorization: Bearer $TWENTYSIX_API_KEY"

The API checks the size and checksum and measures the audio. The upload moves to verifying, then to complete with duration_seconds and channels, or to rejected with an error code such as audio_decode_failed. Poll GET /v1/uploads/{id} until it leaves verifying.

4. Start the transcription

curl
curl "$TWENTYSIX_BASE_URL/v1/transcriptions" \
  -H "Authorization: Bearer $TWENTYSIX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: meeting-2026-10-20" \
  -d '{
    "audio": { "upload_id": "upl_…" },
    "language": "hi-IN",
    "mode": "codemix",
    "diarization": true,
    "webhook_endpoint_id": "wh_…"
  }'

The response is 202 Accepted with the transcription. Credit for the measured duration is reserved now and settled when it finishes.

JSON
{ "id": "tr_…", "object": "transcription", "state": "queued", "request": { "language": "hi-IN", "mode": "codemix", … }, "created_at": "…", "finished_at": null }

Request fields

FieldValuesDefault
audio.upload_idA complete upload in this projectrequired
languageA code from Languagesrequired
modenative, codemix, verbatim — see Output modesnative
diarizationtrue / false — speaker labelsfalse
timestampssegment, nonesegment
channel_modemix, separate — see Speakers and channelsmix
webhook_endpoint_idAn endpoint from Webhooksnone

Unknown fields are rejected with unknown_parameter; nothing is silently ignored.

5. Wait for the result

A transcription moves through queued → preparing → transcribing → finalizing and ends in one of:

StateMeaning
completedThe full transcript is ready.
partialMost of the audio was transcribed; the stretches that could not be are listed in gaps. Not charged.
failedNothing could be produced; error.code says why. Not charged.
cancelledYou cancelled it. Not charged.

Either register a webhook or poll GET /v1/transcriptions/{id} every few seconds. When the state is completed or partial, fetch the transcript:

curl
curl "$TWENTYSIX_BASE_URL/v1/transcriptions/$ID/result" -H "Authorization: Bearer $TWENTYSIX_API_KEY"

Cancel, delete, list

  • POST /v1/transcriptions/{id}/cancel stops a transcription at the next safe point. Cancelled work is never charged.
  • DELETE /v1/transcriptions/{id} deletes the audio and transcript of a finished transcription now, instead of waiting for retention. The transcription record remains with content_deleted_at.
  • GET /v1/transcriptions?limit=20&state=completed,partial lists the project's transcriptions, newest first. Pass the response's next as after for the next page.

Supported files

WAV, FLAC, MP3, M4A/AAC, OGG/Opus and WebM audio, up to two hours and 2 GB. Video files are coming soon.

Scriba is a product of 26AI Private Limited, Pune, India.© 2026 26AI Private Limited