> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reedapt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Dub a video into French and Spanish in four requests.

> [!NOTE]
>
> You need an API key. Make one in Reedapt under **Developers** in the account menu. Test keys are free and dub the first 60 seconds of a file, so you can follow this page without using minutes.

Save the key in an environment variable so it stays out of your code:

```bash theme={null}
export REEDAPT_API_KEY="rk_test_…"
```

**1. Start an upload**

Tell us the file's name and size in bytes. The answer has the upload's `id`, its `part_size`, and a signed link for each of the first parts.

```bash cURL theme={null}
curl https://api.reedapt.com/v1/uploads \
  -H "Authorization: Bearer $REEDAPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "talk.mp4", "size": 48213504}'
```

```javascript Node.js theme={null}
const res = await fetch("https://api.reedapt.com/v1/uploads", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.REEDAPT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ filename: "talk.mp4", size: 48213504 }),
});
const upload = await res.json();
```

```python Python theme={null}
import os, requests

upload = requests.post(
    "https://api.reedapt.com/v1/uploads",
    headers={"Authorization": f"Bearer {os.environ['REEDAPT_API_KEY']}"},
    json={"filename": "talk.mp4", "size": 48213504},
).json()
```

```json Response theme={null}
{
  "id": "job_3f9a2c7e1b4d",
  "object": "upload",
  "filename": "talk.mp4",
  "size": 48213504,
  "status": "uploading",
  "part_size": 16777216,
  "part_count": 3,
  "parts": [
    { "part_number": 1, "url": "https://…" },
    { "part_number": 2, "url": "https://…" },
    { "part_number": 3, "url": "https://…" }
  ],
  "parts_expire_at": "2026-10-28T09:27:44Z"
}
```

> [!TIP]
>
> If the file is already online, send `{"source_url": "https://…/talk.mp4"}` instead and skip to step 4 once the upload is `uploaded`. See [Uploading from a link](https://docs.reedapt.com/guides/uploads.md#uploading-from-a-link).

**2. Send the file in parts**

Cut the file into pieces of `part_size` bytes (the last one is shorter) and `PUT` each piece to its link. Keep the `ETag` header from each answer.

```bash theme={null}
split -b 16777216 talk.mp4 part-   # part-aa, part-ab, part-ac
curl -sS -X PUT --upload-file part-aa "<parts[0].url>" -D - -o /dev/null | grep -i etag
```

> [!WARNING]
>
> Don't send your API key to the signed links. They already carry their own permission, and an extra `Authorization` header makes storage refuse the request.

[Uploads](https://docs.reedapt.com/guides/uploads.md#uploading-in-parts) has a complete upload function in Node.js and Python.

**3. Complete the upload**

List every part with its ETag. We join the parts into the file.

```bash theme={null}
curl https://api.reedapt.com/v1/uploads/job_3f9a2c7e1b4d/complete \
  -H "Authorization: Bearer $REEDAPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"parts": [
        {"part_number": 1, "etag": "\"3858f62230ac3c91\""},
        {"part_number": 2, "etag": "\"9b2cf535f27731c9\""},
        {"part_number": 3, "etag": "\"6f1e9c2ab47d03e5\""}
      ]}'
```

The upload's `status` becomes `uploaded`.

**4. Start the dubs**

Ask for the languages you want. You get one dub per language.

```bash theme={null}
curl https://api.reedapt.com/v1/dubs \
  -H "Authorization: Bearer $REEDAPT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: talk-2026-10-28" \
  -d '{"upload_id": "job_3f9a2c7e1b4d", "source_language": "en", "target_languages": ["fr", "es"]}'
```

The `Idempotency-Key` means you can safely send the request again after a timeout: you get the first answer back instead of a second set of dubs. See [Repeated requests](https://docs.reedapt.com/idempotency.md).

## Get the dubbed files

When a dub finishes we send a `dub.completed` [webhook](https://docs.reedapt.com/guides/webhooks.md). You can also check on it with `GET /dubs/{id}`. Then ask for its files:

```bash theme={null}
curl https://api.reedapt.com/v1/dubs/job_3f9a2c7e1b4d/files \
  -H "Authorization: Bearer $REEDAPT_API_KEY"
```

```json Response theme={null}
{
  "files": [
    { "kind": "dub", "filename": "talk_dubbed_french.mp4", "url": "https://…" }
  ],
  "expires_at": "2026-10-28T10:31:02Z"
}
```

Each link lasts an hour. Ask again whenever you need fresh ones.

## Next steps

> **[Set up webhooks](https://docs.reedapt.com/guides/webhooks.md)**
>
> Stop polling and hear about each dub as it finishes.

> **[Handle errors](https://docs.reedapt.com/errors.md)**
>
> Every error has the same shape and a stable code.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.