Developer API
Automate dubbing from your own app.
The Dubbing Maker API lets registered users create dubbing jobs from scripts, backends, internal tools or future integrations. API jobs use the same account balance and the same temporary output storage as jobs started from the web app.
https://api.dubbingmaker.com
Authorization: Bearer dm_live_...
Status Values
| Status | Meaning |
|---|---|
draft | Job exists, media file is not ready or not started yet. |
queued | Job is waiting for the dubbing backend. |
processing | Job is currently being dubbed. |
completed | Output was created successfully. |
failed | Processing failed. Reserved minutes are refunded. |
cancelled | Job was cancelled or abandoned. |
Common Error Codes
| HTTP | Code | Meaning |
|---|---|---|
| 401 | api_key_required | Missing Bearer token. |
| 401 | invalid_api_key | The API key is invalid or revoked. |
| 400 | invalid_duration | durationSeconds is missing or invalid. |
| 402 | insufficient_minutes | The account does not have enough dubbing minutes. |
| 404 | job_not_found | The job does not exist for this account. |
| 409 | output_not_ready | The job has not completed yet. |
| 410 | output_expired | The temporary output file is no longer available. |
Practical Notes
- API jobs appear in the same dashboard as web jobs and are marked as API jobs.
- Input files are temporary and are removed after processing or after cleanup.
- Output files are temporary. Download them shortly after completion.
- Use one API key per app, script or environment so you can revoke access cleanly.
- For long files, prefer multipart upload and retry failed parts client-side.
- Do not expose your API key in browser JavaScript. Use your backend for public apps.
1. Create an API Key
Sign in to Dubbing Maker, open the account menu and choose API Keys. Create a key, copy it immediately and store it securely. The full key is shown only once.
Authorization: Bearer dm_live_XXXXXXXXXXXXXXXXXXXXXXXX
Treat API keys like passwords. If a key leaks, revoke it in the API Keys dialog and create a new one.
2. Response Format
Successful JSON responses use this envelope:
{
"ok": true,
"data": {
"...": "..."
}
}
Errors use the same shape across endpoints:
{
"ok": false,
"error": {
"code": "insufficient_minutes",
"message": "Not enough dubbing minutes."
}
}
3. Check Account Balance
Use this before creating jobs if you want to show available minutes in your own UI.
curl https://api.dubbingmaker.com/v1/account \
-H "Authorization: Bearer dm_live_..."
{
"ok": true,
"data": {
"user": {
"id": "user_...",
"email": "you@example.com"
},
"minutes": 294
}
}
4. Create a Job
Create a draft job with filename, content type, source language, target language and estimated duration. The duration is a client estimate used to reserve minutes early. The dubbing backend verifies the real media duration before expensive processing starts.
| Field | Required | Description |
|---|---|---|
filename | Yes | Original file name, used for dashboard display and output naming. |
contentType | No | MIME type. Use application/octet-stream if unknown. |
sourceLanguage | No | Language code such as en, or auto. |
targetLanguage | Yes | Target dubbing language code, for example sk. |
durationSeconds | Yes | Estimated media duration in seconds. Do not send file size. |
curl https://api.dubbingmaker.com/v1/jobs \
-H "Authorization: Bearer dm_live_..." \
-H "Content-Type: application/json" \
-d '{
"filename": "demo.mp4",
"contentType": "video/mp4",
"sourceLanguage": "en",
"targetLanguage": "sk",
"durationSeconds": 185
}'
{
"ok": true,
"data": {
"jobId": "0c1f...",
"assetId": "8a42...",
"status": "draft",
"estimatedMinutes": 4,
"upload": {
"mode": "multipart",
"method": "POST",
"createMultipartUrl": "/v1/uploads/8a42.../multipart",
"partUrlsUrl": "/v1/uploads/8a42.../multipart/{uploadId}/parts",
"completeUrl": "/v1/uploads/8a42.../multipart/{uploadId}/complete",
"abortUrl": "/v1/uploads/8a42.../multipart/{uploadId}"
}
}
}
5. Upload the Media File
Create a multipart upload
curl -X POST https://api.dubbingmaker.com/v1/uploads/{assetId}/multipart \
-H "Authorization: Bearer dm_live_..."
{
"ok": true,
"data": {
"uploadId": "2~abc...",
"partSize": 10485760,
"maxParts": 10000
}
}
Request signed URLs for parts
curl -X POST https://api.dubbingmaker.com/v1/uploads/{assetId}/multipart/{uploadId}/parts \
-H "Authorization: Bearer dm_live_..." \
-H "Content-Type: application/json" \
-d '{ "parts": [1, 2, 3] }'
{
"ok": true,
"data": {
"parts": [
{ "partNumber": 1, "url": "https://..." },
{ "partNumber": 2, "url": "https://..." }
]
}
}
Upload each part directly
curl -X PUT "https://signed-upload-url-for-part-1" \
--data-binary "@part-1.bin"
Store the returned ETag header for each uploaded part.
Complete the upload
curl -X POST https://api.dubbingmaker.com/v1/uploads/{assetId}/multipart/{uploadId}/complete \
-H "Authorization: Bearer dm_live_..." \
-H "Content-Type: application/json" \
-d '{
"parts": [
{ "partNumber": 1, "etag": "\"etag-1\"" },
{ "partNumber": 2, "etag": "\"etag-2\"" }
]
}'
If an upload cannot continue, call DELETE /v1/uploads/{assetId}/multipart/{uploadId}
to abort it.
6. Start Processing
Starting a job reserves the estimated number of minutes. If processing fails, the reserved minutes are refunded automatically. If the real media duration is materially longer than the submitted estimate, the job fails before producing an output.
curl -X POST https://api.dubbingmaker.com/v1/jobs/{jobId}/start \
-H "Authorization: Bearer dm_live_..."
{
"ok": true,
"data": {
"jobId": "0c1f...",
"status": "queued",
"estimatedMinutes": 4
}
}
7. Track Jobs
Poll a single job or list recent jobs for the authenticated account.
GET /v1/jobs/{jobId}
GET /v1/jobs?limit=20
{
"ok": true,
"data": {
"id": "0c1f...",
"status": "processing",
"stage": "transcribing",
"progress": 34,
"stageProgress": 62,
"sourceLanguage": "en",
"targetLanguage": "sk",
"estimatedMinutes": 4,
"chargedMinutes": 4,
"createdAt": "2026-07-12T12:00:00Z",
"startedAt": "2026-07-12T12:01:00Z",
"completedAt": null,
"runtimeSeconds": null,
"outputAvailable": false,
"source": "api"
}
}
8. Download the Result
Completed outputs are temporary. When the output is still available, this endpoint returns a short-lived download URL.
curl https://api.dubbingmaker.com/v1/jobs/{jobId}/download \
-H "Authorization: Bearer dm_live_..."
{
"ok": true,
"data": {
"url": "https://api.dubbingmaker.com/api/downloads/ticket/...",
"expiresInSeconds": 600,
"filename": "demo_sk_dubbing.mp4"
}
}
If the output has already expired, the API returns 410 output_expired.