SpyBara
Go Premium

model-capabilities/images/generation.md 2026-10-07 23:59 UTC to 2026-10-08 23:58 UTC

This page contains 199 additions and 127 deletions.

2026
Thu 8 23:58

Model Capabilities

Image Generation

Generate images from text prompts with Grok Imagine models. The API supports batch generation of multiple images, and control over aspect ratio, resolution, and quality.

Quick Start

Generate an image with a single API call:

import { xai } from "@ai-sdk/xai";
import { generateImage } from "ai";

const { image } = await generateImage({
    model: xai.image("grok-imagine-image-2.0"),
    prompt: "A collage of London landmarks in a stenciled street‑art style",
});

console.log(image.base64);
from openai import OpenAI

client = OpenAI(
    base_url="https://api.x.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.images.generate(
    model="grok-imagine-image-2.0",
    prompt="A collage of London landmarks in a stenciled street‑art style",
)

print(response.data[0].url)
curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "A collage of London landmarks in a stenciled street‑art style"
  }'
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: 'https://api.x.ai/v1',
});

const response = await client.images.generate({
    model: "grok-imagine-image-2.0",
    prompt: "A collage of London landmarks in a stenciled street‑art style",
});

console.log(response.data[0].url);
import xai_sdk

client = xai_sdk.Client()

response = client.image.sample(
    prompt="A collage of London landmarks in a stenciled street‑art style",
    model="grok-imagine-image-2.0",
)

print(response.url)

Images are returned as URLs by default. URLs are temporary, so download or process promptly. You can also request base64 output for embedding images directly.

Configuration

Multiple Images

Generate multiple images in a single request with the n parameter (1–10). On the REST API and OpenAI-compatible SDKs, n is optional and defaults to 1. The xAI Python SDK uses sample() for a single image and sample_batch(n=...) for more than one — n is required on sample_batch().

import { xai } from "@ai-sdk/xai";
import { generateImage } from "ai";

const { images } = await generateImage({
    model: xai.image("grok-imagine-image-2.0"),
    prompt: "A futuristic city skyline at night",
    n: 4,
});

images.forEach((image, i) => {
    console.log(`Variation ${i + 1}: ${image.base64.slice(0, 50)}...`);
});

from openai import OpenAI

client = OpenAI(
    base_url="https://api.x.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.images.generate(
    model="grok-imagine-image-2.0",
    prompt="A futuristic city skyline at night",
    n=4,
)

for i, image in enumerate(response.data):
    print(f"Variation {i + 1}: {image.url}")
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: "https://api.x.ai/v1",
});

const response = await client.images.generate({
    model: "grok-imagine-image-2.0",
    prompt: "A futuristic city skyline at night",
    n: 4,
});

response.data.forEach((image, i) => {
    console.log(`Variation ${i + 1}: ${image.url}`);
});

curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "A futuristic city skyline at night",
    "n": 4
  }'
import xai_sdk

client = xai_sdk.Client()

responses = client.image.sample_batch(
    prompt="A futuristic city skyline at night",
    model="grok-imagine-image-2.0",
    n=4,
)

for i, image in enumerate(responses):
    print(f"Variation {i + 1}: {image.url}")

Aspect Ratio

Control image dimensions with the aspect_ratio parameter. When omitted, the default is auto, which lets the model pick the best ratio for the prompt.

Ratio Use case
1:1 Social media, thumbnails
16:9 / 9:16 Widescreen, mobile, stories
4:3 / 3:4 Presentations, portraits
3:2 / 2:3 Photography
2:1 / 1:2 Banners, headers
19.5:9 / 9:19.5 Modern smartphone displays (iPhone)
20:9 / 9:20 Modern smartphone displays (Android)
21:9 Cinematic widescreen
5:2 Wide banners
auto Model auto-selects the best ratio for the prompt
import { xai } from "@ai-sdk/xai";
import { generateImage } from "ai";

const { image } = await generateImage({
    model: xai.image("grok-imagine-image-2.0"),
    prompt: "Mountain landscape at sunrise",
    aspectRatio: "16:9",
});

console.log(image.base64);
from openai import OpenAI

client = OpenAI(
    base_url="https://api.x.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.images.generate(
    model="grok-imagine-image-2.0",
    prompt="Mountain landscape at sunrise",
    extra_body={"aspect_ratio": "16:9"},
)

print(response.data[0].url)
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: "https://api.x.ai/v1",
});

const response = await client.images.generate({
    model: "grok-imagine-image-2.0",
    prompt: "Mountain landscape at sunrise",

    aspect_ratio: "16:9",
});

console.log(response.data[0].url);
curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "Mountain landscape at sunrise",
    "aspect_ratio": "16:9"
  }'
import xai_sdk

client = xai_sdk.Client()

response = client.image.sample(
    prompt="Mountain landscape at sunrise",
    model="grok-imagine-image-2.0",
    aspect_ratio="16:9",
)

print(response.url)

Resolution

You can specify different resolutions of the output image with the resolution parameter. Currently supported image resolutions are:

  • 1k (default when omitted)
  • 2k
import { xai } from "@ai-sdk/xai";
import { generateImage } from "ai";

const { image } = await generateImage({
    model: xai.image("grok-imagine-image-2.0"),
    prompt: "An astronaut performing EVA in LEO.",
    providerOptions: {
        xai: { resolution: "2k" },
    },
});

console.log(image.base64);
from openai import OpenAI

client = OpenAI(
    base_url="https://api.x.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.images.generate(
    model="grok-imagine-image-2.0",
    prompt="An astronaut performing EVA in LEO.",
    extra_body={"resolution": "2k"},
)

print(response.data[0].url)
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: "https://api.x.ai/v1",
});

const response = await client.images.generate({
    model: "grok-imagine-image-2.0",
    prompt: "An astronaut performing EVA in LEO.",

    resolution: "2k",
});

console.log(response.data[0].url);
curl -X POST https://api.x.ai/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "An astronaut performing EVA in LEO.",
    "resolution": "2k"
}'
import xai_sdk

client = xai_sdk.Client()

response = client.image.sample(
    prompt="An astronaut performing EVA in LEO.",
    model="grok-imagine-image-2.0",
    resolution="2k"
)

print(response.url)

Quality

Control generation quality with the optional quality parameter. Allowed values are low, medium, and auto. When omitted, the default is auto, which lets the service choose the quality for each request. Auto currently uses low for image generation and medium for image editing. Images are billed at the quality they are served at (see Pricing). Pass low or medium to pin a specific quality. The parameter is only supported for grok-imagine-image-2.0.

curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "A watercolor painting of a lighthouse at dawn",
    "quality": "low"
  }'
import xai_sdk

client = xai_sdk.Client()

response = client.image.sample(
    prompt="A watercolor painting of a lighthouse at dawn",
    model="grok-imagine-image-2.0",
    quality="low",
)

print(response.url)

Base64 Output

Control the output format with the response_format parameter. When omitted, the default is url, which returns temporary hosted URLs. For embedding images directly without downloading, request base64:

import { xai } from "@ai-sdk/xai";
import { generateImage } from "ai";
import fs from "fs";

const { image } = await generateImage({
    model: xai.image("grok-imagine-image-2.0"),
    prompt: "A serene Japanese garden",
});

// Save to file (AI SDK returns base64 by default)
const imageBuffer = Buffer.from(image.base64, "base64");
fs.writeFileSync("garden.jpg", imageBuffer);
import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://api.x.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.images.generate(
    model="grok-imagine-image-2.0",
    prompt="A serene Japanese garden",
    response_format="b64_json",
)

# Save to file
image_bytes = base64.b64decode(response.data[0].b64_json)
with open("garden.jpg", "wb") as f:
    f.write(image_bytes)
import OpenAI from "openai";
import fs from "fs";

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: "https://api.x.ai/v1",
});

const response = await client.images.generate({
    model: "grok-imagine-image-2.0",
    prompt: "A serene Japanese garden",
    response_format: "b64_json",
});

// Save to file
const imageBuffer = Buffer.from(response.data[0].b64_json, "base64");
fs.writeFileSync("garden.jpg", imageBuffer);
curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "A serene Japanese garden",
    "response_format": "b64_json"
  }'
import xai_sdk

client = xai_sdk.Client()

response = client.image.sample(
    prompt="A serene Japanese garden",
    model="grok-imagine-image-2.0",
    image_format="base64",
)

# Save to file
with open("garden.jpg", "wb") as f:
    f.write(response.image)

Deferred Generation

Image generation normally completes within the request. For long-running batches, or to avoid holding a connection open, set deferred: true on /v1/images/generations or /v1/images/edits. The request returns a request_id immediately; poll GET /v1/images/{request_id} for the result. Deferred requests support response_format: "url" only (the default). Results are stored alongside deferred chat completions and retained for 24 hours.

The poll response carries a status:

  • pending (HTTP 202): still generating
  • done (HTTP 200): data and usage are populated, in the same shape as a synchronous response
  • failed (HTTP 200): error holds a code and message
import os
import time
import requests

headers = {
    "Authorization": f"Bearer {os.getenv('XAI_API_KEY')}",
    "Content-Type": "application/json",
}

# Step 1: Start generation
response = requests.post(
    "https://api.x.ai/v1/images/generations",
    headers=headers,
    json={
        "model": "grok-imagine-image-2.0",
        "prompt": "A serene Japanese garden",
        "deferred": True,
    },
)
request_id = response.json()["request_id"]

# Step 2: Poll for the result
while True:
    result = requests.get(
        f"https://api.x.ai/v1/images/{request_id}",
        headers={"Authorization": headers["Authorization"]},
    )
    data = result.json()

    if data["status"] == "done":
        print(f"Image URL: {data['data'][0]['url']}")
        break
    elif data["status"] == "failed":
        print(f"Generation failed: {data['error']['message']}")
        break
    else:
        print("Still processing...")
        time.sleep(5)
# Step 1: Start generation
curl -X POST https://api.x.ai/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-imagine-image-2.0",
    "prompt": "A serene Japanese garden",
    "deferred": true
  }'
# => {"request_id": "..."}

# Step 2: Poll for the result
curl https://api.x.ai/v1/images/<request_id> \
  -H "Authorization: Bearer $XAI_API_KEY"
# => 202 {"request_id": "...", "status": "pending"}
# => 200 {"request_id": "...", "status": "done", "data": [{"url": "...", "mime_type": "image/jpeg"}], "usage": {...}}

You can also register a webhook for the image.generation.completed, image.generation.failed, image.edit.completed and image.edit.failed events instead of polling.

Response Details

The xAI SDK exposes additional metadata on the response object beyond the image URL or base64 data.

Moderation — Check whether the generated image passed content moderation:

if response.respect_moderation:
    print(response.url)
else:
    print("Image filtered by moderation")

Model — Get the actual model used (resolving any aliases):

print(f"Model: {response.model}")

Concurrent Requests

When you need to generate multiple images with different prompts, such as generating unrelated images in parallel, use AsyncClient with asyncio.gather to fire requests concurrently. This is significantly faster than issuing them one at a time.

[!TIP]

If you want multiple variations from the same prompt, use sample_batch() with the n parameter` instead. That generates all images in a single request and is the most efficient approach for same-prompt generation.

import asyncio
import xai_sdk

async def generate_concurrently():
    client = xai_sdk.AsyncClient()

    # Each request uses a different prompt
    prompts = [
        "A futuristic city skyline at sunset",
        "A serene Japanese garden in winter",
        "An astronaut floating above Earth",
        "A medieval castle on a misty mountain",
    ]

    # Fire all requests concurrently
    tasks = [
        client.image.sample(
            prompt=prompt,
            model="grok-imagine-image-2.0",
        )
        for prompt in prompts
    ]

    results = await asyncio.gather(*tasks)

    for prompt, result in zip(prompts, results):
        print(f"{prompt}: {result.url}")

asyncio.run(generate_concurrently())