Batch processing is the cheapest way to run one prompt over a lot of rows, at about half the interactive price, and the file it wants is unforgiving in one specific way: results come back in whatever order they finish. The custom id is the only thing tying a result to the row it came from, so a duplicate id means two results you cannot tell apart — silently, after the job has run. This expands your template over the rows, derives an id from a column or generates one, renames duplicates rather than letting them collide, and sizes the job so you know what you are submitting before you submit it.
Features
One request per row, from a template and a table
Custom id from a column of your choosing, or generated
Duplicate ids renamed rather than left to collide
Ids sanitised to the characters the field allows
Warns per row when a placeholder had no value
Job size: request count, estimated input tokens and file size
Emits both the request body and the same requests as JSONL
Splits an oversized job into files, and shows how to submit it
How to use the Batch Request Builder
Paste the prompt template and the rows
Pick the model and the per-request token limit
Choose which column becomes the custom id
Download the request body and submit it
Example
Input
"custom_id": "Acme-Ltd"
Output
Row 2 repeats the id “Acme-Ltd”; renamed to “Acme-Ltd-2”
Results arrive out of order, so the id is the only way back to the row.
Common errors & troubleshooting
I cannot match results back to rows. — Key on the custom id, never on position — results come back in completion order. Duplicates are renamed here for exactly this reason.
The submission is rejected. — The endpoint takes a JSON body with a requests array, not the JSONL file. Both are produced; submit the .json one.
A prompt contains a literal placeholder. — That row had no value for it. Every affected row is listed, with the placeholder named.
The job is too large. — Split it. Files of at most ten thousand requests are offered automatically when the count goes above that.
Frequently asked questions
Why is batch processing cheaper?
Because it is not interactive. The work is queued and run when there is capacity, which is a much easier thing to schedule — so it is priced at about half. The trade is latency, not quality.
What is the custom id for?
Matching results to inputs. Results arrive in completion order rather than submission order, so the id is the only reliable link back to the row a result came from.
What happens if two rows share an id?
In a real job, two results you cannot tell apart. Here the duplicate is renamed and flagged, which is a much better time to find out.
What is the JSONL output for, if the endpoint takes JSON?
Line-oriented tooling: splitting a large job, diffing two versions of one, or feeding a different runner. The JSON body is the one to submit.
How should I choose max_tokens?
High enough that no answer is truncated, since a truncated result has to be redone. The ceiling shown assumes every request uses its full allowance, which is a worst case rather than an estimate.
Related tools
Prompt Template Filler — Expand one prompt over a table of rows and see what is missing.