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) plus a data form part with the same JSON object (omit source). 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). 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
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. Optionally, you may send source-language, destination-language, and diarization as separate form fields.

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 s3_token.
file yes* Single audio/video file upload (multipart/form-data only). Supported extensions match direct file URLs below. Omit when using source.
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 source (JSON) or file (multipart), not both.
† 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.

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.
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 (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/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