The same job API
Submit, poll, wait, cancel, resume, and collect results the same way for every provider.
Batch APIs for Python
Use OpenAI, Anthropic, Gemini, Groq, Mistral, Together AI, and xAI through the same async Python API, or from your terminal with the batchwork CLI. Built for people, scripts, and coding agents alike.
add batchwork-aiimport asyncio
from batchwork import BatchRequest, Batchwork
async def main() -> None:
requests = [
BatchRequest(custom_id="doc-1", prompt="Summarize the first document"),
BatchRequest(custom_id="doc-2", prompt="Summarize the second document"),
]
async with Batchwork() as client:
job = await client.batch(
model="openai/gpt-5.6-sol",
requests=requests,
)
await job.wait(timeout=3600)
async for result in job.results():
print(result.custom_id, result.status, result.text)
asyncio.run(main())Providers set batch pricing and model eligibility. Check current pricing before submitting.
What Batchwork handles
Submit requests and read results the same way across OpenAI, Anthropic, Gemini, and the rest. Batchwork handles each provider's files, endpoints, and output formats.
Submit, poll, wait, cancel, resume, and collect results the same way for every provider.
Requests still go to each provider's own batch API and use its batch pricing.
Handle unordered successes, errors, usage, embeddings, and images without provider-specific parsing.
Switch providers
The same requests, job lifecycle, and result handling work across provider batch APIs.
job = await client.batch( model="openai/gpt-5.6-sol", requests=requests,) await job.wait() async for result in job.results(): print(result.custom_id, result.text)job = await client.batch( model="anthropic/claude-sonnet-4-6", requests=requests,) await job.wait() async for result in job.results(): print(result.custom_id, result.text)Submit
Choose a provider and model, pass your requests, and get a BatchJob back as soon as the provider accepts the batch.
Read the guidefrom batchwork import BatchRequest, Batchwork
requests = [
BatchRequest(
custom_id=document.id,
prompt=f"Summarize:\n{document.text}",
max_output_tokens=400,
)
for document in documents
]
async with Batchwork() as client:
job = await client.batch(
model="anthropic/claude-sonnet-4-5",
requests=requests,
)
print(job.id, job.provider, job.status)Results
Provider output may be unordered and can contain both successes and failures. Batchwork gives every item the same status and result shape.
Read the guideawait job.wait(timeout=3600)
async for result in job.results():
match result.status:
case "succeeded":
await save_summary(
result.custom_id,
result.text,
result.usage,
)
case "errored":
await queue_retry(
result.custom_id,
result.error,
)
case "expired" | "canceled":
await mark_unfinished(result.custom_id)Terminal and agents
The batchwork CLI ships in the same package. You get readable summaries in the terminal; your scripts and coding agents get schema-versioned JSON, stable exit codes, and a local registry for resuming jobs. An Agent Skill teaches agents to drive it safely.
Read the guideuv tool install batchwork-ai
# Submit a file of prompts and check on it later
batchwork submit text prompts.txt --model openai/gpt-5
batchwork wait BW_RECORD_ID --timeout 2h
batchwork results BW_RECORD_ID
# Machine mode for scripts and coding agents
batchwork --jsonl --quiet run text requests.jsonl \
--model openai/gpt-5Production
Store tracked jobs, run the poller from a worker or cron, and send a signed webhook when a batch finishes. OpenAI's native webhooks use the same completion path.
Read the guidefrom batchwork import (
BatchPoller,
ProviderCredentials,
TrackTarget,
create_memory_store,
)
poller = BatchPoller(
create_memory_store(),
credentials=ProviderCredentials(api_key="..."),
)
target = TrackTarget(
id=job.id,
provider=job.provider,
status=job.status,
)
await poller.track(
target,
webhook_url="https://app.example/webhooks/batch",
secret=webhook_secret,
)
# Run from a worker or scheduled task.
result = await poller.tick()Provider support
Input media and generated output are listed separately. A provider can accept images in a text request without supporting image generation.
When you need more
Start with a script. Add persistence, media handling, scheduled polling, or signed delivery when the workload moves into production.
Browse the public APIUse images, PDFs, text files, audio, and provider file references where the selected provider supports them.
Run text batches on all seven providers, embeddings on three, and image generation on OpenAI, Google, and xAI.
Track jobs in memory during development or use Redis-compatible storage in production.
Sign completion events, reject stale deliveries, and deduplicate retries by event ID.
Pass provider-specific settings without changing the shared request and result models.
Batchwork talks to provider APIs directly with HTTPX.
Get started
Add one provider credential, choose a model, and use the same job API for every supported provider.