# Skyboxes

> Generate a 360° environment — an 8K HDRI to light a 3D scene, an equirectangular PNG, a depth map and a web preview — for one flat price.

A skybox is a whole surrounding world in one image: sky, ground, horizon and light, wrapped all the way around the viewer. `POST /v1/skybox` takes a description and answers at once with a `gen_…` id; poll `GET /v1/skybox/{id}` until it is done, then download the files you need.

```bash title="curl"
curl https://api.lumavox.ai/v1/skybox \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "A salt flat at blue hour, thin cloud, distant mesas" }'
```

```json title="Response — 202 Accepted (abridged)"
{
  "id": "gen_a1B2c3D4e5F6g7H8",
  "status": "queued",
  "capability": "skybox",
  "model": "skybox-ai",
  "prompt": "A salt flat at blue hour, thin cloud, distant mesas",
  "seed": null,
  "enhance_prompt": false,
  "negative_text": null,
  "style_id": null,
  "init_image": null,
  "init_strength": null,
  "credits_micros": 10000000,
  "skybox": null,
  "error": null,
  "created_at": "2026-10-24T09:31:00.004Z",
  "finished_at": null
}
```

A generation has the same fields whatever made it; [Images](https://docs.lumavox.ai/media/images.md) shows them all. `credits_micros` is what was charged, in micro-credits ([Conventions](https://docs.lumavox.ai/conventions.md#credits)).

The key needs the `skybox` scope. See [Authentication](https://docs.lumavox.ai/authentication.md).

## What you get back

Poll every few seconds until `status` is `succeeded` or `failed` — [Queued jobs](https://docs.lumavox.ai/jobs.md) covers the pattern.

```bash title="curl"
curl https://api.lumavox.ai/v1/skybox/gen_a1B2c3D4e5F6g7H8 \
  -H "Authorization: Bearer $API_KEY"
```

```json title="Response — succeeded (abridged)"
{
  "id": "gen_a1B2c3D4e5F6g7H8",
  "status": "succeeded",
  "capability": "skybox",
  "skybox": {
    "asset_id": "ast_Q9r8S7t6U5v4W3x2",
    "url": "https://…",
    "preview_url": "https://…",
    "width": 8192,
    "height": 4096,
    "content_type": "image/vnd.radiance",
    "size_bytes": 98304000,
    "has_thumbnail": true,
    "files": [
      { "name": "hdr-4k", "content_type": "image/vnd.radiance", "url": "https://…", "width": 4096, "height": 2048, "size_bytes": 25165824 },
      { "name": "png-8k", "content_type": "image/png", "url": "https://…", "width": 8192, "height": 4096, "size_bytes": 61000000 },
      { "name": "preview-2k", "content_type": "image/webp", "url": "https://…", "width": 2048, "height": 1024, "size_bytes": 640000 },
      { "name": "depth-2k", "content_type": "image/jpeg", "url": "https://…", "width": 2048, "height": 1024, "size_bytes": 310000 }
    ]
  },
  "error": null,
  "created_at": "2026-10-24T09:31:00.004Z",
  "finished_at": "2026-10-24T09:31:52.640Z"
}
```

- **`skybox.url` is the full-size HDRI** — a 32-bit Radiance `.hdr`, 2:1 equirectangular. It is what you load into a 3D engine to light a scene. **It will not display in a browser.**
- **`skybox.preview_url` is a 2K WebP** — load this in a 360° web viewer.
- **`skybox.files`** lists every file made, each with its own link:

| `name` | Type | What it is |
|---|---|---|
| `hdr-4k`, `hdr-2k` | `image/vnd.radiance` | Smaller copies of the HDRI. |
| `png-8k`, `png-4k`, `png-2k` | `image/png` | The environment as an ordinary equirectangular image. |
| `preview-2k` | `image/webp` | The web preview (`preview_url`). |
| `depth-2k` | `image/jpeg` | A depth map of the scene. |

Every file is 2:1. The HDRI is always there when the status is `succeeded`; any other file that could not be made is left out of `files`, so read the list rather than assuming every name. A file whose link could not be made this time is still listed, with `url` `null`.

Every link is short-lived — about fifteen minutes, made fresh on each response. Poll again, or read the asset with `GET /v1/assets/{asset_id}`, for new ones. The skybox stays in your [asset library](https://docs.lumavox.ai/library/assets.md) under `skybox.asset_id`.

## What you can set

Only `prompt` is required.

| Field | Default | What it does |
|---|---|---|
| `prompt` | — | The environment, 1–550 characters. Describe the surroundings — sky, ground, horizon, light — rather than a subject. |
| `negative_text` | none | What to keep out of it, up to 200 characters. |
| `style_id` | provider default | A style from `GET /v1/skybox/styles`. |
| `seed` | random | Reuse a seed to get the same environment again. **Starts at 1, not 0.** |
| `enhance_prompt` | `false` | Let the provider rewrite your prompt before generating. |
| `init_image` | none | An `ast_…` **equirectangular** image in your library to build from. |
| `init_strength` | `0.5` | How much `init_image` shapes the result, from `0` (ignore it) to `0.97`. |
| `folder_id` | root | The `fld_…` folder in your library the result goes in. |

`init_strength` only means something with `init_image`: sending a strength other than the default without an image is a 422, so you never pay for a setting that does nothing.

## Styles

Styles change the look — and the model — of the environment. The list is the provider's and changes over time, so fetch it rather than hard-coding ids.

```bash title="curl"
curl https://api.lumavox.ai/v1/skybox/styles \
  -H "Authorization: Bearer $API_KEY"
```

```json title="Response"
{
  "data": [
    {
      "id": 2,
      "name": "…",
      "max_prompt_chars": 550,
      "max_negative_chars": 200,
      "model_version": "…",
      "image": "https://…"
    }
  ],
  "next_cursor": null
}
```

Pass a style's `id` as `style_id`. Each style can carry its own prompt limits (`max_prompt_chars`, `max_negative_chars`) and a sample `image`, each `null` where the provider gave none. Every style is in one page. The list is fetched live and cached briefly; if the provider cannot be reached, `data` comes back empty.

## Charges and refunds

- **One flat price per generation**, whatever style, seed or input you choose. `credits_micros` on the 202 is what was charged.
- **Charged when accepted, refunded in full** if the generation ends `failed`.
- **There is a limit on how many of your skyboxes may be generating at once.** Over it, the request is a 429 and nothing is charged.

## Errors

| Status | When |
|---|---|
| 400 | The body is not valid JSON. |
| 422 | `init_image` or `folder_id` is missing, is not yours, or is not a ready image. |
| 402 | Your organisation has run out of credits, or this job's estimate would take its balance past the grace buffer. Nothing is charged. |
| 403 | The key does not hold the `skybox` scope. |
| 404 | (Poll) No skybox with that id in your organisation. |
| 422 | The body failed validation: an empty prompt, a number out of range, `init_strength` without `init_image`, an unknown field. `issues` names each. |
| 429 | Too many requests, or too many skyboxes already generating. Nothing was charged. |
| 503 | Skybox generation is not available on this deployment. |

See [Errors and limits](https://docs.lumavox.ai/errors.md) for the error shape.

## See also

- [Templates](https://docs.lumavox.ai/media/templates.md) — skyboxes someone has already designed.
- [The skybox reference](https://docs.lumavox.ai/reference/skybox.md) — every field.
