OpenRouter allows you to batch requests1. Providers discount batch traffic to fill idle capacity, and OpenRouter passes the discount through to the client. The examples use Claude Sonnet 5, where batched requests costs 50% of the regular API pricing.
Synchronous API
| Page | In / Out per 1M |
|---|---|
| Sync | $2.00 / $10.00 |
results = []
for doc in docs:
response = client.chat.completions.create(
model="anthropic/claude-sonnet-5",
messages=[{"role": "user", "content": f"Summarize: {doc}"}],
)
results.append(response.choices[0].message.content)
Asynchronous Batch API
| Page | In / Out per 1M |
|---|---|
| Batch | $1.00 / $5.00 |
The batch route bills at exactly half the sync rate.
batch = requests.post(
"https://openrouter.ai/api/beta/batches",
headers={"Authorization": f"Bearer {key}"},
json={
"endpoint": "/v1/chat/completions",
"model": "anthropic/claude-sonnet-5",
"requests": [
{
"custom_id": f"doc-{i}",
"body": {"messages": [{"role": "user", "content": doc}]},
}
for i, doc in enumerate(docs)
],
},
)
# Poll GET /api/beta/batches/:id until status == "completed".
# The finished results come back inline, matched by custom_id.
What the same workload costs
For example, classifying 10,000 support tickets at 1,000 input tokens and 200 output tokens each lands us at 10M input tokens and 2M output tokens:
| Route | In $/1M | Out $/1M | Cost (10M in + 2M out) |
|---|---|---|---|
| Sync | $2.00 | $10.00 | $40.00 |
| Batch | $1.00 | $5.00 | $20.00 |
The batch route costs 50% of the sync price and saves $20.00 on one job. Run the same job weekly and batch saves $1,040 a year on this model alone.
Embeddings
The batch endpoint also
covers /v1/embeddings, with inputs as strings or token arrays. The
Embeddings API reference
documents the request and response shape.
In Rust: openrouter-batch
I packaged this flow as openrouter-batch, a small Rust client for the Batch API, structured output, and embeddings (docs.rs).
The demo is two questions, one shared strict JSON Schema, submitted as a batch to a :batch model. The examples/cli.rs binary runs it against the live API:
cargo run --release --example cli -- batch
Output from my run β status transitions, counts, usage, then each decoded result line keyed by custom_id:
submitted: batch-1788203224-A92OrCi1hb82JNrfN6M1 status: Validating
status: InProgress
status: Completed
request_counts: Some(RequestCounts { total: 2, completed: 2, failed: 0 })
usage: Some(BatchUsage { prompt_tokens: Some(52), completion_tokens: Some(27), total_tokens: Some(79), cost: Some(2.13e-5), is_byok: Some(false) })
req-1: {"answer": "4", "confidence": 99}
req-2: { "answer": "21", "confidence": 1 }
The whole run cost $0.0000213.
Footnotes
-
OpenRouter's Batch API Quickstart covers submission, polling, limits, and pricing. β©
