If your workload can wait until tomorrow, both APIs offer lower model charges. OpenAI uses uploaded JSONL and supports several endpoints; Anthropic accepts Messages requests directly and exposes typed outcomes.
Use OpenAI Batch for mixed offline API work such as responses, embeddings, and moderation. Prefer Anthropic Message Batches when the workload is built around Claude Messages, particularly when many requests share a long prompt prefix. Neither fits a blocking CI check or an interactive user flow.
All prices, limits, and product behavior below are from official documentation as of 2026-07-20.
The short comparison
| Decision point | OpenAI Batch API | Anthropic Message Batches |
|---|---|---|
| Discount | 50% below synchronous API pricing | 50% of standard API prices |
| Processing window | 24h is the only supported completion window | Results are released when all requests finish or at 24 hours; unfinished requests expire |
| Typical completion claim | Within 24 hours, often sooner | Most batches finish within one hour |
| Submission | Upload one JSONL file, then create a batch using its file ID | Send an array of {custom_id, params} requests in the create call |
| Maximum batch | 50,000 requests and a 200 MB input file | 100,000 requests or 256 MB, whichever comes first |
| Result delivery | Separate output and error JSONL files through the Files API | One streamed or downloaded JSONL result set with typed outcomes |
| Ordering | May differ from input; join on custom_id | May differ from input; join on custom_id |
| Prompt caching | Batch usage reports cached input; OpenAI caching rules still depend on model, prefix, and retention | Explicitly supported; cache and batch discounts can stack, but hits are best effort |
OpenAI documents its discount, 24-hour window, supported endpoints, and limits in the Batch API guide. Anthropic documents its discount, timing, size ceiling, result lifecycle, and caching behavior in the Message Batches guide.
Submission format changes your ingestion pipeline
OpenAI: build and upload JSONL first
Each line in an OpenAI batch input file is an HTTP request envelope. It needs a unique custom_id, POST method, relative url, and endpoint-specific body. A simplified document-extraction input looks like this:
{"custom_id":"doc-0042","method":"POST","url":"/v1/responses","body":{"model":"YOUR_MODEL","input":"Extract invoice number, date, and total from: ..."}}
You upload the .jsonl file with purpose batch, then create the batch using the returned input_file_id, the target endpoint, and completion_window: "24h". One input file can target only one model. As of 2026-07-20, OpenAI lists Responses, Chat Completions, Embeddings, Completions, Moderations, image generation, image edits, and video among supported batch routes; check the guide because model and route support can change.
This two-step design fits data platforms that already write immutable job manifests. It also adds a staging step: malformed lines or a mismatched endpoint can invalidate work before inference begins.
Anthropic: submit Messages parameters as a request list
Anthropic’s create call accepts a requests array. Each item has a unique custom_id and a params object shaped like a normal Messages API call:
{
"requests": [
{
"custom_id": "doc-0042",
"params": {
"model": "YOUR_MODEL",
"max_tokens": 500,
"messages": [{"role": "user", "content": "Extract invoice number, date, and total from: ..."}]
}
}
]
}
This is simpler for an application already producing Messages requests in memory. Anthropic permits different request types in one batch because each item is independent. Validation of each params object happens asynchronously, so test the shape first with the synchronous Messages API.
Turnaround is a deadline, not a latency target
OpenAI’s only documented completion window is 24 hours, as of 2026-07-20. Anthropic also expires unfinished requests after 24 hours, although its official guide says most batches complete within one hour. Treat the shorter figure as an observation, not a service-level promise.
For nightly evals, schedule backward from the consumer. Submit the previous evening, poll with backoff, and define what happens when only partial results exist.
The APIs expose different state models. OpenAI batches progress through statuses including validating, in_progress, finalizing, completed, failed, expired, cancelling, and cancelled, according to the Batch API reference. Anthropic’s batch-level processing_status moves from in_progress to ended; the detailed outcome sits on every request.
Results and retries require an ID-based join
OpenAI puts successes in output_file_id and failures in error_file_id. Download both through the Files API and join by custom_id, never line number. Output files are deleted 30 days after completion, as of 2026-07-20, so retain required records elsewhere.
Anthropic exposes a results_url after processing ends and recommends streaming large results. Each JSONL line is succeeded, errored, canceled, or expired. Results remain available for 29 days after batch creation, as of 2026-07-20. The retrieve endpoint reference says result order may differ from request order.
Build retries from a ledger containing custom_id, source checksum, attempt number, provider batch ID, terminal type, and output location:
- Do not retry successful items.
- Fix validation or invalid-request errors before resubmission.
- Retry transient server errors and expired items in a new batch with a bounded attempt count.
- Keep the original record ID and make ingestion idempotent so late duplicates cannot overwrite accepted results.
OpenAI charges completed requests in an expired batch; unfinished requests go to the error file. Anthropic does not bill errored, canceled, or expired requests. These are official rules as of 2026-07-20.
Size and rate limits favor different shapes
OpenAI caps one batch at 50,000 requests and 200 MB. Embeddings batches also have a 50,000-input ceiling across all request lines. Batch rate limits use a separate pool from synchronous per-model limits, and OpenAI also applies model-specific enqueued-token limits. The official guide lists a batch-creation limit of 2,000 batches per hour as of 2026-07-20.
Anthropic allows up to 100,000 requests or 256 MB per Message Batch, whichever comes first. Workspace rate limits apply both to Batch API calls and queued requests. Anthropic also notes that demand can slow processing and increase the number of requests that expire at 24 hours.
Prompt caching can help, but measure actual hits
OpenAI prompt caching works on exact shared prefixes. Its prompt caching guide says caching is enabled automatically for prompts of at least 1,024 tokens, as of 2026-07-20, and reports cache reads as cached_tokens. Current batch objects also expose cached-token usage. Put stable instructions, schemas, tools, and examples first; append the per-document text last. Cache behavior and write pricing vary by model family, so log usage rather than assuming that every shared prefix receives the same discount.
Anthropic is more explicit about the combination: its official batch guide says prompt-caching and batch discounts can stack. Add identical cache_control blocks to the shared prefix in every request. Because requests execute asynchronously and concurrently, cache hits are best effort. Anthropic reports observed hit rates ranging from 30% to 98%, depending on traffic patterns, and recommends the one-hour cache duration for shared batch context because the default five-minute entry may expire while the batch runs. Those figures and TTLs are official specifications as of 2026-07-20, not a forecast for your workload.
For nightly extraction, place the policy and JSON schema in the cached prefix and each document in the suffix. Measure Claude’s cache_read_input_tokens and cache_creation_input_tokens, or OpenAI’s cached and cache-write fields, before projecting savings.
Worked choice: 40,000-document extraction
Suppose 40,000 documents arrive nightly. Every request shares a long extraction rubric and emits a small JSON object for a morning warehouse load.
With OpenAI, write 40,000 JSONL envelopes, upload the file, create one batch, and reconcile both result files by custom_id. This fits the official ceiling as of 2026-07-20. Two 20,000-record shards reduce retry scope.
With Anthropic, send one batch or two smaller arrays. Mark the rubric with cache_control and consider a one-hour TTL. Stream successes to validation, fix invalid requests, and retry transient or expired rows.
The discount does not select a winner. Run the same sample through both models and compare schema-valid records, correction rate, cached-token usage, and cost per accepted document.
Use OpenAI Batch when…
- Your offline pipeline needs more than text generation, especially embeddings or moderation.
- An uploaded JSONL manifest fits your audit and replay architecture.
- Separate batch rate-limit headroom is important.
- Your team already uses Responses or Chat Completions.
Use Claude Message Batches when…
- The application is already centered on the Messages API.
- You want the larger official ceiling of 100,000 requests or 256 MB per batch, as of 2026-07-20.
- Many requests share a long context and you can measure the documented stacking of prompt-cache and batch discounts.
- Typed results in one stream simplify reconciliation.
Bottom line
Choose the model on task quality, then the wrapper on operational fit. OpenAI has broader endpoints and a file workflow. Anthropic has a larger envelope, direct Messages submission, and explicit batch-caching guidance. For either, use durable IDs, test synchronously before scaling, and budget against accepted outputs.