Skip to content
Batchwork
Esc
navigateopen⌘Jpreview
On this page

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

  1. Build — each request becomes a { custom_id, method, url, body } JSONL line.
  2. Upload — the JSONL is uploaded to /v1/files (xAI’s upload omits the purpose field).
  3. CreatePOST /v1/batches references the file via input_file_id.
  4. PollGET /v1/batches/{id} returns counts (num_pending, num_requests, num_cancelled, …), from which Batchwork derives the normalized status.
  5. Read — the proprietary, paginated GET /v1/batches/{id}/results is walked 100 at a time via pagination_token. Chat completions live under batch_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

Was this page helpful?