> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Nasynchronisatieproject maken

POST https://api.elevenlabs.io/v1/dubbing/project
Content-Type: multipart/form-data

Maak een nasynchronisatieproject vanuit een geüpload bestand (`file`) of een bron-URL (`source_url`).

Retourneert zodra het projectrecord bestaat, voordat de bron is opgehaald: het project start als `queued` en wordt `ready` zodra de bron is getranscribeerd. Voeg voor elke gewenste taal een taaldoel toe, of geef `target_language` door om hier het eerste doel in de wachtrij te zetten.

Voor het maken van een project worden minimaal de kosten voor één taal in rekening gebracht: bij het maken van het project worden kosten voor nasynchronisatie in ten minste één taal berekend, voordat er uitvoer bestaat. Deze kosten betalen het eerste taaldoel vooraf — het eerste doel dat je toevoegt, of het doel dat via `target_language` in de wachtrij is gezet, gebruikt dit — en voor elke extra taal worden afzonderlijke kosten berekend.

De voorbereiding kan bij een lange bron minuten duren. We raden daarom aan `webhook_ids` door te geven, zodat je een melding krijgt wanneer het project `ready` of `failed` wordt, in plaats van ernaar te pollen.

Reference: https://elevenlabs.io/docs/api-reference/dubbing/create-project

## Servers

- `https://api.elevenlabs.io` (Production, default)
- `https://api.us.elevenlabs.io` (Production US)
- `https://api.eu.residency.elevenlabs.io` (Production EU)
- `https://api.in.residency.elevenlabs.io` (Production India)
- `https://api.sg.residency.elevenlabs.io` (Production Singapore)

## Request

### Body (multipart/form-data)

This endpoint expects a multipart form with multiple files.

- `file` (file, optional) — Het bronmediabestand voor nasynchronisatie: een audio- of videobestand van maximaal 3 GiB. Geef dit of `source_url` op, niet beide.
- `source_url` (string, optional) — Openbare HTTP(S)-URL waarvandaan de bronmedia server-side worden opgehaald, onderhevig aan dezelfde limieten voor omvang en indeling als een upload. Geef deze of `file` op, niet beide.
- `reference` (string, optional) — Optionele vrije tekenreeks (maximaal 500 tekens) om het project aan jouw kant te identificeren. Wordt letterlijk opgeslagen en teruggegeven; heeft geen invloed op de nasynchronisatie.
- `source_language` (string, optional) — BCP-47-taaltag van de bronmedia; moet een taal zijn die het transcriptiemodel ondersteunt. Elke subtag voor regio of schrift wordt genegeerd, aangezien transcriptie per taal plaatsvindt. Laat weg voor automatische detectie.
- `model_id` (V1DubbingProjectPostRequestBodyContentMultipartFormDataSchemaModelId, optional) — Nasynchronisatiemodel (`dubbing_v1` of `dubbing_v2`) waarmee elk taaldoel van dit project van nasynchronisatie wordt voorzien. Standaard is `dubbing_v2`. Wordt vastgelegd bij het maken — de bron wordt voorbereid voor dit model, dus noch het project noch een afzonderlijk doel kan dit later wijzigen.
- `keyterms` (list of string, optional) — Kerntermen om de transcriptie en vertaling op te sturen (bijvoorbeeld product- of merknamen). Maximaal 1.000 termen; elke term maximaal 50 tekens en 5 woorden; de tekens `<>{}[]\` zijn niet toegestaan. Termen worden ingekort en ontdubbeld. Herhaal het veld één keer per term of geef één JSON-array door.
- `webhook_ids` (list of string, optional) — ID's van workspace-webhooks die een melding ontvangen naarmate dit project vordert — het aanbevolen alternatief voor polling. Elke webhook ontvangt een `dubbing_project_ready`- of `dubbing_project_failed`-event voor het project, en een `dubbing_language_completed`- of `dubbing_language_failed`-event voor elke onderliggende taal; `dubbing_language_completed` bevat de download-URL's voor de output. Maximaal 3 ID's, die elk al in je workspace zijn geconfigureerd — zie [Webhooks](https://elevenlabs.io/docs/eleven-api/resources/webhooks) voor informatie over het maken van een webhook en het verifiëren van de handtekening. Herhaal het veld eenmaal per ID, of geef één JSON-array of door komma's gescheiden string door. Bezorging gebeurt naar beste vermogen en kan worden herhaald, dus we raden aan events idempotent te verwerken.
- `target_language` (string, optional) — Optionele snelkoppeling: maak ook een taaldoel in deze BCP-47-taal, dat in de wachtrij wordt geplaatst om te starten zodra het project klaar is — gelijk aan het maken van het project en daarna één taaldoel. Moet een van de [talen zijn die het nasynchronisatiemodel ondersteunt](https://elevenlabs.io/docs/help-center/product/dubbing/which-languages-are-supported-in-dubbing), en een tag met regioaanduiding moet een van de ondersteunde dialecten zijn. Dit is het eerste taaldoel en verbruikt daarom de minimale kosten van het project in plaats van deze te verhogen. De ID wordt geretourneerd in `language_ids`.
- `transcript` (file, optional) — Alleen voor Enterprise. Optioneel JSON-transcript om te gebruiken in plaats van de bron te transcriberen: een document `{"segments": [...]}`, met maximaal 20.000 segmenten en 4 MiB. Zie [Gebruik je eigen transcript](https://elevenlabs.io/docs/eleven-api/guides/how-to/dubbing/bring-your-own-transcript) voor de segmentvelden en hun beperkingen. `source_language` is vereist wanneer een transcript wordt opgegeven. Als een segment een `translation` bevat, is `target_language` vereist en moet elk segment er een bevatten; deze vertalingen vormen de basis voor het via `target_language` gemaakte doel, dat machinevertaling vervolgens overslaat.

## Response

### 201

Geslaagde response

- `project_id` (string, required) — Unieke identificatiecode van het nasynchronisatieproject.
- `status` (enum, required) — Levenscyclusstatus van het project: `queued` voordat de bron wordt opgepakt, `preparing` tijdens de transcriptie, `ready` zodra de transcriptie klaar is en taaldoelen kunnen starten, of `failed`. Een project wordt nooit gerapporteerd als `processing` — die waarde hoort bij taaldoelen.
  - Allowed values: `queued`, `preparing`, `processing`, `ready`, `failed`
- `revision` (integer, required) — Monotone teller die wordt verhoogd wanneer het brontanscript wordt bewerkt (segment toevoegen/bewerken/verwijderen).
- `created_at` (string, required) — Wanneer het project is gemaakt.
- `updated_at` (string, required) — Wanneer het project voor het laatst is bijgewerkt.
- `reference` (string, optional, nullable) — De vrije tekenreeks die je bij het maken van het project hebt opgegeven als `reference`, of null als je niets hebt opgegeven.
- `source_language` (string, optional, nullable) — BCP-47-taaltag van de bronmedia (null indien automatisch gedetecteerd).
- `model_id` (string, optional, nullable) — Nasynchronisatiemodel waarmee elk taaldoel van dit project van nasynchronisatie wordt voorzien. Wordt vastgelegd bij het maken en kan niet per taal worden geselecteerd.
- `media` (DubbingSourceMediaInfo, optional, nullable) — Metadata van bronmedia, ingevuld zodra de bron is opgehaald en gedecodeerd (kort na create, voordat het project `ready` is); tot die tijd null.
- `language_ids` (list of string, optional, default: []) — ID's van de taaldoelen onder dit project. Wordt ingevuld wanneer één project wordt opgehaald en bij het maken wanneer `target_language` er een maakt. Is altijd leeg in lijstreacties — vraag in plaats daarvan de taaldoelen van het project op.
- `webhook_ids` (list of string, optional, default: []) — ID's van de workspace-webhooks die een melding ontvangen wanneer dit project en de bijbehorende talen de status `ready`, `completed` of `failed` bereiken.
- `error` (DubbingError, optional, nullable) — Waarom het project is mislukt; null tenzij `status` `failed` is. Ook null voor de enkele projecten die mislukten voordat foutmeldingrapportage werd geïntroduceerd.
- `warnings` (list of VoicesNotPermittedWarning, optional) — Niet-fatale omstandigheden die zijn opgetreden tijdens het voorbereiden van de bron, of leeg als er geen zijn. Weerspiegelt de nieuwste voorbereiding. Omstandigheden die zijn opgetreden tijdens het nasynchroniseren van een specifieke taal worden in plaats daarvan bij die taal gerapporteerd.

## Errors

### 422 Unprocessable Entity Error

Validatiefout

- `detail` (list of ValidationError, optional)

## Types

### DubbingSourceMediaInfo

Metadata over de bronmedia van het project.

- `filename` (string, optional, nullable) — Oorspronkelijke bestandsnaam van de geüploade bronmedia (null voor URL-bronnen).
- `duration_s` (double, optional, nullable) — Duur van de bronmedia, in seconden.
- `has_video` (boolean, optional, nullable) — Of de bronmedia een videostream bevatten.
- `mime_type` (string, optional, nullable) — MIME type of the uploaded source media (null for URL sources).

### DubbingError

- `message_type` ("error", required)
- `error` (string, required)

### VoicesNotPermittedWarning

- `type` ("voices_not_permitted", required) — Identificeert deze waarschuwing; gebruik dit om te vertakken en de andere velden te lezen.
- `speaker_ids` (list of string, required) — Speakers waarvan de stemmen niet mochten worden gekloond. De dub gebruikte voor elk van hen een vervangende stem; alle andere speakers blijven ongewijzigd.
- `message` (string, required) — Voor mensen leesbare beschrijving van de waarschuwing, voor weergave. De formulering kan op elk moment veranderen, dus we raden aan in plaats daarvan te vertakken op `type`.

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)

### ValidationErrorLocItems

## Examples

**Request**

```json
{
  "file": "<file: <file1>>",
  "reference": "Q3 marketing video",
  "source_language": "en",
  "source_url": "https://example.com/promo.mp4",
  "transcript": "<file: <file1>>"
}
```

**Response**

```json
{
  "project_id": "proj_1601kwkyxp0hfzvtmyxwqxx6mcy3",
  "status": "queued",
  "revision": 0,
  "created_at": "2026-07-03T10:15:30Z",
  "updated_at": "2026-07-03T10:15:30Z",
  "reference": "Q3 marketing video",
  "source_language": "en",
  "model_id": "dubbing_v2",
  "language_ids": [],
  "webhook_ids": [],
  "warnings": []
}
```

**SDK Code**

```python
import requests

url = "https://api.elevenlabs.io/v1/dubbing/project"

files = {
    "file": "open('<file1>', 'rb')",
    "transcript": "open('<file1>', 'rb')"
}
payload = {
    "keyterms": ,
    "model_id": ,
    "reference": "Q3 marketing video",
    "source_language": "en",
    "source_url": "https://example.com/promo.mp4",
    "target_language": ,
    "webhook_ids": 
}

response = requests.post(url, data=payload, files=files)

print(response.json())
```

```javascript
const url = 'https://api.elevenlabs.io/v1/dubbing/project';
const form = new FormData();
form.append('file', '<file1>');
form.append('keyterms', '');
form.append('model_id', '');
form.append('reference', 'Q3 marketing video');
form.append('source_language', 'en');
form.append('source_url', 'https://example.com/promo.mp4');
form.append('target_language', '');
form.append('transcript', '<file1>');
form.append('webhook_ids', '');

const options = {method: 'POST'};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.elevenlabs.io/v1/dubbing/project"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keyterms\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model_id\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"reference\"\r\n\r\nQ3 marketing video\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_url\"\r\n\r\nhttps://example.com/promo.mp4\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"target_language\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transcript\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_ids\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("POST", url, payload)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.elevenlabs.io/v1/dubbing/project")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keyterms\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model_id\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"reference\"\r\n\r\nQ3 marketing video\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_url\"\r\n\r\nhttps://example.com/promo.mp4\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"target_language\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transcript\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_ids\"\r\n\r\n\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.elevenlabs.io/v1/dubbing/project")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keyterms\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model_id\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"reference\"\r\n\r\nQ3 marketing video\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_url\"\r\n\r\nhttps://example.com/promo.mp4\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"target_language\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transcript\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_ids\"\r\n\r\n\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.elevenlabs.io/v1/dubbing/project', [
  'multipart' => [
    [
        'name' => 'file',
        'filename' => '<file1>',
        'contents' => null
    ],
    [
        'name' => 'reference',
        'contents' => 'Q3 marketing video'
    ],
    [
        'name' => 'source_language',
        'contents' => 'en'
    ],
    [
        'name' => 'source_url',
        'contents' => 'https://example.com/promo.mp4'
    ],
    [
        'name' => 'transcript',
        'filename' => '<file1>',
        'contents' => null
    ]
  ]
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.elevenlabs.io/v1/dubbing/project");
var request = new RestRequest(Method.POST);
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keyterms\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model_id\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"reference\"\r\n\r\nQ3 marketing video\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"source_url\"\r\n\r\nhttps://example.com/promo.mp4\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"target_language\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"transcript\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_ids\"\r\n\r\n\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation
let parameters = [
  [
    "name": "file",
    "fileName": "<file1>"
  ],
  [
    "name": "keyterms",
    "value": 
  ],
  [
    "name": "model_id",
    "value": 
  ],
  [
    "name": "reference",
    "value": "Q3 marketing video"
  ],
  [
    "name": "source_language",
    "value": "en"
  ],
  [
    "name": "source_url",
    "value": "https://example.com/promo.mp4"
  ],
  [
    "name": "target_language",
    "value": 
  ],
  [
    "name": "transcript",
    "fileName": "<file1>"
  ],
  [
    "name": "webhook_ids",
    "value": 
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://api.elevenlabs.io/v1/dubbing/project")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```