xAI
Run batches on xAI's Grok Batch API — an OpenAI-compatible file upload and batch creation with proprietary status, paginated results, and cancel shapes.
xAI’s Batch API uses an OpenAI-compatible Files API to upload the input and create the batch, but its status, results, and cancel shapes are proprietary — results come back from a paginated /results endpoint rather than a downloadable file. Batchwork bridges the two.
| Property | Value |
|---|---|
| Shape | JSONL file upload (OpenAI-compat) |
| Endpoint | /v1/chat/completions, /v1/images/generations, /v1/images/edits, /v1/videos/* |
| Results | Paginated /results JSON |
| Webhooks | Poll-only (managed by the server) |
| Env var | XAI_API_KEY |
| Package | @ai-sdk/xai |
| Base URL | https://api.x.ai/v1 |
Example
import { batch } from "batchwork";
import { xai } from "@ai-sdk/xai";
const job = await batch({
model: xai("grok-4"),
requests: [
{ customId: "fr", prompt: "Capital of France? One word." },
{ customId: "jp", prompt: "Capital of Japan? One word." },
],
});
How it works
- Build — each request becomes a
{ custom_id, method, url, body }JSONL line. - Upload — the JSONL is uploaded to
/v1/files(xAI’s upload omits thepurposefield). - Create —
POST /v1/batchesreferences the file viainput_file_id. - Poll —
GET /v1/batches/{id}returns counts (num_pending,num_requests,num_cancelled, …), from which Batchwork derives the normalized status. - Read — the proprietary, paginated
GET /v1/batches/{id}/resultsis walked 100 at a time viapagination_token. Chat completions live underbatch_result.response.chat_get_completion.
Cancellation uses POST /v1/batches/{id}:cancel.
Batchwork validates xAI batch ids before using them in API paths.
Images
xAI image models (e.g. grok-imagine-image-quality) batch through /v1/images/generations, uploaded and polled the same way as chat. Submit with batch.images():
import { batch } from "batchwork";
import { xai } from "@ai-sdk/xai";
const job = await batch.images({
model: xai.image("grok-imagine-image-quality"),
requests: [{ customId: "a", prompt: "A red bicycle against a brick wall." }],
});
Image results come back under the image_response op in the paginated /results response.
xAI also batches image edits through /v1/images/edits — source images are passed as hosted URL references ({ imageUrl }; data URIs work, file ids and masks don’t). Use batch.images.edit():
const job = await batch.images.edit({
model: xai.image("grok-imagine-image-quality"),
requests: [
{
customId: "a",
prompt: "Add a rainbow.",
images: [{ imageUrl: "https://example.com/photo.png" }],
},
],
});
Videos
xAI is the only provider whose batch API accepts video generation. Grok Imagine video models batch through /v1/videos/generations — plus /v1/videos/edits and /v1/videos/extensions for editing and extending, selected per request line via providerOptions. Submit with batch.videos():
import { batch } from "batchwork";
import { xai } from "@ai-sdk/xai";
const job = await batch.videos({
model: xai.video("grok-imagine-video"),
requests: [
{ customId: "a", prompt: "A red bicycle rolling downhill.", duration: 5 },
],
});
Video results come back under the video op in the paginated /results response, normalized to result.videos[].url — signed URLs with the same ~1h expiry as batch images. See Videos for edit/extend modes.
Notes
xAI has no native batch webhook, so it is poll-only. Use the server layer for unified completion events.
xAI exposes no embedding model, so batch.embeddings() throws UnsupportedProviderError.
Credentials
Set XAI_API_KEY, or pass apiKey / baseURL / headers to batch(). Install the peer dependency:
bun add @ai-sdk/xai