---
title: "Claude Opus 5 Batch API Tutorial: AI Contract Data Extraction at Scale, with Real Costs"
description: "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."
image: "https://foundrysoft.co/api/og?type=article&title=Claude+Opus+5+Batch+API+Tutorial%3A+AI+Contract+Data+Extraction+at+Scale%2C+with+Real+Costs&cat=AI+Engineering&rt=10+min+read&au=Varun+Raj+Manoharan&dt=2026-07-25"
url: "https://foundrysoft.co/blog/claude-opus-5-batch-api-contract-extraction"
---

AI Engineering 2026-07-25 10 min read

# 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.

![Varun Raj Manoharan](https://foundrysoft.co/images/about/founder.webp)

Varun Raj Manoharan

Claude Opus 5 Anthropic Batch API Structured Outputs Document Extraction Python

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:

Python

Copy

```python
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:

Python

Copy

```python
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

Python

Copy

```python
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.

Python

Copy

```python
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.

#### Related reading

[Claude Opus 5 vs Grok 4.5 vs Muse Spark 1.1: Which Agentic Model to Use in 2026

An independent comparison of the three agentic models that launched this month. Real pricing, production failure modes, cost per completed task, and the routing table we actually run, not a benchmark aggregation.

Claude Opus 5 Grok 4.5 Muse Spark

](https://foundrysoft.co/blog/claude-opus-5-vs-grok-4-5-vs-muse-spark-comparison)[Claude Opus 5 Effort Parameter Guide: How to Reduce Claude API Costs Without Switching Models

How to use the Claude Opus 5 effort parameter (low, medium, high, xhigh, max) to cut Claude API costs. Real per-request cost numbers, working Python code, and why we retired our Haiku/Sonnet/Opus routing layer.

Claude Opus 5 Anthropic Claude API

](https://foundrysoft.co/blog/claude-opus-5-effort-parameter-cost-routing)[How to Build a Long-Running AI Agent with the Claude Opus 5 API: An Overnight Build Log

A hands-on guide to building autonomous AI agents on the Claude Opus 5 API: the agent loop in Python, mid-conversation system messages, prompt caching costs, and what an overnight dependency-upgrade run actually cost.

Claude Opus 5 Anthropic Claude API

](https://foundrysoft.co/blog/claude-opus-5-overnight-long-horizon-agent)

#### Next Article

[

Claude Opus 5 Effort Parameter Guide: How to Reduce Claude API Costs Without Switching Models

](https://foundrysoft.co/blog/claude-opus-5-effort-parameter-cost-routing)

Available for new projects

## 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.

Start a Project [See our work](https://foundrysoft.co/work)

```json
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co",
  "logo": "https://foundrysoft.co/logo.svg",
  "description": "FoundrySoft builds production-grade software and AI systems for US companies, from an India-based team of senior engineers.",
  "sameAs": [
    "https://github.com/foundrysofthq",
    "https://www.linkedin.com/company/foundrysoft",
    "https://www.instagram.com/foundrysoft/"
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co"
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "Claude Opus 5 Batch API Tutorial: AI Contract Data Extraction at Scale, with Real Costs",
  "description": "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.",
  "url": "https://foundrysoft.co/blog/claude-opus-5-batch-api-contract-extraction",
  "mainEntityOfPage": "https://foundrysoft.co/blog/claude-opus-5-batch-api-contract-extraction",
  "image": [
    "https://foundrysoft.co/api/og?type=article&title=Claude+Opus+5+Batch+API+Tutorial%3A+AI+Contract+Data+Extraction+at+Scale%2C+with+Real+Costs&cat=AI+Engineering&rt=10+min+read&au=Varun+Raj+Manoharan&dt=2026-07-25"
  ],
  "datePublished": "2026-07-25",
  "dateModified": "2026-07-25",
  "keywords": "Claude Opus 5, Anthropic, Batch API, Structured Outputs, Document Extraction, Python",
  "author": {
    "@type": "Person",
    "name": "Varun Raj Manoharan"
  },
  "publisher": {
    "@type": "Organization",
    "name": "FoundrySoft",
    "logo": {
      "@type": "ImageObject",
      "url": "https://foundrysoft.co/logo.svg"
    }
  }
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://foundrysoft.co/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://foundrysoft.co/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Claude Opus 5 Batch API Tutorial: AI Contract Data Extraction at Scale, with Real Costs",
      "item": "https://foundrysoft.co/blog/claude-opus-5-batch-api-contract-extraction"
    }
  ]
}
```
