Skip to content

Claude Message Batches

Use Anthropic-compatible Message Batches while Model Gate executes every item through its durable internal queue.

No current prepared translation is available. The English source is shown without machine translation.

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"
  }
}