Claude Opus 5 Batch API Tutorial: AI Contract Data Extraction at Scale, with Real Costs
A step-by-step tutorial for bulk AI document extraction with the Claude Opus 5 Batch API: structured outputs with JSON schemas, 50% batch pricing, the 300K output beta, and the real cost of processing 40,000 vendor contracts.
A procurement client came to us with 40,000 vendor contracts in a document store and a question their team had been answering one PDF at a time: which of these auto-renew in the next 90 days, at what price change, with what termination window? Classic bulk-extraction work, where model quality decides whether legal trusts the output and unit economics decide whether the project happens at all.
Claude Opus 5 launched this week at $5/$25 per million tokens, which is Opus 4.8 pricing for a model that trades blows with Fable 5 on benchmarks. Put it behind the Batch API's 50% discount and you're running a frontier model at $2.50/$12.50 per million tokens. That number moved this project from "pilot on a sample" to "run the whole corpus." Here's the full pipeline, as a tutorial you can adapt.
Step 1: make the JSON schema the contract
The most important design decision in bulk AI document extraction is that parsing must never fail on item 31,882. Claude Opus 5's structured outputs make the response schema enforced rather than requested. Pass output_config.format with a JSON schema and the first text block is guaranteed to be valid JSON matching it:
CONTRACT_SCHEMA = {
"type": "object",
"properties": {
"vendor_name": {"type": "string"},
"auto_renews": {"type": "boolean"},
"renewal_date": {"type": ["string", "null"], "format": "date"},
"price_change_pct": {"type": ["number", "null"]},
"termination_notice_days": {"type": ["integer", "null"]},
"governing_law": {"type": "string"},
"confidence": {"type": "string", "enum": ["high", "medium", "low"]},
"needs_human_review": {"type": "boolean"},
"review_reason": {"type": ["string", "null"]},
},
"required": ["vendor_name", "auto_renews", "renewal_date", "price_change_pct",
"termination_notice_days", "governing_law", "confidence",
"needs_human_review", "review_reason"],
"additionalProperties": False,
}
Two of those fields are process rather than data: confidence and needs_human_review. Opus 5 follows instructions literally, and told plainly ("if the renewal terms are ambiguous or reference an external amendment you cannot see, set needs_human_review to true and say why"), it actually does it instead of hallucinating a confident date. About 4% of our corpus came back flagged. That 4% is the product. It's what turns "AI did the contracts" into a review queue legal can staff.
Step 2: build the batch
The Claude Batch API takes up to 100,000 requests or 256 MB per batch, keyed by your custom_id. Everything the synchronous API supports works inside a batch, including structured outputs, PDFs, and prompt caching:
import anthropic
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request
client = anthropic.Anthropic()
SYSTEM = [
{"type": "text", "text": EXTRACTION_INSTRUCTIONS, # ~2K tokens, byte-stable
"cache_control": {"type": "ephemeral"}},
]
def make_request(doc_id: str, contract_text: str) -> Request:
return Request(
custom_id=doc_id,
params=MessageCreateParamsNonStreaming(
model="claude-opus-5",
max_tokens=4000,
output_config={
"effort": "medium",
"format": {"type": "json_schema", "schema": CONTRACT_SCHEMA},
},
system=SYSTEM,
messages=[{"role": "user", "content": contract_text}],
),
)
batch = client.messages.batches.create(
requests=[make_request(d.id, d.text) for d in chunk] # chunks of 10k docs
)
Two choices worth defending. effort: "medium": extraction against a schema isn't open-ended reasoning, and on our 200-document eval sample, medium matched high on field-level accuracy while spending about half the output tokens. Opus 5 defaults to high, so leaving effort unset on a 40,000-document batch is an expensive oversight. The shared system block with cache_control: identical instructions across every request get served from cache, and cache-read pricing stacks with the batch discount.
Step 3: poll, collect, key by custom_id
import time
while True:
batch = client.messages.batches.retrieve(batch.id)
if batch.processing_status == "ended":
break
time.sleep(120)
results, flagged, errored = {}, [], []
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
msg = result.result.message
if msg.stop_reason == "refusal":
errored.append(result.custom_id) # quarantine, don't crash
continue
data = json.loads(next(b.text for b in msg.content if b.type == "text"))
(flagged if data["needs_human_review"] else results)[result.custom_id] = data
else:
errored.append(result.custom_id) # server-side error: resubmit
Results arrive in any order, so key by custom_id and never by position. Note the refusal check even here: Opus 5's safety classifiers apply inside batches too, and one weird scanned document shouldn't kill the run. Most batches complete well under the 24-hour ceiling; ours averaged around 40 minutes per 10K-document chunk.
Step 4 (optional): the 300K output beta for the final report
One launch-week addition specific to batches: with the output-300k-2026-03-24 beta header, Opus 5 supports up to 300K output tokens per request on the Batch API, versus 128K synchronous. We didn't need it for per-contract extraction. We used it for the final act instead: a single request that took the aggregated JSON for the worst 500 contracts and wrote the entire renewal-risk report, per-vendor narratives included, in one pass.
params=MessageCreateParamsNonStreaming(
model="claude-opus-5",
max_tokens=300000,
betas=["output-300k-2026-03-24"], # batch-only extended output
...
)
If you've ever built the "generate the report in 12 chunks and stitch them together" pipeline, you know which module this deletes.
What 40,000 contracts cost on the Claude Opus 5 Batch API
Final tally for the full corpus: roughly 610M input tokens (contracts average around 15K tokens each) and 41M output tokens. At batch rates, with the cached system prompt, the whole job came in just under $1,700 end to end, eval reruns included. The same job at synchronous Fable 5 prices would have been north of $8,000. Done by paralegals at market rates, six figures.
It ran over two nights, flagged 1,630 contracts for human review, and found 217 auto-renewals inside the 90-day window. Nine of those were renewing at price increases nobody had noticed, which paid for the project on their own.
The stack is three launch-week features composing cleanly: structured outputs so parsing never breaks, batch pricing so frontier quality fits the budget, and enough output headroom to write the deliverable in one pass. Bulk document intelligence has been technically possible for two years. What it got this week is a cost story you can put in front of a CFO.
Estimate your project cost, token budget, and automation ROI
We built free, production-calibrated tools to help engineering leaders forecast token consumption, compare build vs buy scenarios, and audit code security.
Work with us on this
Secure, scalable LLM integration services. We embed current OpenAI and Anthropic models into your existing enterprise software, with the provider abstraction that lets you switch later.
AI Agent DevelopmentExpert AI Agent Development services by FoundrySoft. We build scalable, secure, and modern solutions tailored to your business needs.
AI Software DevelopmentExpert AI Software Development services by FoundrySoft. We build scalable, secure, and modern solutions tailored to your business needs.
Related reading
Anthropic cut Fable 5.1 cache-read costs 75% on 1 September 2026. Here is who actually saves money, how to structure prompts so the cache hits, and when Opus 5 is still the right spend.
US Commerce rules from June 2026 restrict some Anthropic frontier SKUs for foreign-national staff. Here is what that means for a US company with an India engineering bench, and the patterns that still ship.
Standard vector chunking fails completely on multi-page financial reports, nested tables, and scanned insurance policies. Here is how we build multi-agent extraction pipelines with schema reflection and deterministic reconciliation.
Let's build something great.
Have a project in mind? We are an elite software and AI development studio ready to bring your ideas to production. Let's talk about your roadmap.