DEVELOPER API



Integrate DaDaScribe's powerful transcription system into your apps and workflows. For any questions or special requests, please contact us.

Do you have an AI agent? Downoad the SKILL.md file or copy and paste the prompt below to your agent to get started:

Integrate the DaDaScribe transcription API into this project.

Docs: https://api.dadascribe.com/
Base URL: https://api.dadascribe.com/v1
Auth: Authorization: Bearer <API_KEY> on all JSON requests (create a key manually at https://dadascribe.com/account/api.php).

Workflow:
1. POST /v1/transcribe — JSON body: source (YouTube URL/ID or direct audio URL; string or array of up to 10), source-language (required code), optional destination-language (comma-separated codes, max 5), optional diarization (comma-separated speaker names, min 2). Or multipart/form-data: file (single audio/video, max 480 MB) plus a data form part with the same JSON object (omit source). For files up to 10 GB use the /v1/upload/init → /v1/upload/parts → PUT parts → /v1/upload/complete flow, then send upload_token instead of source (see "Large file uploads" in the docs; helpers: https://www.dadascribe.com/api/dadascribe_upload.py and .mjs). Save the returned id.
2. Poll POST /v1/status with {"id":"..."} every few seconds until status is "complete" (or "error"). Rate limits: 60/min transcribe, 120/min status.
3. GET each URL in urls — no Authorization header. Downloads are .txt transcripts and .srt subtitles.

Errors use {"status":"error","message":"..."} with HTTP 401, 402, 403, 429, etc.

Build a small reusable client for our stack with config for the API key, polling with backoff, and file download. Ask me for our language/framework and where outputs should be stored.
You can also use the official DaDaScribe API wrapper in Python or CLI. Or use the OpenAPI JSON file for Postman and other tools.


Prerequisites

The API is available on every plan, including the free plan. All you need is an API key — create one in your account settings to get started. Transcription time is deducted from your account balance.

Overview

The DaDaScribe API is versioned under /v1. JSON endpoints use POST with Content-Type: application/json. POST /v1/transcribe also accepts multipart/form-data for direct audio/video file upload (one file per request, up to 480 MB). Larger files (up to 10 GB) are uploaded straight to storage with the /v1/upload endpoints. File delivery uses GET on secure output URLs returned when a batch is complete.

Base URL:
https://api.dadascribe.com/v1

Each submission creates a batch with one public 16-character id and up to 10 transcription jobs (one per source URL). Account time is deducted from your balance based on the combined duration of all sources in the batch.

Authentication

Create an API key in your account settings. The full key is shown only once when created or replaced. Store it securely and make sure to use it on every JSON request.

Authorization: Bearer dds_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Note: Output file URLs do not require the Bearer header, they are capability URLs scoped to the batch id and filename.

Rate limits

Limits apply per API key (per minute), except output downloads which are limited per client IP.

EndpointLimit
POST /v1/transcribe60 requests / minute
POST /v1/status120 requests / minute
POST /v1/upload/init, /parts, /complete, /abort60 requests / minute each
GET /v1/output/...600 requests / minute (per IP)

When exceeded, the API returns HTTP 429 with { "status": "error", "message": "rate limit exceeded" }. Response headers include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.

POST /v1/transcribe

POST https://api.dadascribe.com/v1/transcribe

Submit one or more sources for transcription. Duplicate URLs in a batch are removed automatically (including equivalent YouTube URL forms). Alternatively, upload a single local audio/video file via multipart/form-data.

File upload

curl -sS -X POST 'https://api.dadascribe.com/v1/transcribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@/path/to/recording.mp3' \
  -F 'data={
    "source-language": "en",
    "destination-language": "en,fr",
    "diarization": "Alice,Bob"
  };type=application/json'
import json
import requests

params = {
    'source-language': 'en',
    'destination-language': 'en,fr',
    'diarization': 'Alice,Bob',
}

with open('/path/to/recording.mp3', 'rb') as f:
    response = requests.post(
        'https://api.dadascribe.com/v1/transcribe',
        headers={'Authorization': 'Bearer YOUR_API_KEY'},
        files={
            'file': ('recording.mp3', f),
            'data': (None, json.dumps(params), 'application/json'),
        },
    )
print(response.json())
const params = {
  'source-language': 'en',
  'destination-language': 'en,fr',
  diarization: 'Alice,Bob',
};

const form = new FormData();
form.append('file', fileInput.files[0]);
form.append('data', new Blob([JSON.stringify(params)], { type: 'application/json' }));

const response = await fetch('https://api.dadascribe.com/v1/transcribe', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
  body: form,
});
const data = await response.json();
console.log(data);

One single audio/video file is allowed in the file field, up to 480 MB. Optionally, you may send source-language, destination-language, and diarization as separate form fields. For larger files (up to 10 GB), see Large file uploads.

Single source (URL)

curl -sS -X POST 'https://api.dadascribe.com/v1/transcribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "source": "https://www.youtube.com/watch?v=VIDEO_ID",
    "source-language": "en",
    "destination-language": "it,fr",
    "diarization": "Alice,Bob"
  }'
import requests

response = requests.post(
    'https://api.dadascribe.com/v1/transcribe',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'source': 'https://www.youtube.com/watch?v=VIDEO_ID',
        'source-language': 'en',
        'destination-language': 'it,fr',
        'diarization': 'Alice,Bob',
    },
)
print(response.json())
const response = await fetch('https://api.dadascribe.com/v1/transcribe', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    source: 'https://www.youtube.com/watch?v=VIDEO_ID',
    'source-language': 'en',
    'destination-language': 'it,fr',
    diarization: 'Alice,Bob',
  }),
});
const data = await response.json();
console.log(data);

Batch (up to 10 URLs)

curl -sS -X POST 'https://api.dadascribe.com/v1/transcribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "source": [
      "https://www.youtube.com/watch?v=VIDEO_ID",
      "https://example.com/podcast.mp3"
    ],
    "source-language": "en",
    "destination-language": "it"
  }'
import requests

response = requests.post(
    'https://api.dadascribe.com/v1/transcribe',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'source': [
            'https://www.youtube.com/watch?v=VIDEO_ID',
            'https://example.com/podcast.mp3',
        ],
        'source-language': 'en',
        'destination-language': 'it',
    },
)
print(response.json())
const response = await fetch('https://api.dadascribe.com/v1/transcribe', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    source: [
      'https://www.youtube.com/watch?v=VIDEO_ID',
      'https://example.com/podcast.mp3',
    ],
    'source-language': 'en',
    'destination-language': 'it',
  }),
});
const data = await response.json();
console.log(data);

Parameters

ParameterRequiredDescription
source yes* YouTube URL or video ID, or a direct HTTP(S) link to an audio or video file. String for one source, or array for up to 10. Omit when uploading a file or when using upload_token.
file yes* Single audio/video file upload (multipart/form-data only, max 480 MB). Supported extensions match direct file URLs below. Omit when using source.
upload_token yes* Token returned by POST /v1/upload/complete for a file uploaded with the large file upload flow (JSON only). Each token can be submitted once. Omit when using source or file.
data yes† Multipart only (for file upload): JSON string with the same fields as a JSON request (omit source). Use type=application/json on this part.
source-language yes Short code for the spoken language (see Languages).
destination-language no Comma-separated target language codes for translation (max 5). Omit for transcription only — defaults to the source language code.
diarization no Comma-separated speaker names for multiple-speaker diarization (minimum two names). Omit or send an empty string for none.

* Provide exactly one of source (JSON), file (multipart), or upload_token (JSON).
† With file upload, provide data (JSON part) or individual form fields for source-language, destination-language, and diarization.

Supported sources

Success response

{
  "status": "ok",
  "id": "a1B2c3D4e5F6g7H8",
  "count": 2
}

Save id — it is the public batch identifier used for status polling and output URLs.

Error response

{ "status": "error", "message": "no time left" }

HTTP 402 when the combined duration of all sources exceeds your account time balance.

Large file uploads (up to 10 GB)

Files larger than 480 MB (and up to 10 GB) are uploaded straight to DaDaScribe storage in parts, then submitted to POST /v1/transcribe with the returned upload_token. Account time is deducted only when you submit the upload_token, based on the file's duration (max 10 hours).

Upload helper (recommended)

The helpers below handle the whole flow for you (parallel parts, retries, and cleanup on failure) and have no dependencies: dadascribe_upload.py (Python 3.8+) and dadascribe_upload.mjs (Node.js 18+).

export DADASCRIBE_API_KEY='YOUR_API_KEY'

# Python
python3 dadascribe_upload.py /path/to/recording.mp4 \
  --source-language en --destination-language it,fr --diarization 'Alice,Bob'

# Node.js
node dadascribe_upload.mjs /path/to/recording.mp4 \
  --source-language en --destination-language it,fr --diarization 'Alice,Bob'

# Both print the /v1/transcribe response, e.g. {"status": "ok", "id": "a1B2c3D4e5F6g7H8", "count": 1}
# Add --upload-only to just upload and print the upload_token.
from dadascribe_upload import transcribe_file

result = transcribe_file(
    'YOUR_API_KEY',
    '/path/to/recording.mp4',
    source_language='en',
    destination_language='it,fr',
    diarization='Alice,Bob',
)
print(result['id'])  # poll POST /v1/status with this id
import { transcribeFile } from './dadascribe_upload.mjs';

const result = await transcribeFile('YOUR_API_KEY', '/path/to/recording.mp4', {
  sourceLanguage: 'en',
  destinationLanguage: 'it,fr',
  diarization: 'Alice,Bob',
});
console.log(result.id); // poll POST /v1/status with this id

Upload flow (raw API)

  1. POST /v1/upload/init with filename, size (bytes), and content_type. Files up to 16 MB get "mode": "put" and a single url: PUT the whole file there, then go to step 4 (omit upload_id and parts). Larger files get "mode": "multipart" with token, upload_id, part_size (16,777,216 bytes) and part_count.
  2. POST /v1/upload/parts with token, upload_id, part_from, and part_to (max 100 parts per call) to get one upload URL per part. URLs are valid for 12 hours.
  3. PUT bytes (n−1)×part_size to n×part_size−1 of the file to the URL for part n (the last part is shorter). Do not send the Authorization header to these URLs. Save the ETag response header of each part. Parts can be uploaded in parallel and retried individually.
  4. POST /v1/upload/complete with token, upload_id, parts ([{ "partNumber": 1, "etag": "..." }, ...]), and size. The file is checked (size, max 10 hours, audio track present, not corrupted) and you get back an upload_token and the duration in seconds.
  5. POST /v1/transcribe with upload_token instead of source, plus the usual language and diarization fields. Each upload_token can be submitted once.

To give up on an unfinished upload, call POST /v1/upload/abort with { "token": "..." }; the uploaded parts are discarded.

# 1. Start the upload (example: a 5 GB video)
curl -sS -X POST 'https://api.dadascribe.com/v1/upload/init' \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{ "filename": "recording.mp4", "size": 5368709120, "content_type": "video/mp4" }'
# → { "status": "ok", "token": "TOKEN", "mode": "multipart", "upload_id": "UPLOAD_ID", "part_size": 16777216, "part_count": 320, ... }

# 2. Get upload URLs for parts 1–100 (then 101–200, ...)
curl -sS -X POST 'https://api.dadascribe.com/v1/upload/parts' \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{ "token": "TOKEN", "upload_id": "UPLOAD_ID", "part_from": 1, "part_to": 100 }'
# → { "status": "ok", "urls": { "1": "https://...", "2": "https://...", ... } }

# 3. Upload each 16 MB part and keep its ETag (no Authorization header)
curl -sS -X PUT --data-binary @part1.bin -D - -o /dev/null 'URL_FOR_PART_1' | grep -i etag

# 4. Finish the upload
curl -sS -X POST 'https://api.dadascribe.com/v1/upload/complete' \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{ "token": "TOKEN", "upload_id": "UPLOAD_ID", "size": 5368709120,
        "parts": [ { "partNumber": 1, "etag": "\"ETAG_1\"" }, { "partNumber": 2, "etag": "\"ETAG_2\"" } ] }'
# → { "status": "ok", "upload_token": "TOKEN", "duration": 7215 }

# 5. Transcribe
curl -sS -X POST 'https://api.dadascribe.com/v1/transcribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' \
  -d '{ "upload_token": "TOKEN", "source-language": "en", "destination-language": "it" }'

POST /v1/status

POST https://api.dadascribe.com/v1/status

curl -sS -X POST 'https://api.dadascribe.com/v1/status' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ "id": "a1B2c3D4e5F6g7H8" }'
import requests

response = requests.post(
    'https://api.dadascribe.com/v1/status',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    json={'id': 'a1B2c3D4e5F6g7H8'},
)
print(response.json())
const response = await fetch('https://api.dadascribe.com/v1/status', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ id: 'a1B2c3D4e5F6g7H8' }),
});
const data = await response.json();
console.log(data);

Status values

statusMeaning
queueAll jobs are waiting in the queue.
processingAt least one job is being processed.
completeAll jobs finished (urls array is returned).
errorBatch not found, or one or more jobs failed.

Processing example

{
  "status": "processing",
  "count": 3,
  "complete": 1,
  "queue": 1,
  "processing": 1
}

Complete example

{
  "status": "complete",
  "count": 2,
  "urls": [
    "https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}.txt",
    "https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}.srt",
    "https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}_it.srt"
  ]
}

Each job produces a plain-text transcript (.txt) and subtitles (.srt). Translation requests add additional _{lang}.srt files per target language.

GET /v1/output

GET https://api.dadascribe.com/v1/output/{id}/{filename}

Download a completed file with a plain GET request. No Authorization header is required. The job must be complete; otherwise the API returns HTTP 403 with { "status": "error", "message": "not ready" }. Only .txt and .srt files associated with your batch id can be downloaded.

curl -sS -O 'https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}.txt'
import requests

url = 'https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}.txt'
response = requests.get(url)
response.raise_for_status()
with open('{file_unique_id}.txt', 'wb') as f:
    f.write(response.content)
const url = 'https://api.dadascribe.com/v1/output/a1B2c3D4e5F6g7H8/{file_unique_id}.txt';
const response = await fetch(url);
const buffer = await response.arrayBuffer();
// save buffer to disk with your runtime's file API

Polling workflow

  1. POST /v1/transcribe — save the returned id.
  2. Loop: POST /v1/status with { "id": "..." } every few seconds (stay within rate limits).
  3. When status is complete, GET each URL in urls.

IMPORTANT: You have one hour to download the files after the job is complete. After that, the files will be no longer available for privacy reasons.

Languages

Source language codes

Use the Code value for source-language:

LanguageCode
Afrikaansaf
Albaniansq
Arabicar
Armenianhy
Assameseas
Azerbaijaniaz
Bashkirba
Basqueeu
Belarusianbe
Bengalibn
Bosnianbs
Bretonbr
Bulgarianbg
Catalanca
Chinesezh
Croatianhr
Czechcs
Danishda
Dutchnl
Englishen
Estonianet
Faroesefo
Finnishfi
Frenchfr
Galiciangl
Georgianka
Germande
Greekel
Gujaratigu
Haitian Creoleht
Hausaha
Hawaiianhaw
Hebrewhe
Hindihi
Hungarianhu
Icelandicis
Indonesianid
Italianit
Japaneseja
Javanesejw
Kannadakn
Kazakhkk
Khmerkm
Koreanko
Laolo
Latinla
Latvianlv
Lingalaln
Lithuanianlt
Luxembourgishlb
Macedonianmk
Malagasymg
Malayms
Malayalamml
Maltesemt
Maorimi
Marathimr
Mongolianmn
Myanmarmy
Nepaline
Norwegianno
Nynorsknn
Occitanoc
Pashtops
Persianfa
Polishpl
Portuguesept
Punjabipa
Romanianro
Russianru
Sanskritsa
Serbiansr
Shonasn
Sindhisd
Sinhalasi
Slovaksk
Sloveniansl
Somaliso
Spanishes
Sundanesesu
Swahilisw
Swedishsv
Tagalogtl
Tajiktg
Tamilta
Tatartt
Telugute
Thaith
Tibetanbo
Turkishtr
Turkmentk
Ukrainianuk
Urduur
Uzbekuz
Vietnamesevi
Welshcy
Yiddishyi
Yorubayo

Destination language codes

Use comma-separated Code values for destination-language (max 5). Destination codes must not include the source language. Source language will always be included in the destination languages.

LanguageCode
Afrikaansaf
Albaniansq
Arabicar
Armenianhy
Assameseas
Azerbaijaniaz
Bashkirbh
Basqueeu
Belarusianbe
Bengalibn
Bosnianbs
Bretonbr
Bulgarianbg
Cantoneseyue
Catalanca
Cebuanoceb
Cherokeechr
Chichewany
Chinese (Simplified)zh-CN
Chinese (Traditional)zh-TW
Corsicanco
Croatianhr
Czechcs
Danishda
Dutchnl
Dzongkhadz
Englishen
Esperantoeo
Estonianet
Faroesefo
Filipinofil
Finnishfi
Frenchfr
Frisianfy
Galiciangl
Georgianka
Germande
Greekel
Guaranign
Gujaratigu
Haitian Creoleht
Hausaha
Hawaiianhaw
Hebrewiw
Hindihi
Hmonghmn
Hungarianhu
Icelandicis
Igboig
Indonesianid
Irishga
Italianit
Japaneseja
Javanesejv
Kannadakn
Kazakhkk
Khmerkm
Kinyarwandarw
Koreanko
Kurdish (Kurmanji)ku
Kurdish (Sorani)ckb
Kyrgyzky
Laolo
Latinla
Latvianlv
Lingalali
Lithuanianlt
Luxembourgishlb
Macedonianmk
Malagasymg
Malayms
Malayalamml
Maltesemt
Maorimi
Marathimr
Mongolianmn
Myanmar (Burmese)my
Nepaline
Norwegianno
Nynorsknn
Occitanoc
Odia (Oriya)or
Pashtops
Persianfa
Polishpl
Portuguesept
Punjabipa
Romanianro
Romanshrm
Russianru
Samoansm
Sanskritss
Scots Gaelicgd
Serbiansr
Serranoser
Sesothost
Shonasn
Sicilianscn
Sindhisd
Sinhalasi
Slovaksk
Sloveniansl
Somaliso
Spanishes
Sundanesesu
Swahilisw
Swedishsv
Tagalogtl
Tajiktg
Tamazightber
Tamilta
Tatartt
Telugute
Thaith
Tibetanbo
Turkishtr
Turkmentk
Ukrainianuk
Urduur
Uyghurug
Uzbekuz
Vietnamesevi
Welshcy
Wolofwo
Xhosaxh
Yiddishyi
Yorubayo
Zuluzu

Errors & HTTP codes

All JSON errors use the shape { "status": "error", "message": "..." }.

HTTPTypical messageWhen
400missing source, missing file, use either source or file upload, invalid source-language, invalid YouTube URL, etc.Invalid or missing request parameters.
400file too large, could not determine file size, source exceeds maximum duration, no audio track, file appears corrupted or incompleteThe file or file URL is over 10 GB, its size cannot be read from the server hosting it, it is longer than 10 hours, or it is not usable audio/video.
400unsupported file type, invalid token, upload_id mismatch, bad part range, bad_parts, complete_failed, missing_object, size_mismatch, oversize, no_audio, corrupt_file, could not read media file, media processing failed, upload not completed, upload_token already usedLarge file upload errors (see Large file uploads).
401unauthorizedMissing or invalid API key.
402no time leftBatch duration exceeds account balance.
403not readyOutput requested before job completion.
404job_not_found, not foundUnknown batch id or file.
405method not allowedWrong HTTP method on a JSON endpoint.
429rate limit exceededToo many requests in the current window.
500internal error, etc.Unexpected server error.

Schemas

Request and response shapes for each endpoint.

POST /v1/transcribe — request (JSON)

{
  "source": "string | string[]",     // required unless uploading a file — 1 URL/ID, or array of 1–10 URLs/IDs
  "source-language": "string",       // required — source language short code
  "destination-language": "string",  // optional — comma-separated codes, max 5; omit for transcription only
  "diarization": "string"            // optional — comma-separated speaker names (min 2), or ""
}

POST /v1/transcribe — request (JSON, uploaded file)

{
  "upload_token": "string",              // required — from POST /v1/upload/complete; usable once
  "source-language": "string",       // required
  "destination-language": "string",  // optional
  "diarization": "string"            // optional
}

POST /v1/transcribe — request (multipart)

Content-Type: multipart/form-data

file:                 // required — single audio/video file
data:                 // recommended — same JSON as above, omit source; Content-Type: application/json
                      // alternative: individual form fields source-language, destination-language, diarization

POST /v1/transcribe — success response

{
  "status": "ok",                    // literal
  "id": "string",                    // 16-char alphanumeric public batch id
  "count": "integer"                 // number of jobs queued (1–10)
}

POST /v1/upload/init — request / response

{
  "filename": "string",              // required — original file name; extension decides the format
  "size": "integer",                 // required — bytes, 1 to 10737418240 (10 GB)
  "content_type": "string"           // optional — e.g. "video/mp4"
}

// files up to 16 MB
{ "status": "ok", "token": "string", "mode": "put", "url": "string", "content_type": "string" }

// larger files
{ "status": "ok", "token": "string", "mode": "multipart", "upload_id": "string",
  "part_size": 16777216, "part_count": "integer" }

POST /v1/upload/parts — request / response

{
  "token": "string",                 // required — from /v1/upload/init
  "upload_id": "string",             // required — from /v1/upload/init
  "part_from": "integer",            // required — first part number (1-based)
  "part_to": "integer"               // required — last part number; max 100 parts per call, max part 640
}

{ "status": "ok", "urls": { "1": "string", "2": "string" } }   // PUT targets, valid 12 hours

POST /v1/upload/complete — request / response

{
  "token": "string",                 // required
  "upload_id": "string",             // multipart only
  "parts": [ { "partNumber": "integer", "etag": "string" } ],   // multipart only — all parts, ETags as returned by the PUTs
  "size": "integer"                  // recommended — total bytes; checked against the stored file
}

{ "status": "ok", "upload_token": "string", "duration": "integer" }   // duration in seconds

POST /v1/upload/abort — request / response

{ "token": "string" }               // required — an upload that has not been completed

{ "status": "ok" }

POST /v1/status — request

{
  "id": "string"                     // required — batch id from /v1/transcribe
}

POST /v1/status — response (queue)

{
  "status": "queue",
  "count": "integer",                // total jobs in batch
  "complete": "integer",             // jobs finished
  "queue": "integer",                // jobs still waiting
  "processing": "integer"            // jobs currently running
}

POST /v1/status — response (processing)

{
  "status": "processing",
  "count": "integer",
  "complete": "integer",
  "queue": "integer",
  "processing": "integer"
}

POST /v1/status — response (complete)

{
  "status": "complete",
  "count": "integer",
  "urls": [                          // flat list of download URLs for the whole batch
    "string"                         // GET /v1/output/{id}/{filename}
  ]
}

POST /v1/status — response (error)

{
  "status": "error",
  "message": "string",               // e.g. "job_not_found", "one or more transcriptions failed"
  "count": "integer",                // present when batch exists but jobs failed
  "complete": "integer",             // optional progress fields
  "queue": "integer",
  "processing": "integer"
}

GET /v1/output — response

Success returns the raw file stream (text/plain or application/x-subrip). Errors are JSON:

{
  "status": "error",
  "message": "string"                // "invalid request" | "not found" | "not ready" | "invalid file"
}

Common error envelope

All JSON endpoints use this shape on failure (including /v1/transcribe):

{
  "status": "error",
  "message": "string"
}

Get your API key



Top of Page