Tracking, Status, and Cancellation
On this page
Updated November 2, 2026 based on xAI documentation: the batch discount is 20% on eligible text models (not 50%), examples follow the REST API and the official
xai-sdk(client.batch.*; xAI’s Batch API does not match OpenAI’s format, so the OpenAI SDK does not apply), and the Responses API takes precedence over Chat Completions, a legacy endpoint at xAI. Sources: Batch API · REST Reference · Batch Pricing.
Manage the batch lifecycle
Once you submit your requests, you need to track processing progress, read statuses, and know when and how to cancel a batch. This lesson covers all available management operations.
Two levels of status
xAI tracks progress at two levels. The batch itself has no global status like “completed” or “failed”: it carries counters in its state object. Each request, however, has its own status:
| Request status | Meaning | Action |
|---|---|---|
pending | Queued | Wait |
succeeded | Processed, result available | Retrieve result |
failed | Error during processing | Read message, retry if useful |
cancelled | Canceled, for example with its batch | Resubmit if necessary |
The batch is fully processed when its num_pending counter drops to zero. It can also be canceled or expire: after expire_time, its results are no longer accessible.
Check counters
The GET /v1/batches/{batch_id} call returns the batch and its counters:
curl "https://api.x.ai/v1/batches/$BATCH_ID" \
-H "Authorization: Bearer $XAI_API_KEY"
The response includes:
{
"batch_id": "batch_1934e8b5-f3dc-45f1-8329-9841b0aee9d8",
"name": "analyse_avis_clients",
"state": {
"num_requests": 500,
"num_pending": 155,
"num_success": 342,
"num_error": 3,
"num_cancelled": 0
}
}
These counters track progress in real time, without waiting for processing to finish. With the SDK, read them in client.batch.get(batch_id=...).state.
List your batches
To find a batch or check history:
curl "https://api.x.ai/v1/batches?limit=20" \
-H "Authorization: Bearer $XAI_API_KEY"
The list is paginated by limit and pagination_token. Batches remain there until expiration. With the SDK, client.batch.list(limit=20) returns a batches list where each element carries its name, batch_id, and state. The xAI console offers the same view, in visual form.
Retrieve results
You can retrieve results at any time, even during processing:
curl "https://api.x.ai/v1/batches/$BATCH_ID/results?limit=100" \
-H "Authorization: Bearer $XAI_API_KEY"
Each result carries the batch_request_id of its request. Failed requests appear there with their message; with the SDK, the succeeded and failed properties of each page separate them.
Check request metadata
To track the status of each request:
curl "https://api.x.ai/v1/batches/$BATCH_ID/requests?limit=50" \
-H "Authorization: Bearer $XAI_API_KEY"
Each entry gives the request identifier, its endpoint, model, status, and creation and end dates. This is the diagnostic tool when a counter stalls, or to verify what was successfully added.
Cancel a batch
If you need to stop processing in progress:
curl -X POST "https://api.x.ai/v1/batches/$BATCH_ID:cancel" \
-H "Authorization: Bearer $XAI_API_KEY"
Cancellation is final: pending requests won’t be processed, and you can no longer add requests to the batch. Requests already processed, however, remain available in the results. Cancel if:
- You detected an error in your requests after submission
- The batch is no longer needed (priority change)
- You want to resubmit a corrected batch
With the SDK: client.batch.cancel(batch_id=...), which returns the batch and its counters at the time of cancellation.
Polling strategy
In production, wait for completion with spaced polling and a maximum delay:
import time
def attendre_batch(client, batch_id, intervalle=300, delai_max=2 * 86400):
"""Wait until all requests in the batch are processed."""
debut = time.monotonic()
while time.monotonic() - debut < delai_max:
batch = client.batch.get(batch_id=batch_id)
etat = batch.state
if batch.cancel_by_xai_message:
raise RuntimeError(f"Canceled by xAI: {batch.cancel_by_xai_message}")
if etat.num_requests > 0 and etat.num_pending == 0:
return batch
print(f"{etat.num_success} succeeded, {etat.num_error} failed, "
f"{etat.num_pending} pending out of {etat.num_requests}")
time.sleep(intervalle)
raise TimeoutError(f"Batch not finished after {delai_max} s")
An interval of a few minutes suits large batches; xAI’s documentation polls every few seconds in its examples, which cover small batches. And since results are available as they come in, nothing prevents retrieving them during the wait.
Key takeaways
- Read the batch by its counters (
num_pending,num_success,num_error…); each request has its status:pending,succeeded,failed,cancelled GET /v1/batches/{id}gives progress,/resultsthe results,/requeststhe request detail- Cancellation (
POST /v1/batches/{id}:cancel) is irreversible, but keeps results already produced - Lists and results paginate with
limitandpagination_token - Poll at intervals of a few minutes, with a maximum delay, and retrieve before
expire_time