Skip to main content
This page walks through a complete batch from start to finish in both curl and the Python openai SDK. By the end you’ll have submitted 3 chat completions through the Batch API and read the results.

Prerequisites

Both headers are required on every request. Missing either returns 401.
Keep your API key out of source controlStore it in environment variables, secret managers, or your CI’s secret store, never commit it.

Base URLs

The Batch and Files endpoints live under these hostnames:
  • POST /v1/files, GET /v1/files, GET /v1/files/{id}, GET /v1/files/{id}/content, DELETE /v1/files/{id}
  • POST /v1/batches, GET /v1/batches, GET /v1/batches/{batch_id}

1. Build the input JSONL

Every batch is driven by a JSONL file where each line is one inference request:
Full schema and validation rules: JSONL format.

2. Upload the file

Send the JSONL to POST /v1/files with purpose=batch. The response contains the file_id you’ll reference when creating the batch.
Response:

3. Create the batch

Submit the batch with the file ID, the target endpoint, and a 24-hour completion window. The response returns immediately with status: "in_progress", actual processing is asynchronous.
Response:
Validation runs at create timeThe server streams the entire input JSONL and validates every line before responding. If anything is wrong, duplicate custom_id, line over 1 MB, stream: true, mismatched url, you’ll get a 400 with the offending line. Once the response returns, the batch is durably committed.

4. Poll until complete

Poll GET /v1/batches/{batch_id} until status is completed, expired, or failed. A 30-second interval is a reasonable default.
When status is completed, the response contains output_file_id (and, if any line failed, error_file_id).

5. Download the results

Stream the output and error files via GET /v1/files/{file_id}/content.
Output line shape (one per successful line, order not preserved, match by custom_id):
Error line shape (one per failed line):
Full schemas: JSONL format.

Scale it up

The same five steps handle a real workload. This script sends 1,000 prompts and collects the answers into a CSV, generating the JSONL from your own data, polling once a minute, and matching results back by custom_id:
For larger jobs, also read error_file_id and resubmit only the failed lines, see Errors reference for the recovery pattern.

Next steps

JSONL format →

Exact line schema for input, output, and error files.

Supported endpoints →

Body and response shape for /v1/chat/completions.

Objects & lifecycle →

Status lifecycle, the full Batch object schema, and every endpoint.

Errors reference →

Recover from failed lines without re-running the whole batch.