Back to introduction

Batch API

GA-validated · 27/27 PASS

Submit up to 500 audio files against a saved recipe, then let us call you back when the work is done. Every guarantee below passed the GA readiness suite, 27 out of 27.

The async model

Submit a batch and it returns immediately with 202 Accepted and a batch_id. The work runs asynchronously behind a per-tenant fair-concurrency queue, so one account's large batch can never starve another's. Poll the status, or receive a completion webhook, then read the per-item results. Identical audio you resubmit within your own account is analyzed once and reused: we never re-analyze or re-charge you for the same file twice within your account.

Five verbs

The batch surface is five endpoints: submit, check status, read results, cancel, and retry.

VerbRouteBehavior
SubmitPOST /v1/batch202 + batch_id (UUID), status IN_QUEUE, meta.source cloudflare_workflow.
StatusGET /v1/batch/{id}Counters + percent_complete; terminal completed / failed / cancelled.
ResultsGET /v1/batch/{id}/resultsPer-item raw_results (page size 50, has_more).
CancelDELETE /v1/batch/{id}Cancels pending items; in-flight items finish.
RetryPOST /v1/batch/{id}/retryRequeues failed items by lineage (retry_of, attempt+1).

Submit a batch

POST/v1/batch

Queue a batch of audio against a recipe. Returns 202 with a batch_id (UUID) and status IN_QUEUE.

curl -X POST https://api.scarleta.ai/v1/batch \
  -H "Authorization: Bearer $SCARLETA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipe_id": "rec_0007_stem_split",
    "audio_urls": [
      "https://example.com/track-1.wav",
      "https://example.com/track-2.wav"
    ],
    "webhook_url": "https://your-app.com/hooks/scarleta"
  }'

Parameters

NameTypeRequiredDescription
recipe_idstringRequiredThe saved recipe to run over every item (format rec_NNNN_name).
audio_urlsstring[]RequiredUp to 500 audio URLs to process. Duplicate URLs are de-duplicated.
webhook_urlstringOptionalWhere we POST the batch_completed event when the batch is terminal.
max_retriesintegerOptionalPositive integer; per-item automatic retry ceiling.

Response

FieldTypeDescription
batch_idstring (UUID)Identifier for the batch.
statusstringIN_QUEUE on a fresh submit.
meta.sourcestringcloudflare_workflow: the engine running your batch.

Example response

{
  "batch_id": "b1a2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
  "status": "IN_QUEUE",
  "meta": { "source": "cloudflare_workflow" }
}

Check status

GET/v1/batch/{id}

Read live counters and percent_complete. Terminal states are completed, failed, or cancelled.

curl https://api.scarleta.ai/v1/batch/$BATCH_ID \
  -H "Authorization: Bearer $SCARLETA_API_KEY"

Response

FieldTypeDescription
statusstringIN_QUEUE, or terminal completed / failed / cancelled.
total_itemsintegerTotal items in the batch.
completed_itemsintegerItems that finished successfully.
failed_itemsintegerItems that failed after retries.
cancelled_itemsintegerItems cancelled before they ran.
percent_completeintegerProgress from 0 to 100.

Example response

{
  "batch_id": "b1a2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
  "status": "completed",
  "total_items": 2,
  "completed_items": 2,
  "failed_items": 0,
  "cancelled_items": 0,
  "percent_complete": 100
}

Read results

GET/v1/batch/{id}/results

Page through per-item raw_results. Page size is 50; has_more tells you when to fetch the next page.

curl "https://api.scarleta.ai/v1/batch/$BATCH_ID/results?page_size=50" \
  -H "Authorization: Bearer $SCARLETA_API_KEY"

Parameters

NameTypeRequiredDescription
page_sizeintegerOptionalItems per page. Maximum and default is 50.

Response

FieldTypeDescription
itemsobject[]Per-item status and raw_results.
page_sizeintegerItems returned in this page (max 50).
has_morebooleanTrue when another page is available.

Example response

{
  "batch_id": "b1a2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
  "items": [
    {
      "audio_url": "https://example.com/track-1.wav",
      "status": "completed",
      "raw_results": { "…": "per-item output for each recipe step" }
    }
  ],
  "page_size": 50,
  "has_more": false
}

Cancel a batch

DELETE/v1/batch/{id}

Cancel pending items. Items already in flight are allowed to finish; nothing is dropped.

curl -X DELETE https://api.scarleta.ai/v1/batch/$BATCH_ID \
  -H "Authorization: Bearer $SCARLETA_API_KEY"

Retry failed items

POST/v1/batch/{id}/retry

Requeue the failed items of a batch by lineage: each requeued item tracks its retry_of parent and attempt count.

curl -X POST https://api.scarleta.ai/v1/batch/$BATCH_ID/retry \
  -H "Authorization: Bearer $SCARLETA_API_KEY"

Error model

Every error returns a documented, stable code and an HTTP status: no guessing, no opaque 500s. These nine codes cover every way a batch call can be rejected.

Errors

StatusCodeDescription
400missing_audio_urlsThe audio_urls array is empty or absent.
400missing_recipe_idNo recipe_id was supplied.
400invalid_jsonThe request body was not valid JSON.
400invalid_max_retriesmax_retries must be a positive integer.
422batch_too_largeMore than 500 items in a single batch.
404batch_not_foundUnknown batch id, or a batch owned by another account.
409batch_already_finalTried to cancel a batch that has already reached a terminal state.
403batch_paid_onlyThe batch API is paid-only; free-tier keys are rejected by design.
500workflow_binding_missingServer-side deploy-regression guard; the workflow binding was unavailable.

Completion webhook

Don't poll. Pass a webhook_url and we POST a batch_completed event when the batch reaches a terminal state. The payload is exactly these nine keys, in this order:

KeyTypeDescription
eventstringAlways batch_completed.
batch_idstring (UUID)The batch that finished.
statusstringTerminal state: completed, failed, or cancelled.
total_itemsintegerTotal items in the batch.
completed_itemsintegerItems that finished successfully.
failed_itemsintegerItems that failed after retries.
cancelled_itemsintegerItems cancelled before they ran.
actual_total_costintegerLedger-accurate total tokens charged for the batch.
completed_atstring (ISO 8601)When the batch reached its terminal state.

Deliveries are unsigned (the only secret is whatever you embed in the webhook URL), SSRF-guarded so private and loopback targets are never called, retried up to three times with backoff, and idempotent, with no double-POST on replay.

Example response

{
  "event": "batch_completed",
  "batch_id": "b1a2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
  "status": "completed",
  "total_items": 2,
  "completed_items": 2,
  "failed_items": 0,
  "cancelled_items": 0,
  "actual_total_cost": 1234,
  "completed_at": "2026-09-17T18:04:11.000Z"
}

Next steps

Batch API · Scarleta API | Scarleta