# 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](https://docs.x.ai/developers/rest-api-reference/inference/images) · [Image generation guide](https://docs.x.ai/developers/model-capabilities/images/generation) · [Editing](https://docs.x.ai/developers/model-capabilities/images/editing) · [Multi-image editing](https://docs.x.ai/developers/model-capabilities/images/multi-image-editing) · [Imagine overview](https://docs.x.ai/developers/model-capabilities/imagine) · [Files API integration](https://docs.x.ai/developers/model-capabilities/imagine/files) · [Migration: -quality retirement](https://docs.x.ai/developers/migration/imagine-image-quality-nov-2) · [Pricing](https://docs.x.ai/developers/pricing) · [Rate limits](https://docs.x.ai/developers/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, ``… 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 ```json {"data": [{"b64_json": "", "mime_type": "image/jpeg"}], "usage": {"cost_in_usd_ticks": 200000000}} ``` - `data[]`: `url` (ephemeral `https://imgen.x.ai/xai-imgen/xai-.jpeg`, download promptly) or `b64_json` (bare base64), `mime_type` (live: always `image/jpeg`), optional `file_output {file_id, filename, expires_at, public_url, public_url_error, public_url_expires_at}` and `storage_error`. - `usage`: only `cost_in_usd_ticks` was present live; the documented token fields (`input_tokens`, `output_tokens`, `*_details` with upsampler reasoning tokens) were absent. - No `created`, `id`, `model` or `revised_prompt` fields (unlike OpenAI). The xAI SDK exposes `respect_moderation` and `model` from 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) 1. `POST /v1/images/generations` `grok-imagine-image`, "a plain white square", `n=1`, `1:1`, `1k`, `b64_json` → 200, 110 KB JPEG, `cost_in_usd_ticks` 200000000 ($0.02). 2. `POST /v1/images/edits` same model, `image.url` = data URL of (1), "draw a small red circle in the center" → 200, 123 KB JPEG, 220000000 ticks ($0.022). 3. 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`).