Claude Message Batches: What to Do With Each Result State A developer outlined a pattern for handling Claude's Message Batches API results, stressing that each request needs a custom_id from the caller's own records and that the four result states — succeeded, errored, canceled and expired — each require different follow-up. The writeup warns that succeeded only means a message exists, not that it is correct, and that resubmitting a whole batch after partial failures risks duplicate tasks or overwriting human decisions, so execution should be separated from model output via an approved_for_action gate. 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.