Embeddings & multimodal inputs
Every BatchRouter batch item declares an operation that tells the router what kind of work it is and what input shape to expect. There are three: responses (chat-style text generation, the default), embeddings (vector generation), and vision (multimodal prompts that mix text and images). This guide covers the input shape for each, with JSONL you can drop into a batch.
The operation is matched against each model’s supported operations — see GET /v1/catalog/models for which models accept responses, embeddings, or vision. If you omit operation, BatchRouter treats the item as responses.
responses — chat-style generation
Section titled “responses — chat-style generation”Use responses for text generation: summarization, extraction, classification, rewriting, Q&A. The input is a messages array of {role, content} objects, the same shape you already use with chat-completions-style APIs.
{ "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 is your own per-item identifier — it is echoed back on every result so you can join outputs to inputs. model is a slug from GET /v1/catalog/models (gpt-4o-mini here is illustrative). operation may be omitted for responses since it is the default.
embeddings — vector generation
Section titled “embeddings — vector generation”Use embeddings to turn text into vectors for search, retrieval, clustering, or deduplication. The input is an input field that is either a single string or an array of strings (one vector per string).
{ "customer_item_id": "doc-1", "operation": "embeddings", "model": "text-embedding-3-small", "input": { "input": "BatchRouter routes batch-AI workloads across providers." }}{ "customer_item_id": "doc-2", "operation": "embeddings", "model": "text-embedding-3-small", "input": { "input": ["First chunk of text.", "Second chunk of text.", "Third chunk."] }}vision — multimodal (text + images)
Section titled “vision — multimodal (text + images)”Use vision for prompts that combine text with one or more images. The shape is the same messages array as responses, but a message’s content becomes an array of content blocks instead of a plain string. Mix text blocks with image blocks in the order you want the model to see them.
An image block references a file you uploaded first via POST /v1/files, by its returned file_id:
{ "type": "input_image", "file_id": "file_..." }Upload the image, then reference it
Section titled “Upload the image, then reference it”-
Upload the file.
POST /v1/filesstores the image and returns afile_id. The upload defaults to purposemodel_input; send the raw bytes with aContent-Lengthheader (andX-BatchRouter-Purpose: model_inputif you want to be explicit).Terminal window curl -X POST https://api.batchrouter.com/v1/files \-H "Authorization: Bearer $BATCHROUTER_API_KEY" \-H "Content-Type: image/png" \-H "X-BatchRouter-Purpose: model_input" \--data-binary @receipt.pngimport { readFileSync } from 'node:fs';const body = readFileSync('receipt.png');const res = await fetch('https://api.batchrouter.com/v1/files', {method: 'POST',headers: {Authorization: `Bearer ${process.env.BATCHROUTER_API_KEY}`,'Content-Type': 'image/png','X-BatchRouter-Purpose': 'model_input','Content-Length': String(body.length),},body,});const { file_id } = await res.json();import os, requestsbody = open("receipt.png", "rb").read()res = requests.post("https://api.batchrouter.com/v1/files",headers={"Authorization": f"Bearer {os.environ['BATCHROUTER_API_KEY']}","Content-Type": "image/png","X-BatchRouter-Purpose": "model_input",},data=body,)file_id = res.json()["file_id"] -
Reference the
file_idin aninput_imageblock inside your vision item (below). -
Submit the batch as usual via
POST /v1/batches. See Submit a batch.
Vision JSONL example
Section titled “Vision JSONL example”{ "customer_item_id": "receipt-1", "operation": "vision", "model": "gpt-4o-mini", "input": { "messages": [ { "role": "user", "content": [ { "type": "input_image", "file_id": "file_abc123" }, { "type": "text", "text": "Extract the merchant, date, and total from this receipt as JSON." } ] } ] }}Mixing operations in one batch
Section titled “Mixing operations in one batch”A single batch can contain items with different operations and different models — BatchRouter splits them into model-specific internal lanes under your one customer batch. For example, you can embed a corpus and run a vision extraction in the same submission. Each item carries its own operation and model.
Quote before you submit
Section titled “Quote before you submit”Quoting is free and works for every operation. Send a representative subset of items (you do not need to send them all) to POST /v1/quotes/model with the matching operation to see the price before creating the batch.
curl -X POST https://api.batchrouter.com/v1/quotes/model \ -H "Authorization: Bearer $BATCHROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "operation": "embeddings", "model": "text-embedding-3-small", "items": [{ "customer_item_id": "doc-1", "operation": "embeddings", "input": { "input": "Sample text." } }] }'const res = await fetch('https://api.batchrouter.com/v1/quotes/model', { method: 'POST', headers: { Authorization: `Bearer ${process.env.BATCHROUTER_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ operation: 'embeddings', model: 'text-embedding-3-small', items: [ { customer_item_id: 'doc-1', operation: 'embeddings', input: { input: 'Sample text.' } }, ], }),});const quote = await res.json();import os, requests
res = requests.post( "https://api.batchrouter.com/v1/quotes/model", headers={ "Authorization": f"Bearer {os.environ['BATCHROUTER_API_KEY']}", "Content-Type": "application/json", }, json={ "operation": "embeddings", "model": "text-embedding-3-small", "items": [ {"customer_item_id": "doc-1", "operation": "embeddings", "input": {"input": "Sample text."}} ], },)quote = res.json()