xAI Imagine — Images API (/v1/images/*)
Status: POST /v1/images/generations DOCUMENTED + LIVE_VERIFIED · POST /v1/images/edits DOCUMENTED + LIVE_VERIFIED · GET /v1/image-generation-models[/{id}] DOCUMENTED + LIVE_VERIFIED · grok-imagine-image-quality DEPRECATED (slug retired 2026-11-02 → served by grok-imagine-image-2.0 quality: low) · grok-2-image RETIRED (live 404) · grok-imagine-image-pro LEGACY alias of -quality.
Sources: Images reference · Image generation guide · Editing · Multi-image editing · Imagine overview · Files API integration · Migration: -quality retirement · Pricing · Rate limits · OpenAPI GenerateImageRequest, EditImageRequest, GeneratedImageResponse, ImageGenerationModel, ImagePricingTier.
Last verified: 2026-09-18 (live calls logged in reports/live-requests.jsonl, notes prefixed media-agent; raw in tmp-live/xai-media/images-*.json).
Machine-readable: generated/fragments/endpoints/xai-media-voice-skills.json, parameters/xai-images.json, objects/xai-media-objects.json.
The Imagine image surface is OpenAI-shaped for generation (client.images.generate() works with base_url=https://api.x.ai/v1) but edits are JSON-only (no multipart) — the OpenAI SDK images.edit() is explicitly unsupported. Image generation also exists as a Responses-API tool (image_generation, output item image_generation_call) — documented by the tools agent (docs/tools/); generated/fragments/status-lifecycles/xai-lifecycles.json carries its status machine.
Endpoints
| Method / path | Purpose | Body | Sync | Status |
|---|---|---|---|---|
POST /v1/images/generations |
text → 1–10 images | JSON | yes (~5–10 s live) | LIVE_VERIFIED |
POST /v1/images/edits |
prompt + 1 image (image) or 2–5 images (images[]) → image(s) |
JSON only (URL / data URL / file_id) |
yes | LIVE_VERIFIED |
GET /v1/image-generation-models |
models + per-image price matrix | — | — | LIVE_VERIFIED |
GET /v1/image-generation-models/{model_id} |
one model (aliases resolve) | — | — | LIVE_VERIFIED |
Batch API: image generation/editing are accepted in /v1/batches at standard (undiscounted) rates; result URLs expire after 1 hour. Priority processing is not available for images.
Models (live GET /v1/image-generation-models, 2026-09-18)
| id | aliases | max_prompt_length | inputs | default price (image_price) |
pricing matrix | notes |
|---|---|---|---|---|---|---|
grok-imagine-image |
grok-imagine-image-2026-03-02 |
16,000 | text, image | 2e8 ticks = $0.02 | — (flat) | v1.0; cheapest |
grok-imagine-image-2.0 |
— | 64,000 | text, image | 6e8 = $0.06 (medium/1k) | low 1k $0.04 · 1.5k $0.05 · 2k $0.06 · medium 1k $0.06 · 1.5k $0.07 · 2k $0.08 | only model with quality; up to 5 edit sources |
grok-imagine-image-quality |
-quality-20260403, -quality-latest, grok-imagine-image-pro |
16,000 | text, image | 5e8 = $0.05 | — | retired 2026-11-02 → 2.0 low (60-day notice from 2026-09-02) |
Prices are USD ticks: 1 cent = 100,000,000 ticks, 1 USD = 10,000,000,000 ticks. The pricing page rows: grok-imagine-image $0.02 / image, grok-imagine-image-quality $0.05, grok-imagine-image-2.0 $0.04 (the page quotes the low/1k tier; the models endpoint quotes medium/1k = $0.06 as default). Edits bill input image + output image: live edit on grok-imagine-image = 2.2e8 ticks = $0.022.
Rate limits (documented, per tier): image models 6 / 12 / 25 / 50 / 100 requests-per-minute at T0–T4 (x-ratelimit-limit-requests: 300 observed on our key, window unknown). Imagine limit increases go through sales@x.ai, not the credit tiers.
Request parameters — POST /v1/images/generations
| param | type | default | notes | status |
|---|---|---|---|---|
model |
string | (none) | id or alias; grok-2-image → 404 not-found |
LIVE_VERIFIED |
prompt |
string | required | ≤ max_prompt_length |
LIVE_VERIFIED |
n |
int | 1 | 1–10; 0 → 400 invalid-argument "must be between 1 and 10 inclusive" |
LIVE_VERIFIED |
response_format |
url | b64_json |
url |
png → 400 "Invalid format." |
LIVE_VERIFIED |
aspect_ratio |
enum | auto |
1:1 3:4 4:3 9:16 16:9 2:3 3:2 9:19.5 19.5:9 9:20 20:9 1:2 2:1 21:9 5:2 auto; bad value → 422 text/plain serde error listing the enum |
LIVE_VERIFIED |
resolution |
1k | 1.5k | 2k |
1k |
grok-imagine models; 1.5k only in OpenAPI/reference, not the guide | LIVE_VERIFIED |
quality |
low | medium | auto |
auto (= low for generation, medium for edits) |
documented as 2.0-only, but live quality: low on grok-imagine-image was accepted (200, $0.02) — not rejected |
LIVE_VERIFIED (quirk) |
storage_options |
object | — | {filename (req), expires_after ≤ 2592000 s, public_url bool|obj} → adds data[].file_output |
DOCUMENTED |
user |
string | — | abuse monitoring id | DOCUMENTED |
POST /v1/images/edits takes the same fields plus image {url | file_id} or images[] {url | file_id} (2–5, <IMAGE_0>… in the prompt; aspect_ratio only meaningful for multi-image). image.url accepts a public URL or a data:image/...;base64, URL (also spelled image_url; the docs' extra "type": "image_url" key is optional). There is no size, style, seed, mask or streaming parameter on this surface. Quirk: an edit request with prompt only (no image/images) returned 200 and a fresh image billed $0.02 instead of a validation error.
Response
{"data": [{"b64_json": "<base64 JPEG>", "mime_type": "image/jpeg"}],
"usage": {"cost_in_usd_ticks": 200000000}}data[]:url(ephemeralhttps://imgen.x.ai/xai-imgen/xai-<uuid>.jpeg, download promptly) orb64_json(bare base64),mime_type(live: alwaysimage/jpeg), optionalfile_output {file_id, filename, expires_at, public_url, public_url_error, public_url_expires_at}andstorage_error.usage: onlycost_in_usd_tickswas present live; the documented token fields (input_tokens,output_tokens,*_detailswith upsampler reasoning tokens) were absent.- No
created,id,modelorrevised_promptfields (unlike OpenAI). The xAI SDK exposesrespect_moderationandmodelfrom the gRPC response.
Errors observed
| case | HTTP | body |
|---|---|---|
unknown enum value (aspect_ratio: "7:7") |
422 text/plain |
Failed to deserialize the JSON body into the target type: aspect_ratio: unknown variant 7:7, expected one of … |
n: 0 |
400 | {"code":"invalid-argument","error":"The number of images to generate (n) must be between 1 and 10 inclusive."} |
response_format: "png" |
400 | {"code":"invalid-argument","error":"Invalid format."} |
model: "grok-2-image" |
404 | {"code":"not-found","error":"The model grok-2-image does not exist or your team … does not have access to it. …"} |
Live verification (2026-09-18)
POST /v1/images/generationsgrok-imagine-image, "a plain white square",n=1,1:1,1k,b64_json→ 200, 110 KB JPEG,cost_in_usd_ticks200000000 ($0.02).POST /v1/images/editssame model,image.url= data URL of (1), "draw a small red circle in the center" → 200, 123 KB JPEG, 220000000 ticks ($0.022).- Two accidental generations while probing validation (quality on v1, edit without image) — $0.04, logged with cost corrections.
Examples
examples/xai/images/generate.sh (LIVE_VERIFIED), generate.py (OpenAI SDK + extra_body), generate.ts (fetch), edit.py (JSON edit with data URL), list_models.sh — see examples/manifest-xai-media.json. Tests: tests/xai/test_images.py (validation tests free; generation gated by RUN_IMAGE_TESTS).