Dubbing Maker

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.

Base URL https://api.dubbingmaker.com
Authentication Authorization: Bearer dm_live_...
Billing unit Dubbing minutes from your Dubbing Maker account.

Status Values

StatusMeaning
draftJob exists, media file is not ready or not started yet.
queuedJob is waiting for the dubbing backend.
processingJob is currently being dubbed.
completedOutput was created successfully.
failedProcessing failed. Reserved minutes are refunded.
cancelledJob was cancelled or abandoned.

Common Error Codes

HTTPCodeMeaning
401api_key_requiredMissing Bearer token.
401invalid_api_keyThe API key is invalid or revoked.
400invalid_durationdurationSeconds is missing or invalid.
402insufficient_minutesThe account does not have enough dubbing minutes.
404job_not_foundThe job does not exist for this account.
409output_not_readyThe job has not completed yet.
410output_expiredThe temporary output file is no longer available.

Practical Notes

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.

FieldRequiredDescription
filenameYesOriginal file name, used for dashboard display and output naming.
contentTypeNoMIME type. Use application/octet-stream if unknown.
sourceLanguageNoLanguage code such as en, or auto.
targetLanguageYesTarget dubbing language code, for example sk.
durationSecondsYesEstimated 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}"
    }
  }
}
The media file is uploaded directly to storage with signed URLs. It does not pass through the Worker during normal production uploads.

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.