> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.hrizn.io/llms.txt
> Use this file to discover all available pages before exploring further.

# images:write

> Generate AI images into the site Media Library

<code>images:write</code>

The `images:write` scope lets you start asynchronous AI image generation into a site's Media Library and regenerate an existing generated image in place. It is included in the **Full Access** and **Content Generation** presets and in the MCP **Read + Create** profile. Reading images back (including polling a generation) uses [`images:read`](/scopes/images-read); keys that hold only `images:write` may still poll `GET /public/images/{imageId}`.

Generation is gated by the site's `IMAGE_GENERATION` plan entitlement. Denied sites receive `403 plan_upgrade_required` before any asset or job is created.

## Endpoints

| Method | Path                       | Description                                       |
| ------ | -------------------------- | ------------------------------------------------- |
| `POST` | `/public/images/generate`  | Start (or regenerate) an AI image                 |
| `GET`  | `/public/images/{imageId}` | Poll generation status (also under `images:read`) |

***

## Generate image

```
POST /public/images/generate
```

Returns `202` with `image_id` (the Media Library asset id). Send `X-Idempotency-Key` to make retries safe. Pass `asset_id` in the body to regenerate an existing image.

### Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.app.hrizn.io/v1/public/images/generate \
    -H "X-API-Key: hzk_your_key_here" \
    -H "X-Idempotency-Key: 6f1d2c3b-4a5e-4f60-9b7c-8d9e0f1a2b3c" \
    -H "Content-Type: application/json" \
    -d '{"prompt":"A silver mid-size SUV parked outside a dealership at golden hour","aspect_ratio":"16:9"}'
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const res = await fetch("https://api.app.hrizn.io/v1/public/images/generate", {
    method: "POST",
    headers: {
      "X-API-Key": "hzk_your_key_here",
      "X-Idempotency-Key": crypto.randomUUID(),
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      prompt: "A silver mid-size SUV parked outside a dealership at golden hour",
      aspect_ratio: "16:9",
    }),
  });
  const { data } = await res.json(); // { image_id, generation_id, status: "generating" }
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests, uuid

  response = requests.post(
      "https://api.app.hrizn.io/v1/public/images/generate",
      headers={
          "X-API-Key": "hzk_your_key_here",
          "X-Idempotency-Key": str(uuid.uuid4()),
      },
      json={
          "prompt": "A silver mid-size SUV parked outside a dealership at golden hour",
          "aspect_ratio": "16:9",
      },
  )
  data = response.json()["data"]
  ```
</CodeGroup>

***

## Get image

```
GET /public/images/{imageId}
```

Returns `status` (`generating`, `complete`, `error`), `image_url` once complete, and `error` on failure — plus the full image read projection (alt text, AI metadata, prompts, variants) documented under [`images:read`](/scopes/images-read).

***

## Webhooks

Subscribe to `image.generation.completed` and `image.generation.failed` instead of polling. Both carry `asset_id` (the `image_id`), `generation_id`, and `idempotency_key`; completed events add `image_url` and `reused`, failed events add `error`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "event_type": "image.generation.completed",
  "site_id": "8f1c...",
  "timestamp": "2026-09-06T14:02:11.000Z",
  "data": {
    "asset_id": "2c9c5b1e-6d0d-4c74-9c8f-3b1e0a5d8f21",
    "generation_id": "7a3f2e10-1b2c-4d5e-8f90-abcdef123456",
    "idempotency_key": "6f1d2c3b-4a5e-4f60-9b7c-8d9e0f1a2b3c",
    "article_id": null,
    "image_url": "https://assets.app.hrizn.io/public/media-library/8f1c.../7a3f2e10.jpg",
    "reused": false
  }
}
```

See [Webhooks](/webhooks) for delivery and signature details.
