101 101
102With your batch created, you can now add requests to it. Each request will be processed asynchronously.102With your batch created, you can now add requests to it. Each request will be processed asynchronously.
103 103
104104**With the xAI SDK, adding batch requests is simple:** use `chat.create()` for text, `image.prepare()` for images, `video.prepare()` for videos, or `video.prepare_extension()` for video extensions, then pass them as a list. You can also upload a [JSONL file](#jsonl-file-upload) if you prefer.With the xAI SDK, build each request with the method for its type, then pass them as a list:
105 105
106106**Important:** Assign a unique `batch_request_id` to each request. This ID lets you match results back to their original requests, which becomes important when you're processing hundreds or thousands of items. If you don't provide an ID, we generate a UUID for you. Using your own IDs is useful for idempotency (ensuring a request is only processed once) and for linking batch requests to records in your own system.| Request type | SDK method |
107|---|---|
108| Text | `chat.create()` |
109| Image | `image.prepare()` |
110| Video | `video.prepare()` |
111| Video extension | `video.prepare_extension()` |
112
113You can also upload a [JSONL file](#jsonl-file-upload) if you prefer.
114
115**Important:** Assign a unique `batch_request_id` to each request.
116
117* The ID lets you match results back to their original requests. This matters when you process hundreds or thousands of items.
118* If you don't provide an ID, we generate a UUID for you.
119* Your own IDs are useful for idempotency (ensuring a request is only processed once).
120* They also let you link batch requests to records in your own system.
107 121
108```bash122```bash
109curl -X POST https://api.x.ai/v1/batches/{batch_id}/requests \\123curl -X POST https://api.x.ai/v1/batches/{batch_id}/requests \\
419 433
420You can retrieve results at any time, even before the entire batch completes. Results are available as soon as individual requests finish processing, so you can start consuming completed results while other requests are still in progress.434You can retrieve results at any time, even before the entire batch completes. Results are available as soon as individual requests finish processing, so you can start consuming completed results while other requests are still in progress.
421 435
422436Each result is linked to its original request via the `batch_request_id` you assigned earlier. For chat completions, use `result.response` which has the familiar fields: `.content`, `.usage`, `.finish_reason`, and more. For image requests, use `result.image_response` which provides `.url`, `.base64`, `.usage`, and `.model`. For video requests, use `result.video_response` which provides `.url`, `.duration`, `.usage`, and `.model`. These are the same response types returned by the regular `client.image.sample()` and `client.video.generate()` methods.Each result is linked to its original request via the `batch_request_id` you assigned earlier. Read the response from the accessor for its request type:
437
438| Request type | Accessor | Fields |
439|---|---|---|
440| Chat completion | `result.response` | `.content`, `.usage`, `.finish_reason`, and more |
441| Image | `result.image_response` | `.url`, `.base64`, `.usage`, `.model` |
442| Video | `result.video_response` | `.url`, `.duration`, `.usage`, `.model` |
443
444These are the same response types returned by the regular `client.image.sample()` and `client.video.generate()` methods.
423 445
424The SDK provides convenient `.succeeded` and `.failed` properties to separate successful responses from errors.446The SDK provides convenient `.succeeded` and `.failed` properties to separate successful responses from errors.
425 447
864 886
865As an alternative to adding requests via the SDK, you can create batches by uploading a JSONL file. This is useful when generating requests from scripts, pipelines, or external tools.887As an alternative to adding requests via the SDK, you can create batches by uploading a JSONL file. This is useful when generating requests from scripts, pipelines, or external tools.
866 888
867889Each line in the file is a JSON object with four fields: `custom_id` (unique identifier, maps to `batch_request_id`), `method` (always `"POST"`), `url` (API endpoint path), and `body` (the JSON request payload matching the [REST API reference](/developers/rest-api-reference) for that endpoint).Each line in the file is a JSON object with four fields:
890
891| Field | Description |
892|---|---|
893| `custom_id` | Unique identifier. Maps to `batch_request_id`. |
894| `method` | Always `"POST"`. |
895| `url` | API endpoint path. |
896| `body` | The JSON request payload, matching the [REST API reference](/developers/rest-api-reference) for that endpoint. |
868 897
869```json898```json
870{"custom_id": "chat-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "grok-4.3", "messages": [{"role": "user", "content": "Classify this as positive, negative, or neutral: The product exceeded my expectations!"}]}}899{"custom_id": "chat-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "grok-4.3", "messages": [{"role": "user", "content": "Classify this as positive, negative, or neutral: The product exceeded my expectations!"}]}}
891| `/v1/videos/edits` | [Video editing](/developers/model-capabilities/video/editing) |920| `/v1/videos/edits` | [Video editing](/developers/model-capabilities/video/editing) |
892| `/v1/videos/extensions` | [Video extension](/developers/model-capabilities/video/extension) |921| `/v1/videos/extensions` | [Video extension](/developers/model-capabilities/video/extension) |
893 922
894923Only batch-enabled models are accepted. Refer to the relevant [model pages](/developers/models) for the most up-to-date information; models that are not batch-enabled are rejected with "not supported for batch processing".Only batch-enabled models are accepted. Refer to the relevant [model pages](/developers/models) for the most up-to-date information; models that are not batch-enabled are rejected with `not supported for batch processing`.
895 924
896Upload the file via the [Files API](/developers/files), then create a batch referencing it:925Upload the file via the [Files API](/developers/files), then create a batch referencing it:
897 926
959 988
960The file is processed asynchronously in the background. If any line is invalid, the batch is cancelled with an error message. Monitor progress and retrieve results the same way as inline batches.989The file is processed asynchronously in the background. If any line is invalid, the batch is cancelled with an error message. Monitor progress and retrieve results the same way as inline batches.
961 990
962991File-based batches are sealed after creation — you cannot add more requests via `AddBatchRequests`. Maximum file size is **200 MB** with up to **50,000** requests. Each `custom_id` must be unique within the file.File-based batch limits:
992
993* The batch is sealed after creation. You cannot add more requests via `AddBatchRequests`.
994* Maximum file size is **200 MB**.
995* A file can hold up to **50,000** requests.
996* Each `custom_id` must be unique within the file.
963 997
964## Limitations998## Limitations
965 999