The Message Batches API processes many requests asynchronously at half the price. Use it when nobody waits for the answer.
Create a batch
Each request has a custom_id and the params of a normal Messages request.
requests =
for {id, events} <- days do
%{
custom_id: id,
params: %{model: "claude-opus-5-5", max_tokens: 1024, messages: [%{role: "user", content: events}]}
}
end
{:ok, %{"id" => batch_id}} = Jibu.Batches.create(client, %{requests: requests})Wait for the result
Poll Jibu.Batches.get/2 until processing_status is "ended".
{:ok, batch} = Jibu.Batches.get(client, batch_id)
batch["processing_status"]
batch["request_counts"]Read the results
{:ok, results} = Jibu.Batches.results(client, batch_id)
for %{"custom_id" => id, "result" => result} <- results do
case result do
%{"type" => "succeeded", "message" => message} -> {id, Jibu.Response.new(message)}
%{"type" => other} -> {id, other}
end
endResults arrive in any order. Match them by custom_id, never by position.
A result type is "succeeded", "errored", "canceled" or "expired".
results/2 holds the whole result file in memory while you consume it.
Cancel and delete
Jibu.Batches.cancel(client, batch_id)
Jibu.Batches.delete(client, batch_id)Cancelling keeps the results of requests already processed.