Claude Message Batches
Use Anthropic-compatible Message Batches while Model Gate executes every item through its durable internal queue.
Existing Batch read/control operations remain available at zero balance for a valid active key. Creating a batch with POST /v1/messages/batches requires a positive balance and available spending allowance. Individual items must still satisfy the current limits when execution starts; insufficient funds can leave them queued. Active-job and queued-item quotas are independent limits, not evidence of an account charge.
Model Gate implements an Anthropic-compatible Message Batches API on https://api.model-gate.com. It is a compatibility layer: Model Gate stores the batch durably and executes each item through the normal Model Gate /v1/messages path. It does not submit a provider-native Anthropic batch upstream.
Use a normal Model API key (mg_live_...). Every item is accounted as an individual request with request_mode=batch, batch_protocol=claude, the batch ID, and its custom_id.
Streaming is not supported inside a batch. Model aliases are resolved before the item is queued.
Create a message batch
Request
curl https://api.model-gate.com/v1/messages/batches \
-H "x-api-key: mg_live_..." \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"requests": [
{
"custom_id": "summary-1",
"params": {
"model": "ch-47",
"max_tokens": 256,
"messages": [{"role":"user","content":"Summarize this text."}]
}
}
]
}'
Response — 200
{
"id": "msgbatch_01K...",
"type": "message_batch",
"processing_status": "in_progress",
"request_counts": {
"processing": 1,
"succeeded": 0,
"errored": 0,
"canceled": 0,
"expired": 0
},
"ended_at": null,
"created_at": "2026-08-13T08:30:00Z",
"expires_at": "2026-08-14T08:30:00Z",
"cancel_initiated_at": null,
"results_url": null
}
Retrieve a batch
Request
curl https://api.model-gate.com/v1/messages/batches/msgbatch_01K... \
-H "x-api-key: mg_live_..."
Response — ended
{
"id": "msgbatch_01K...",
"type": "message_batch",
"processing_status": "ended",
"request_counts": {
"processing": 0,
"succeeded": 1,
"errored": 0,
"canceled": 0,
"expired": 0
},
"ended_at": "2026-08-13T08:30:04Z",
"results_url": "https://api.model-gate.com/v1/messages/batches/msgbatch_01K.../results"
}
Read results
Results are returned as JSON Lines. Do not assume that application logic depends on the original input order; match results by custom_id.
Request
curl https://api.model-gate.com/v1/messages/batches/msgbatch_01K.../results \
-H "x-api-key: mg_live_..."
Response — 200
{"custom_id":"summary-1","result":{"type":"succeeded","message":{"id":"msg_...","type":"message","role":"assistant","content":[{"type":"text","text":"..."}]}}}
List batches
limit defaults to 20 and must be from 1 to 100. Use after_id or before_id for cursor pagination; do not send both in one request.
Request
curl "https://api.model-gate.com/v1/messages/batches?limit=20&after_id=msgbatch_01K..." \
-H "x-api-key: mg_live_..."
Response — 200
{
"data": [],
"has_more": false,
"first_id": null,
"last_id": null
}
Cancel a batch
Cancel stops queued items from being claimed. An item already processing may finish.
Request
curl -X POST https://api.model-gate.com/v1/messages/batches/msgbatch_01K.../cancel \
-H "x-api-key: mg_live_..."
Response — 200
{
"id": "msgbatch_01K...",
"type": "message_batch",
"processing_status": "canceling",
"request_counts": {
"processing": 1,
"succeeded": 0,
"errored": 0,
"canceled": 0,
"expired": 0
}
}
Delete an ended batch
Delete is accepted only after the batch has reached a terminal state.
Request
curl -X DELETE https://api.model-gate.com/v1/messages/batches/msgbatch_01K... \
-H "x-api-key: mg_live_..."
Response — 200
{
"id": "msgbatch_01K...",
"type": "message_batch_deleted"
}
Recovery semantics
Batch execution is at-least-once, not exactly-once. An interruption can lead to another attempt even when the provider accepted the first request. The Model Gate request ID stays the same, and duplicate-billing protection applies to already-finished requests. External tool actions still need application-level idempotency.
Before an item starts, the account balance and key/group spending allowance must still permit execution. Otherwise-valid items stay queued when funds or allowance are exhausted, without consuming an attempt. A top-up, usage reset or limit increase can make them eligible again. There is no worst-case cost reservation: concurrent accepted items can finish above the remaining balance or limit; only later items are held.
Pricing and accounting
Each batch item uses the same model routing, token accounting, pricing snapshot, usage valuation, API-key/group limits, and settlement logic as a normal Model Gate request. Your account pricing may include a Batch request price coefficient. The default is 1; check your applicable pricing before submission.
For example, with normal Model Gate cost 0.02 and batch coefficient 0.5, the actual account debit is 0.01. The saved official-provider reference amount is not multiplied by this Model Gate batch coefficient. Native requests using "async": true are also not affected.
If the coefficient differs from 1, it is shown on the Model prices page. The minimal /v1/models response no longer includes batch_pricing or batch_cost; the actual billing coefficient and saved request accounting are unchanged.
Errors
Invalid or duplicate custom_id, an unknown model, stream:true, nested async:true, an oversized request, or an invalid body returns a normal Anthropic-style error response.
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "summary-1: stream=true is not supported inside a batch"
}
}