Batch Inference API/ workloads

Free text in, your schema out

Contracts, emails, job posts, product descriptions: most business data is prose with a database schema trapped inside. A batch extraction job turns fifty thousand documents into fifty thousand rows.

  • Schema in the prompt
  • JSON out per record
  • Chain with OCR jobs
  • 50% off realtime

Built for this shape of work.

Independent records, no user waiting, and a real budget: the profile the 50% batch discount is priced for.

Extraction is ETL, and ETL is batch

Structured extraction almost always feeds a table, an index, or a training set. The consumers are pipelines with nightly cadences, not users watching a spinner.

The schema is the prompt

Field names, types, allowed values, and null rules go in the system message once and govern every record in the file. Schema changes are file diffs, not code deploys.

Chains cleanly from OCR

Scanned documents run OCR as job one and extraction as job two, both JSONL, both on the same API key. custom_id carries the document key through the whole chain.

One JSONL file, one job.

Each line is a complete OpenAI-compatible request with a custom_id that is echoed on the matching output row. Up to 50,000 records and 200MB per job.

batch.jsonl · one request per linejsonl
{"custom_id":"lease-0071","method":"POST","url":"/v1/chat/completions","body":{"model":"openrelay/gpt-oss-120b","messages":[{"role":"system","content":"Extract from the lease as JSON: {\"tenant\", \"landlord\", \"address\", \"term_months\": int, \"monthly_rent_usd\": number, \"renewal_option\": bool, \"notice_days\": int|null}. Use null when absent. No prose."},{"role":"user","content":"This Lease Agreement is entered into by..."}]}}
{"custom_id":"job-ad-5518","method":"POST","url":"/v1/chat/completions","body":{"model":"openrelay/gpt-oss-20b","messages":[{"role":"system","content":"Extract as JSON: {\"title\", \"company\", \"location\", \"remote\": bool, \"salary_min\": int|null, \"salary_max\": int|null, \"skills\": []}."},{"role":"user","content":"Senior Platform Engineer - Acme (Denver or remote, $185k-$215k)..."}]}}
batch.py · OpenAI SDK, OpenRelay base URLpython
from openai import OpenAI

client = OpenAI(
    base_url="https://inference.openrelay.inc/v1",
    api_key="vl_••••••••",          # same SDK, new base URL
)

# extract lease terms from 50,000 contracts into rows
f = client.files.create(file=open("batch.jsonl", "rb"), purpose="batch")

batch = client.batches.create(
    input_file_id=f.id,
    endpoint="/v1/chat/completions",
    completion_window="24h",        # billed at 50% of realtime
)

# poll: validating → in_progress → completed
batch = client.batches.retrieve(batch.id)
print(batch.status, batch.request_counts)

# JSONL of {custom_id, response}; failures land in error_file_id
results = client.files.content(batch.output_file_id)

The right models for this job.

Batch rates are 50% off the realtime per-token catalog rates, per 1M tokens.

See the full catalog
Most popular

GPT-OSS 120B

OpenAI · 128K context

openrelay/gpt-oss-120b

$0.075 / $0.30

batch input / output per 1M

The extraction default: structured output support and enough headroom for gnarly source text and strict schemas.

Best value

GPT-OSS 20B

OpenAI · 128K context

openrelay/gpt-oss-20b

$0.025 / $0.10

batch input / output per 1M

Simple schemas over short text (contact info, order fields) at one-third the batch price.

OCR

DeepSeek-OCR 2

DeepSeek · 8K context

openrelay/deepseek-ocr-2

$0.019 / $0.019

batch input / output per 1M

Upstream stage for scans and PDFs: transcribe or extract directly from page images.

What separates a good run from a re-run.

Prompt and file patterns learned from real jobs, so the first submission is the one that counts.

01

Type every field and define null

term_months: int and 'use null when the document does not state it' prevent the two classic failures: numbers as prose ('twelve months') and hallucinated values for missing fields.

02

Forbid prose explicitly

End the system prompt with 'Reply with the JSON object only.' A single markdown fence or apology in 2% of rows is the difference between json.loads and a cleanup regex.

03

Validate the output file mechanically

Parse every row against your schema (pydantic or JSON Schema) and re-submit rejects as a small follow-up batch. Two-pass extraction routinely lands above 99% clean.

04

Include one worked example for messy sources

For OCR'd or inconsistent text, a single input-to-JSON example in the prompt buys more accuracy than any amount of instruction prose.

Common questions.

How do I get reliable structured output from an LLM?

Pin the schema in the system prompt with explicit types and null semantics, forbid prose, use a model with structured output support (the GPT-OSS family here), and validate mechanically after the run. In batch, add a second small job that retries the rows that failed validation; the combination is well above 99% parseable in practice.

Can this replace a data extraction API or template-based parser?

For variable-layout sources (contracts, emails, listings, resumes) prompt-defined extraction breaks far less often than templates when layouts shift, and changing it is a prompt edit instead of a template release. Fixed-layout forms at extreme volume can still favor a template engine; many teams run templates for the fixed 20% and LLM extraction for the long tail.

What does extraction cost at scale?

A 2,000-token contract with a 150-token JSON result on GPT-OSS 120B at batch rates costs about $0.0002 per document, so 50,000 contracts run around $10. Short-text extraction on GPT-OSS 20B is several times cheaper still.

How do I extract from PDFs and scans?

Chain two batch jobs: DeepSeek-OCR 2 turns page images into text (or extracts fields directly from the image), then the extraction pass applies your schema. Keep the document key in custom_id and the join is free.

Ship the first job today.

Grab an API key, upload a JSONL file, and run open models at half the realtime cost. No contract, no minimums. Deposit $5 to get $10.