Skip to content

Batch

Submit several videos in one request and follow their progress.

Examples use VIDEO_ID and clp_live_... as placeholders.

Submit a batch

Send POST /v1/batch with a JSON body:

curl -X POST "https://clypso-eta.vercel.app/v1/batch" \
  -H "Authorization: Bearer clp_live_..." \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID_1","https://www.youtube.com/watch?v=VIDEO_ID_2"]}'
FieldRequiredMeaning
urlsYesThe YouTube video URLs. Each one takes the same forms as url in Extraction.
formatsNoAs in Extraction, for every item.
langNoAs in Extraction, for every item.

An accepted batch returns a 202 with one job for each unique video. The Location header holds the batch's path.

JSON
{
  "batch_id": "BATCH_ID",
  "status": "running",
  "items": [
    {
      "url": "https://www.youtube.com/watch?v=VIDEO_ID_1",
      "job_id": "JOB_ID_1"
    },
    {
      "url": "https://www.youtube.com/watch?v=VIDEO_ID_2",
      "job_id": "JOB_ID_2"
    }
  ]
}
  • Items keep the order you sent them in.
  • Repeats of a video collapse onto its first URL, so items can be shorter than urls.
  • Each url in the response is the video's standard watch URL, whatever form you sent.

Limits and rejections

During early access, a batch can hold 10 URLs. Duplicates count toward that, because the check runs before they collapse.

A batch is accepted or rejected whole. When it's rejected, no batch or job is created.

ProblemYou get
More than 10 URLsA 400 with batch_too_large.
A URL that isn't a YouTube videoA 400 with invalid_batch_item. The message lists the indexes of the bad URLs.
Malformed JSON, an unknown field, an unknown format name, an empty urls list, a URL over 2,048 characters, or more than 1,000 URLsA 400 with invalid_request.
Fewer monthly videos left than unique videos in the batchA 429 with quota_exceeded. Queued work is subtracted first. Every unique video needs room here, even one that turns out to be cached.
Your queued and running API and batch jobs, plus this batch, would pass twice your batch limitA 429 with rate_limited and a Retry-After of 60 seconds. Try again when some have finished.

Follow its progress

Poll GET /v1/batch/:batchId. In the example, replace the batchId placeholder with the batch_id you got:

curl -X GET "https://clypso-eta.vercel.app/v1/batch/{batchId}" \
  -H "Authorization: Bearer clp_live_..."
JSON
{
  "batch_id": "BATCH_ID",
  "status": "running",
  "created_at": "2026-11-05T09:30:00.000Z",
  "completed_at": null,
  "counts": {
    "total": 2,
    "pending": 0,
    "running": 1,
    "succeeded": 1,
    "failed": 0
  },
  "items": [
    {
      "job_id": "JOB_ID_1",
      "url": "https://www.youtube.com/watch?v=VIDEO_ID_1",
      "status": "succeeded",
      "error_code": null
    },
    {
      "job_id": "JOB_ID_2",
      "url": "https://www.youtube.com/watch?v=VIDEO_ID_2",
      "status": "running",
      "error_code": null
    }
  ]
}
statusWhat to do
runningItems are still in progress. Poll again.
completedStop. Every item has finished, which doesn't mean every item worked. Check counts.failed.

This response has no results. To read one, poll GET /v1/extract/:jobId with the item's job_id, as in Extraction.

Wait a few seconds between polls. Each poll counts toward the rate limit of 60 a minute, and none of them use your monthly limit. To be told when a batch finishes instead, use the batch.completed event in Webhooks.

A batch is visible only to the account that created it. An unknown batch and another account's batch both get a 404 with batch_not_found.

How items run

  • Each item is an ordinary job that runs in the background, and they don't all start at once.
  • Each one counts against your monthly limit as a single extraction would. A cached result or a failed run doesn't count.
  • One failure doesn't stop the others. An item fails with its own code in error_code, such as no_captions or video_too_long. See Errors.
  • An item that works also lands in your library in the dashboard.
  • To try a failed item again, send it in a new request.

Retry safely

Send an Idempotency-Key header so a retry after a network error can't queue the batch twice. It works as it does for Extraction: the same key and body return the first 202 again, a different body gets a 409 with idempotency_key_reused, and a first request still running gets a 409 with request_in_progress.

A 400 or the queued work 429 doesn't use up the key, so you can retry with it. A quota_exceeded response is stored and replayed, so use a new key after that one.