Order Subs

Create Subs orders subtitles in any number of target languages 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, one order per target language, each with its own package.

How it works

  1. Check the menu. List Products with type=subs lists which target languages, packages and turnarounds your project can order from the source language.
  2. Order. Create Subs with the media and orders[]. You get 202 Accepted and an id for each target language.
  3. Wait. Poll List Subs with id, or wait for a callback if you passed a callback_url in your order.
  4. Download. When status is complete, the order's downloads array holds a signed URL per file.

Every call authenticates with your API key. See Authentication.

Check the menu

List Products returns one row per target language, package and turnaround your project can order from the source language. Pass type=subs and the media's source_language; target_language, package and turnaround narrow the list further. Availability depends on your project, so check before ordering.

GET /v3/products?type=subs&source_language=en-US
{
  "code": 200,
  "data": [
    { "type": "subs", "source_language": "en-US", "target_language": "fr-FR", "variant": null, "package": "refine", "turnaround": "standard" },
    { "type": "subs", "source_language": "en-US", "target_language": "fr-FR", "variant": null, "package": "studio", "turnaround": "standard" },
    { "type": "subs", "source_language": "en-US", "target_language": "de-DE", "variant": null, "package": "creator", "turnaround": "standard" }
  ]
}

Order

{
  "source_url": "https://example.com/master.mp4",
  "name": "Episode 12",
  "source_language": "en-US",
  "external_source_id": "master-s02e12",
  "callback_url": "https://example.com/hooks/3play?token=abcd-1234",
  "orders": [
    { "target_language": "fr-FR", "package": "refine" },
    { "target_language": "de-DE", "package": "studio" }
  ]
}

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.

FieldRequiredNotes
nameyesName of the media file
source_languageyesBCP-47 code of the media's language. Generic (en) or regional (en-US); a generic code resolves to the project's default variant
ordersyesOne entry per target language. See below
localization_profile_idnoLocalization profile to apply. Defaults to the project's default profile
external_source_idnoYour own key for the media, echoed on each order and in callbacks
folder_namenoFolder to file the media under
descriptionnoFree-text description of the media
callback_urlnoURL 3Play calls when each target language finishes. See Callbacks
instructionsnoFree-text instructions for the whole order

orders[] entry.

FieldRequiredNotes
target_languageyesBCP-47 code. Must be a target_language that List Products returns with type subs for the source language
packageyeslaunch, refine, creator, or studio. Not every service offers every package; List Products shows what your project can order
turnaroundnostandard (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 creator between them.

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": "Episode 12",
    "source_language": "en-US",
    "external_source_id": "master-s02e12",
    "folder_name": null,
    "orders": [
      {
        "id": 987,
        "type": "subs",
        "media_file_id": 123456,
        "source_language": "en-US",
        "target_language": "fr-FR",
        "package": "refine",
        "turnaround": "standard",
        "status": "in_progress",
        "external_source_id": "master-s02e12",
        "folder_name": null,
        "downloads": null
      }
    ]
  },
  "meta": {}
}

Each order's id is the ID of the service: pass it to List Subs as the id filter, and the callback carries the same id.

Track status

Poll List Subs with the order's id, or set callback_url and skip polling. An unknown id returns an empty list. List Subs also filters by media_file_id, external_source_id, status, and folder_name, with page and per_page (default 25, max 100).

statusMeaning
in_progressBeing worked on
completeDone. downloads is populated
failedDid not complete. failure says why
cancelled3Play 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 (so once per target language), 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": "master-s02e12",
    "folder_name": null,
    "type": "subs",
    "source_language": "en-US",
    "target_language": "fr-FR",
    "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 Subs 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 Subs with id again for fresh links.

typeWhat it is
srt, vttBy default
dfxp, scc, smptett, ttml, xml (EBU-TT-D)Where your project enables them

Errors

Errors use the standard v3 error envelope.

StatusCause
400A package, turnaround, or language is not available to your project. Call List Products to see what you can order
400A required field is missing
401Missing or invalid API key

Did this page help you?