Skip to content

Submit a batch

Creating a batch submits your work for asynchronous processing and reserves credits against a quote. You send POST /v1/batches with either inline items or a reference to an uploaded file, accept a quote_id, and pass an Idempotency-Key so retries are safe.

This is the deep version of step 3 of the quickstart. It assumes you already have an API key (see Authentication) and a quote (see Quotes and pricing).

You need two things in hand:

  • An API key, sent as Authorization: Bearer br_live_…. Keep it server-side.
  • A quote_id (qlock_…) from POST /v1/quotes/model. The quote is free, pins your price estimate, and is required to reserve credits before dispatch.

A batch’s work comes from exactly one of two sources — they are mutually exclusive:

  • items — an inline array of batch items. Best for small-to-medium batches you assemble in memory.
  • input_file_id — a file_… id from a JSONL file you uploaded with POST /v1/files. Best for large batches or binary inputs. See JSONL format for the line shape and the file-based example below.

Send one or the other. Sending both — or neither — fails preflight with 400 and error.details.preflight.

The canonical item used across these docs:

{"customer_item_id":"item-1","operation":"responses","model":"gpt-4o-mini","input":{"messages":[{"role":"user","content":"Summarize: BatchRouter routes batch-AI workloads across providers."}]}}

POST /v1/batches requires an Idempotency-Key header — a unique string of 8–128 characters per logical submission. If a network error leaves you unsure whether the batch was created, retry with the same key: BatchRouter returns the original batch instead of creating a duplicate. Use a fresh key for each new batch (a UUID works well).

Beyond the input and quote_id, the body accepts these optional fields:

FieldValuesDefaultWhat it does
sla_tierstandard · flex · prioritystandardstandard = 24h SLA; flex = up to 48h, cheaper; priority = expedited.
routing_modecheapest · sla_aware · public_only · edge_only · hybrid · privacy_constrainedcheapestHow BatchRouter selects a lane across providers.
privacy_tierstandard · confidential · restrictedstandardconfidential routes to data-retention opt-out providers; restricted routes only to private edge nodes.
webhook{ url, secret }Per-batch completion callback; secret is 8+ chars and signs X-BatchRouter-Signature.
metadataobjectArbitrary key/value pairs echoed back on the batch.
  1. Assemble your items and accept the quote.

  2. Send the request with an Idempotency-Key.

    Terminal window
    curl -X POST https://api.batchrouter.com/v1/batches \
    -H "Authorization: Bearer $BATCHROUTER_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
    "quote_id": "qlock_abc123",
    "sla_tier": "standard",
    "routing_mode": "cheapest",
    "privacy_tier": "standard",
    "items": [
    {
    "customer_item_id": "item-1",
    "operation": "responses",
    "model": "gpt-4o-mini",
    "input": {
    "messages": [
    { "role": "user", "content": "Summarize: BatchRouter routes batch-AI workloads across providers." }
    ]
    }
    }
    ],
    "webhook": {
    "url": "https://example.com/hooks/batchrouter",
    "secret": "a-strong-shared-secret"
    },
    "metadata": { "project": "docs-demo" }
    }'
  3. Store batch.id (bat_…) and poll for completion. See Results.

For large or binary inputs, upload a JSONL file first, then reference its file_id. Use input_file_id instead of items.

Terminal window
curl -X POST https://api.batchrouter.com/v1/batches \
-H "Authorization: Bearer $BATCHROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"quote_id": "qlock_abc123",
"input_file_id": "file_xyz789",
"sla_tier": "flex",
"routing_mode": "sla_aware"
}'

A successful create returns 202 Accepted — the batch is queued for routing, not yet processed. The body wraps the batch summary:

{
"batch": {
"id": "bat_9f3c2a1b",
"status": "pending",
"item_count": 1,
"created_at": "2026-06-18T10:00:00Z",
"sla_deadline": "2026-06-19T10:00:00Z"
}
}
FieldMeaning
batch.idThe bat_… identifier you poll and fetch results with.
batch.statusStarts at pending, then advances queued → routing → dispatched → processing → completing → completed.
batch.item_countNumber of items accepted into the batch.
batch.sla_deadlineThe SLA deadline by which the batch is expected to complete, derived from the chosen sla_tier.

Replaying the same Idempotency-Key returns this same response rather than creating a second batch.

StatusCauseFix
400Preflight failed (bad JSONL, both/neither input, context window exceeded, unsafe webhook URL).Inspect error.details.preflight; see JSONL format.
401Missing or invalid key.Check your Authorization header — see Authentication.
402Insufficient credits.Check GET /v1/auth/account; top up credits in the dashboard at https://batchrouter.com/app/billing.
409Conflict (e.g. reused key on a different payload).Use a fresh Idempotency-Key for a new batch.