Add Requests in JSON
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.*; the xAI Batch API does not use the OpenAI format, 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.
Adding via the API
Once the batch is created, you add requests to it with POST /v1/batches/{batch_id}/requests. Each call carries a list of requests, and you can call the endpoint as many times as needed as long as the batch isn’t canceled. This approach works for batches built incrementally.
Request Structure
The call body contains a batch_requests array. Each element pairs an identifier (batch_request_id) with the request itself, stored under the key for its type—responses for the Responses API:
{
"batch_requests": [
{
"batch_request_id": "avis-001",
"batch_request": {
"responses": {
"model": "grok-4.3",
"input": [
{"role": "system", "content": "Classify the sentiment: positive, negative, or neutral."},
{"role": "user", "content": "The product exceeded my expectations!"}
]
}
}
}
]
}
batch_request_id: Your identifier, unique within the batch. This is the key matching the request to its result; if missing, xAI generates a UUIDbatch_request: The request, under the key for its type; the API reference also documentschat_get_completionfor the Chat Completions format
For images and videos, use the SDK (lesson 9) or a JSONL file (next lesson).
cURL Request
curl -X POST "https://api.x.ai/v1/batches/$BATCH_ID/requests" \
-H "Authorization: Bearer $XAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"batch_requests": [
{
"batch_request_id": "article-42",
"batch_request": {
"responses": {
"model": "grok-4.3",
"input": [
{"role": "user", "content": "Classify this text: positive, neutral, or negative."}
]
}
}
}
]
}'
Adding with the Python SDK
With the SDK, each request is built like a standard conversation, assigned a batch_request_id; you then add them in chunks:
from xai_sdk import Client
from xai_sdk.chat import system, user
client = Client()
documents = [
{"id": "doc-1", "text": "First document to analyze..."},
{"id": "doc-2", "text": "Second document to analyze..."},
{"id": "doc-3", "text": "Third document to analyze..."},
]
batch_id = "batch_1934e8b5-f3dc-45f1-8329-9841b0aee9d8"
requests = []
for doc in documents:
chat = client.chat.create(model="grok-4.3", batch_request_id=doc["id"])
chat.append(system("Summarize the document in two sentences."))
chat.append(user(doc["text"]))
requests.append(chat)
# Add in chunks of 100: one API call per chunk
for i in range(0, len(requests), 100):
client.batch.add(batch_id=batch_id, batch_requests=requests[i:i + 100])
The documentation doesn’t set a maximum number of requests per call; moderate chunk sizes simply limit what needs to be resent in case of a network incident.
Rate Limits on Adding
A team can make up to 1,000 add calls every 30 seconds, in a sliding window shared across all its batches. The limit applies to calls, not requests: with chunks of 100 requests, this already allows more than 3,000 requests per second. Two other bounds matter more:
- 25 MB maximum per individual request, which mainly concerns images encoded in base64
- Beyond 100,000 requests in a batch, xAI may slow down processing to preserve service stability
When to Use API Adding
API adding works whenever flexibility matters more than upfront preparation. It becomes the natural choice when the batch is built incrementally: requests arriving from a queue are added as they come in, whereas a JSONL file would require knowing everything in advance—and would close the batch. It’s also the path for prototyping, to test the full workflow with five requests before scaling up, and for heterogeneous batches.
Request Validation
Check the status code of each add call: an error at this stage means the chunk wasn’t saved, and you need to resend it. A request can also fail later, during processing; it then appears in the results with its error message. A model that doesn’t accept the batch is rejected with the message not supported for batch processing: check eligibility on the model page before launching a large batch.
Key Takeaways
- Adding goes through
POST /v1/batches/{id}/requests, with abatch_requestslist - Each request carries a unique
batch_request_idand its content under the key for its type (responses,chat_get_completion) - The SDK builds requests with
client.chat.create(..., batch_request_id=...)and adds them withclient.batch.add - The limit is 1,000 add calls per 30 seconds for the team, each call can carry many requests
- Unlike the JSONL file, API adding leaves the batch open to new additions