OpenFill is in development. Inference is off, but is tested end to end, and will switch on at launch. All data currently on the site is for live testing: it will be erased at launch.

Skip to content
openfill

Files and batches

The OpenAI shapes for a file and a batch, with the fields OpenFill adds. A file exists to be a batch input or a batch output; there is no other purpose.

Upload a file

POST /v1/files
curl https://api.openfill.ai/v1/files -H "Authorization: Bearer $OPENFILL_API_KEY" \  -F purpose=batch -F [email protected]

Multipart, one file, purpose of batch. The content is checked when a batch starts rather than at upload. A file over 50 MB is refused with 413.

json
{"id": "file-...", "object": "file", "bytes": 1234, "created_at": 1756700000, "expires_at": 1756786400, "filename": "requests.jsonl", "purpose": "batch", "status": "processed"}

expires_at is when the file is deleted: at least a day after upload, or your storage period. Both timestamps are epoch seconds.

Get a file and its content

GET /v1/files/{id}
curl https://api.openfill.ai/v1/files/<file_id> -H "Authorization: Bearer $OPENFILL_API_KEY"
GET /v1/files/{id}/content
curl https://api.openfill.ai/v1/files/<file_id>/content -H "Authorization: Bearer $OPENFILL_API_KEY" -o output.jsonl

The content is served as application/jsonl with a filename in Content-Disposition. A file past its expiry answers 410 result_unavailable. Each download counts against the hourly allowance on limits.

Create a batch

POST /v1/batches
curl https://api.openfill.ai/v1/batches -H "Authorization: Bearer $OPENFILL_API_KEY" -H "Content-Type: application/json" \  -d '{"input_file_id": "file-...", "endpoint": "/v1/chat/completions", "completion_window": "24h", "max_price": 0.02}'
FieldTypeDefaultMeaning
input_file_idstringrequiredA file uploaded with purpose batch.
endpointstringrequired/v1/chat/completions or /v1/completions. Every line's url must match it.
completion_windowstring24hOnly 24h is accepted, as OpenAI's shape has it.
max_pricenumberkey or accountThe max price every line inherits. A line's own body.max_price wins over it.
max_waitintegera dayThe deadline in seconds. Lines still queued at expires_at are expired unexecuted.
metadataobjectnoneUp to 16 pairs; keys up to 64 characters, values up to 512.

The batch is answered with status validating. With no max price on the batch, the key or the account it is 400 missing_bid; with too many batches already running it is 429 with Retry-After. Up to 10,000 lines per file.

The batch object

FieldMeaning
idbatch_ and 24 characters.
endpoint/v1/chat/completions or /v1/completions.
statusvalidating, in_progress, cancelling, completed, expired, cancelled or failed.
input_file_id, output_file_id, error_file_idThe files. Output and error are null until the batch finishes, and absent when empty.
errorsnull, or {object: list, data: [{code: batch_error, message}]} when validation failed.
completion_windowAlways 24h.
created_at, expires_at, completed_atEpoch seconds. expires_at is the real deadline.
request_counts{total, completed, failed}. failed folds in expired and cancelled lines.
metadataUp to 16 string pairs, as sent.
x_market{active, pending_result, expired, canceled, bid}. bid is the batch max_price, or null.
x_retention{output_days, output_expires_at, output_deleted} for the output file.

List, retrieve and cancel

GET /v1/batches
curl "https://api.openfill.ai/v1/batches?limit=20" -H "Authorization: Bearer $OPENFILL_API_KEY"
json
{"object": "list", "data": [ ...batches... ], "first_id": "batch_...", "last_id": "batch_...", "has_more": true}

Newest first. Pass last_id as ?after= for the next page. has_more is true whenever a page is full, so the page after the last one is empty with has_more false.

GET /v1/batches/{id}
curl https://api.openfill.ai/v1/batches/<batch_id> -H "Authorization: Bearer $OPENFILL_API_KEY"
POST /v1/batches/{id}/cancel
curl -X POST https://api.openfill.ai/v1/batches/<batch_id>/cancel -H "Authorization: Bearer $OPENFILL_API_KEY"

Cancel answers the batch with status cancelling; queued lines are cancelled and executing ones finish. A batch in any other state answers 409 batch_not_cancelable.

Line formats

input line
{"custom_id": "job-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "...", "messages": [{"role": "user", "content": "..."}], "max_price": 0.03}}
output line
{"id": "batch_req_...", "custom_id": "job-1", "response": {"status_code": 200, "request_id": "<order_id>", "body": { ...the completion... }}, "error": null}
error line
{"id": "batch_req_...", "custom_id": "job-2", "response": null, "error": {"code": "expired", "message": "..."}}

The error codes, the statuses, and what a line cannot carry are on the batch page.