Skip to content

JSONL input format

A BatchRouter batch is a list of items, where each item is one JSON object: a model call you want run. You can send items inline in the request body or upload them as a JSONL file (one item per line) and reference it by input_file_id. This page describes the item shape so your JSONL validates on the first try.

Every item — inline or one JSONL line — has the same four fields:

FieldRequiredDescription
customer_item_idyesYour stable ID for this item. Echoed back on every result so you can join outputs to inputs. Must be unique within the batch.
operationyesresponses, embeddings, or vision. Determines the shape of input.
modelyesA model ID. List real values with GET /v1/catalog/models.
inputyesThe operation-specific payload (see below).

The canonical item, illustrated with gpt-4o-mini (run GET /v1/catalog/models for real, available models):

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

As JSONL, each item is one line — no array, no trailing commas, no blank lines:

{"customer_item_id":"item-1","operation":"responses","model":"gpt-4o-mini","input":{"messages":[{"role":"user","content":"Summarize: BatchRouter routes batch-AI workloads across providers."}]}}
{"customer_item_id":"item-2","operation":"responses","model":"gpt-4o-mini","input":{"messages":[{"role":"user","content":"List three benefits of batch inference."}]}}
{"customer_item_id":"item-3","operation":"embeddings","model":"text-embedding-3-small","input":{"input":"BatchRouter routes batch-AI workloads across providers."}}

The input object differs per operation.

A chat-style request. Provide a messages array of { role, content }:

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

Provide the text to embed under input:

{
"customer_item_id": "item-3",
"operation": "embeddings",
"model": "text-embedding-3-small",
"input": { "input": "BatchRouter routes batch-AI workloads across providers." }
}

A messages array where a user message’s content is a list of content blocks. Use a text block for the prompt and an input_image block that references an uploaded file by file_id:

{
"customer_item_id": "item-4",
"operation": "vision",
"model": "gpt-4o-mini",
"input": {
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Describe what is in this image." },
{ "type": "input_image", "file_id": "file_abc123" }
]
}
]
}
}

Items in one batch can target different models. BatchRouter splits them into model-specific internal lanes, routes and prices each lane independently, and reports everything under a single customer batch id. You poll, retrieve results, and bill against that one batch.

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

Inline items are simplest for small batches. Upload a file when your input is large (a big JSONL of items) or binary (an image or document referenced from an item). Send the raw file body to POST /v1/files with the size and type in headers.

HeaderRequiredValue
Content-LengthyesExact body size in bytes (enforced before storage).
Content-TypeyesThe actual MIME type — text/plain (or application/json) for a JSONL of items, image/png, application/pdf, etc. for binary.
X-BatchRouter-FilenamenoOriginal filename. URL-encode spaces or non-ASCII characters.
X-BatchRouter-PurposenoDefaults to model_input.

Supported binary categories include image/*, audio/*, video/*, text/*, PDF, Word, PowerPoint, Excel, RTF, JSON, and XML. The response returns a file_id.

Terminal window
# Upload a JSONL file of items
curl -X POST https://api.batchrouter.com/v1/files \
-H "Authorization: Bearer $BATCHROUTER_API_KEY" \
-H "Content-Type: text/plain" \
-H "Content-Length: $(wc -c < items.jsonl)" \
-H "X-BatchRouter-Filename: items.jsonl" \
-H "X-BatchRouter-Purpose: model_input" \
--data-binary @items.jsonl
# => { "file_id": "file_abc123", ... }

For a JSONL of items, create the batch with input_file_id instead of inline items. Mixed-model JSONL is supported, and you still pass your quote_id:

{
"input_file_id": "file_abc123",
"quote_id": "qlock_..."
}

For a binary input (an image or document), keep your items inline (or in another JSONL) and reference the uploaded file by its file_id inside a content block, as in the vision example above:

{ "type": "input_image", "file_id": "file_abc123" }