The Message Batches API processes independent Messages API requests asynchronously. Submitting a batch is easy. The design work is in what happens after the results come back, especially when some succeed and some do not.
Use a batch for independent work that can wait: evaluations, document classification, data analysis. Use an interactive request when a person or service needs the answer before it can continue. A batch can take up to 24 hours, so check the current limits in the documentation before building anything time sensitive.
Results can come back in a different order from the requests you sent. Give each request a custom_id taken from your own record, such as ticket_8831, and store the mapping before you submit. When results arrive, write each outcome next to its source record, with the prompt version, submission time and status.
| State | What it means | Next step |
|---|---|---|
succeeded |
The model returned a message | Validate the message and its business meaning before any action |
errored |
The request failed | Read the error. Fix invalid input; retry only errors that are eligible |
canceled |
The batch was canceled | Check each request. A canceled batch can still contain completed results |
expired |
The request was not sent before the batch expired | Decide which requests are still useful, then resubmit those |
succeeded is the state people misread. It means a message exists, not that the message is right for the decision.
When a few records fail, the tempting fix is to resubmit everything. That can create duplicate tasks or overwrite decisions a person already made. Instead:
For refunds, notices, account changes or payments, separate the model's output from execution:
approved_for_action only after validation and any required review.
custom_id joins a result to its input. It does not make execution idempotent. That job belongs to the service that performs the action.
custom_id values.