Order Captions
Create Caption orders captions on one media file in a single request. The media (an upload, a URL, or a file already in 3Play) and the order go in the same call.
How it works
- Check the menu. List Products with
type=captionslists what your project can order for the media's language. - Order. Create Caption with the media and
orders[]. You get202 Acceptedand anidfor the order. - Wait. Poll List Captions with
id, or wait for a callback if you passed acallback_urlin your order. - Download. When
statusiscomplete, the order'sdownloadsarray holds a signed URL per file.
Every call authenticates with your API key. See Authentication.
Check the menu
List Products returns one row per package and turnaround your project can order for the media's language. Pass type=captions and the media's source_language; package and turnaround narrow the list further. Availability depends on your project, so check before ordering.
GET /v3/products?type=captions&source_language=en-US
{
"code": 200,
"data": [
{ "type": "captions", "source_language": "en-US", "target_language": "en-US", "variant": null, "package": "launch", "turnaround": "standard" },
{ "type": "captions", "source_language": "en-US", "target_language": "en-US", "variant": null, "package": "launch", "turnaround": "asap" },
{ "type": "captions", "source_language": "en-US", "target_language": "en-US", "variant": null, "package": "refine", "turnaround": "flexible" }
]
}Order
{
"source_url": "https://example.com/lecture.mp4",
"name": "Lecture 3",
"source_language": "en-US",
"external_source_id": "lecture-3",
"callback_url": "https://example.com/hooks/3play?token=abcd-1234",
"orders": [ { "package": "refine", "turnaround": "standard" } ]
}Send JSON, or multipart/form-data when uploading the file in source.
Media. Send exactly one of source (file upload), source_url (3Play downloads it; an authenticated URL must stay valid for at least 1 day), or media_file_id (a file already in 3Play).
Fields.
| Field | Required | Notes |
|---|---|---|
name | yes | Name of the media file |
source_language | yes | BCP-47 code of the media's language. Generic (en) or regional (en-US); a generic code resolves to the project's default variant |
orders | yes | Exactly one entry. See below |
external_source_id | no | Your own key for the media, echoed on each order and in callbacks |
folder_name | no | Folder to file the media under |
description | no | Free-text description of the media |
callback_url | no | URL 3Play calls when the order finishes. See Callbacks |
instructions | no | Free-text instructions for the whole order |
orders[] entry. One entry, with no target_language.
| Field | Required | Notes |
|---|---|---|
package | yes | launch, refine, accommodate, or studio. Not every service offers every package; List Products shows what your project can order |
turnaround | no | standard (default), asap, or flexible. Not every service offers every turnaround; List Products shows what your project can order |
launch is the entry tier and studio the premium tier, with refine and accommodate between them. Which turnarounds a package allows varies by package and project.
The whole request is validated before anything is created. If any order asks for a package, turnaround, or language your project cannot order, the call returns 400 with the allowed values and nothing is ordered.
Response
202 Accepted, with the media and its orders in data:
{
"code": 202,
"data": {
"media_file_id": 123456,
"name": "Lecture 3",
"source_language": "en-US",
"external_source_id": "lecture-3",
"folder_name": null,
"orders": [
{
"id": 987,
"type": "captions",
"media_file_id": 123456,
"source_language": "en-US",
"package": "refine",
"turnaround": "standard",
"status": "in_progress",
"external_source_id": "lecture-3",
"folder_name": null,
"downloads": null
}
]
},
"meta": {}
}Each order's id is the ID of the service: pass it to List Captions as the id filter, and the callback carries the same id.
Track status
Poll List Captions with the order's id, or set callback_url and skip polling. An unknown id returns an empty list. List Captions also filters by media_file_id, external_source_id, status, and folder_name, with page and per_page (default 25, max 100).
status | Meaning |
|---|---|
in_progress | Being worked on |
complete | Done. downloads is populated |
failed | Did not complete. failure says why |
cancelled | 3Play cancelled the order on your behalf. There is no cancel endpoint |
A failed order carries failure, an object with type and message (the same shape as the v3 error object). It is omitted on every other status. The values below are illustrative.
"failure": { "type": "media_error", "message": "The media file could not be processed" }Callbacks
When callback_url is set, 3Play sends one POST per order, when it reaches complete, failed, or cancelled. Nothing fires on intermediate status changes. The body is the same envelope a read of the order returns, downloads included:
{
"code": 200,
"data": {
"id": 987,
"media_file_id": 123456,
"external_source_id": "lecture-3",
"folder_name": null,
"type": "captions",
"source_language": "en-US",
"package": "refine",
"turnaround": "standard",
"status": "complete",
"downloads": [
{
"type": "srt",
"format_name": "SRT",
"mime_type": "application/x-subrip",
"url": "https://api.3playmedia.com/v3/downloads/abc123",
"expires_at": "2026-11-01T12:00:00Z"
}
]
},
"meta": {}
}The download links expire; call List Captions with id for fresh ones. Put an expiring token in the callback URL and check it on receipt; see Using Callback URLs. 3Play retries a callback that fails to deliver.
Download
Once status is complete, downloads holds one entry per file: type, format_name, mime_type, a signed url valid for 8 hours, and expires_at. Call List Captions with id again for fresh links.
type | What it is |
|---|---|
srt, vtt, scc | Captions |
txt, docx, pdf | Transcript |
downloads always holds these formats, plus any formats marked as favorites on your project.
Errors
Errors use the standard v3 error envelope.
| Status | Cause |
|---|---|
400 | A package, turnaround, or language is not available to your project. Call List Products to see what you can order |
400 | A required field is missing |
401 | Missing or invalid API key |
Updated 1 day ago
