Skip to main content

Speech-to-Text (Batch)

Use STT Batch to transcribe long recordings or many files asynchronously. Flow: upload audio → start a job → poll until it finishes → download transcripts
(or receive them on a webhook).

Table of contents

  1. How it works
  2. Before you begin
  3. Quickstart
  4. How do I get the transcript text?
  5. Choose how to send audio
  6. Recipes
  7. Configuration
  8. Limits
  9. Supported languages
  10. Supported audio formats
  11. API reference
  12. Job statuses
  13. File statuses
  14. Webhooks
  15. Errors
  16. Common mistakes
  17. Python example
  18. Support

How it works

Important: creating a job does not start transcription. You must call /start.

Before you begin

  1. An API key from the Gnani APIs dashboard
  2. Audio in a supported format
  3. A supported language code
Base URL
Auth — send on every Batch API request. This is the only required header:

Quickstart (copy-paste)

1. Create the job

Response — 201 Created
Save job_id. Always start with this path (even if the message mentions /v1/jobs/...):

2. Start processing

Response — 202 Accepted

3. Poll status

  • Poll no faster than every 10 seconds
  • For large jobs (100+ files), prefer every 30 seconds
  • Stop when status is COMPLETED, PARTIAL_FAILURE, FAILED, START_FAILED, or CANCELLED
Response — 200 OK (in progress)
Response — 200 OK (done)
Job status does not include transcript text.

4. Get completed files

This response gives you transcript_urlnot the transcript text yet.
Response — 200 OK

5. Download the transcript (full_transcript)

If you are not using webhooks, this is the step that returns the text. Call transcript_url with a normal HTTP GET. Do not send X-API-Key-ID — the URL is pre-signed.
Response — transcript JSON
  • Use full_transcript for the complete text
  • Use segments for timestamps / speaker labels
  • transcript_url expires in 1 hour — re-call /files for a fresh URL

How do I get the transcript text?

GET /jobs/{job_id} and GET /jobs/{job_id}/files do not return full_transcript.
/files only returns transcript_url. You must GET that URL to get the text.

Choose how to send audio

Only these three methods are supported. Authenticated private bucket access (IAM AssumeRole, GCS keys, Azure keys) is not available.

Recipes

Multiple files

Response — 201 Created

ZIP upload

Response — 201 Created

Public URL

URLs are validated at /start, not at create. If every path fails:

Two-speaker diarization

  • Send num_speakers when with_diarization is true
  • Max speakers: 2
  • Set is_multi_channel: true only for true multi-channel audio (for example stereo A/B); leave false for mono

Cancel before start

Response — 200 OK

Configuration

Inverse Text Normalization (ITN) is not supported for STT Batch.

Limits

Direct upload

ZIP upload

Transcript URL

transcript_url is created when you call GET /jobs/{job_id}/files. Re-call /files for a fresh URL. No API key is needed to download from the URL.

Polling

  • Poll GET /jobs/{job_id} no faster than every 10 seconds
  • For 100+ file jobs, prefer every 30 seconds
  • Stop on a terminal status

Supported languages

Example error — 400 UNSUPPORTED_LANGUAGE

Supported audio formats

.wav · .mp3 · .mp4 · .flac · .ogg · .opus · .m4a · .aac · .webm · .amr Tone-only or silent audio may be accepted into a job but later fail with Empty transcript after 3 retries. Use real speech.

API reference

Create job — upload / ZIP

Create job — public URL

Start job

Example conflict — 409

Get job status

See Quickstart step 3 for response shapes.

List jobs

Get file results

Without webhooks:
  1. Call this after the job is terminal
  2. Take transcript_url for each COMPLETED file
  3. GET that URL → read full_transcript
This response never contains full_transcript itself.

Cancel job

Optional JSON body: { "reason": "..." } with Content-Type: application/json.

Job statuses


File statuses


Webhooks

Pass callback_url at create time to receive a POST when the job reaches a terminal state. The transcripts array includes full per-file transcript JSON (with full_transcript), so webhook users usually do not need /files + transcript_url. If you are not using webhooks, see How do I get the transcript text?. Treat webhooks as best-effort. Polling remains the source of truth.

Sample webhook payload


Errors

Missing API key — 401
Unsupported language — 400
Restart finished job — 409
Job not found — 404
Already cancelled — 409

Common mistakes


Python example


Support

Docs feedback: Batch STT docs feedback Last verified: 28 Jul 2026 against https://api.vachana.ai