Batch results merger
Join an Anthropic Message Batches results file back to its rows by custom_id, with failures, gaps and duplicates flagged and the actual cost.
What it does
Results from a batch come back in any order. Give the merger the results .jsonl file and what the batch was built from:
- the rows, as CSV, a JSON array or JSON Lines, with the same
custom_idrule the builder used; - or the requests file the builder wrote.
It joins each result to its row by custom_id and shows:
- how many requests succeeded, errored, were canceled or expired;
- every row with no result, every result that matches no row, and every
custom_idthat repeats on either side; - the error type of each failed request. An
invalid_request_errormust be fixed before the request is sent again; other errors can be sent again as they are; - what the batch actually cost, from each result's own usage;
- a table of the first rows, then CSV or JSON Lines with every row: its own columns, then the answer text, the tool calls, the stop reason, the tokens, the error and the cost.
Both files stay in your browser and are read in a background thread. A shared link holds the settings, never a file.
How it prices
Only succeeded requests are billed: Anthropic's page says errored, canceled and expired requests are not. Each succeeded result is priced from its own usage, with the same arithmetic Salyro uses (calculateCost), less the batch discount Anthropic states.
A result whose model is not in Salyro's catalogue is not priced; the model in Anthropic's own example is one. A result with cache writes is not priced either, because the price list has no rate for them. The merger names both cases instead of guessing.
What it does not know
- OpenAI's and Gemini's results files. Their pages could not be read when this tool was built, so their format is unknown and not guessed.
- Which rule built the ids, if you do not say. If no result matches any row, the rule is most likely different; the merger says so.
FAQ
Why do some rows have no result?
The results file does not contain them. Either the batch has not finished, or it expired before they ran, or they were built with a different custom_id rule.
What happens with a custom_id that repeats?
Only the first row, and the first result, with that id are joined. A later row with the same id is marked repeats an earlier row, not "no result". Repeated results are listed, so nothing is lost silently.
Is the CSV safe to open in a spreadsheet?
A cell that a spreadsheet would run as a formula starts with =, +, - or @; model output can start that way. Such a cell is written with a leading ', which is OWASP's advice for CSV injection. A plain number keeps its sign, and the JSON Lines export is written unchanged. A custom_id that starts with - gets the ' in the CSV too, so to feed an export back into the merger, use the JSON Lines file.
How large can the files be?
The source can be up to 260 MB, just over the 256 MB one batch may be; it is read whole. The results file can be up to 512 MB, because it streams and results are usually larger than their requests.
Sources
The result types and which of them are billed, and that results come back in any order, quote Anthropic's batch-processing page and its results API reference, on platform.claude.com. Prices and the batch discount come from Salyro's catalogue and Reference Data.
Where the numbers come from
- Model and pricing data is a snapshot of the catalogue Salyro itself uses, taken when this site was built.
- Facts about models and providers that are not in that catalogue carry their own source and the date they were checked, and are shown as unknown where no reliable source exists.
