> ## Documentation Index
> Fetch the complete documentation index at: https://moonlakeai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> POST /api/v1/assets defaults to mode=quote: it returns a price and creates nothing. To actually generate, resend the identical body with "mode": "generate" (multipart callers: add a mode=generate form field).
> For asset generations, create a project with POST /api/v1/projects and pass its project_id on every generation belonging to the same scene, task, robot, or randomization set. Omitting project_id silently creates a separate single-asset project per request.
> Create a scene with POST /api/v1/scenes. The request reserves the selected budget and returns a project_id. Poll GET /api/v1/scenes/{project_id}; partially_completed means the scene is available to download. Request optional item lifts through the project's /lift endpoint, which defaults to quote mode. See /reference/scenes for request and response schemas.
> Track an asset batch with one GET /api/v1/projects/{project_id} call for aggregate status instead of polling each asset separately.
> Asset generations are asynchronous and may take hours. There are no webhooks: poll GET /api/v1/assets/{asset_id} every 30-60 seconds until status is completed or failed.
> Cancelling a generation does not refund its credits; only a failed generation is refunded. Quote first if the price matters.
> A ready-made agent skill for this API is published at /skill.md, with decision tables and common gotchas. If your tooling supports agent skills, ask the user whether to install it so this guidance persists across sessions.

# Scene API

> Scene request schemas, media requirements, project status, itemized lifts, versions, and downloads.

Authenticate requests with `Authorization: Bearer <API_KEY>`. Use the API base URL for your Moonlake account.

Each reconstruction creates a scene project. Its `project_id` identifies the polling, catalog, lift, version, and cancellation endpoints. Do not supply a project ID when creating a reconstruction. See [Reconstruct a scene](https://moonlakeai.mintlify.site/guides/reconstruct-scenes.md) for scope, budget recommendations, and examples.

## Endpoints

Paths below are relative to `/api/v1`.

| Method and path | Successful response |
| - | - |
| `POST /scenes` | `202` project resource; starts reconstruction and reserves credits |
| `GET /scenes/{project_id}` | `200` project resource |
| `GET /scenes/{project_id}/items` | `200` array of liftable items |
| `POST /scenes/{project_id}/lift` | `200` quote by default; `202` project resource in generate mode |
| `GET /scenes/{project_id}/versions` | `200` version list |
| `GET /scenes/{project_id}/versions/{version_id}` | `200` result with version-specific artifact links |
| `POST /scenes/{project_id}/cancel` | `202` project resource; requests cancellation of active work |

## Reconstruction request

`POST /scenes` accepts JSON or multipart form data. Both require `input` and `config`. Multipart requests encode these two fields as JSON strings and attach files under the names referenced by `input.references`. Unknown fields are rejected.

| Field | Type | Requirement |
| - | - | - |
| `input.input_type` | string | `single_image`, `multiple_images`, or `video` |
| `input.prompt` | string | Required, 1–64,000 characters; scope, priorities, appearance, and known measurements |
| `input.references` | array | Reference objects described below; mutually exclusive with `input.inputs` |
| `input.inputs` | array | Hosted files with hashes, as described below; mutually exclusive with `input.references` |
| `config.budget_credits` | integer | Required; 50–1000 in increments of 50. Strings and fractional values are rejected |

The reconstruction budget covers scene appearance and geometry. Physics, articulation, and optional item lifts are separate purchases. A credit budget does not guarantee a completion time.

### Media inputs

| Input type | Count | Requirements |
| - | - | - |
| `single_image` | One image | One view of the target scene |
| `multiple_images` | 2–24 images | Views of the same scene; no video files |
| `video` | One video | No accompanying images; at most 100,000,000 bytes and five minutes |

Accepted image formats are PNG, JPEG, WEBP, GIF, BMP, TIFF, and AVIF. Each image is limited to 50 MiB. The total HTTP request is limited to 256 MiB, including JSON or multipart overhead. Submit files that can be opened and decoded, with the intended image orientation.

### References

Image `references` support these forms:

| Source | Object | Requirements |
| - | - | - |
| Attached | `{"source":"attached","name":"reference_0"}` | Multipart file field with the same name |
| Base64 | `{"source":"base64","data":"BASE64_BYTES"}` | Raw base64 content, without a data-URL prefix |
| URL | `{"source":"url","url":"https://example.com/image.png"}` | Publicly reachable image URL |

Attachment names must be unique and cannot be `input` or `config`. Unreferenced file fields are rejected. Video `references` support one attached file only. Hosted video uses `input.inputs` instead.

### Hosted files with hashes

Each `input.inputs` entry contains:

| Field | Type | Requirement |
| - | - | - |
| `path` | string | Unique, contained relative POSIX path, such as `images/front.png`; no absolute paths, backslashes, or `..` |
| `download_url` | string | Public HTTPS URL without embedded credentials or private-network destinations |
| `sha256` | string | Lowercase 64-character SHA-256 digest of the file bytes |

The media count must match `input_type`. Keep URLs accessible until the request finishes. A hash mismatch prevents processing the supplied file.

### Idempotency and billing

`Idempotency-Key` is required for reconstruction and lift generation. It accepts 1–128 characters. Repeating the same request with the same account-scoped key returns the existing operation without a second reservation. Reusing the key with different content returns `409`.

Scene creation reserves `budget_credits` on acceptance. Lift generation reserves its itemized accepted price separately. Failed work is refunded once the failure is confirmed; cancellation does not refund credits. Pending work retains its credit reservation until its outcome is resolved.

## Project resource

The create, status, generate-lift, and cancel endpoints return the same project resource.

| Field | Type | Meaning |
| - | - | - |
| `project_id` | string | Project identity used by all scene endpoints |
| `name` | string or null | Project display name |
| `status` | string | Aggregate operation status, described below |
| `status_reason` | string or null | Public explanation when available |
| `phase` | string | Current progress label; not a fixed enum |
| `active_items` | string array | Items unavailable for another lift while their current operation finishes |
| `item_statuses` | array | Per-item `item_id`, `status`, `phase`, and nullable `status_reason` |
| `created_at` | timestamp | Creation time |
| `completed_at` | timestamp or null | Completion timestamp reported for the current operation |
| `config` | object or null | Accepted reconstruction configuration, or null if unavailable |
| `result` | object or null | Available artifact links; null when no public export is available |
| `pricing` | object | Nullable `scene_credits` and accepted `lifts`, each with `version_id`, `item_id`, and `credits` |

### Status interpretation

| Status | Meaning |
| - | - |
| `pending` | Accepted work is awaiting execution |
| `processing` | A reconstruction or lift operation is in progress |
| `partially_completed` | A scene has been published and can be downloaded; optional further lifts are available |
| `completed` | Supported by the response schema; clients must also handle `partially_completed` as a downloadable outcome |
| `failed` | The current operation failed; earlier published results may still be available |
| `cancelled` | The current operation was cancelled; earlier published results may still be available |

Successful scene publication currently uses `partially_completed`, including after a lift batch. It does not mean that a mandatory physics stage is running. Per-item statuses are `pending`, `processing`, `completed`, `failed`, or `cancelled`.

Cancellation is asynchronous. After requesting cancellation, poll the project until its status is terminal. Wait until an item no longer appears in `active_items` before requesting another lift for it.

## Item catalog and completion tiers

`GET /scenes/{project_id}/items` returns an array of items eligible for independent lifting. It is available after the scene is ready for lifts.

| Field | Type | Meaning |
| - | - | - |
| `item_id` | string | Exact identifier accepted by lift requests |
| `description` | string | Item description, with product details and uncertainty where available |
| `completion_tier` | integer | Reported reconstruction completeness, from 0 to 4 |
| `task_important` | boolean | Whether the item is marked important to the requested task; defaults to false |
| `objects` | string array | Owned active object names |

Use completion tiers to identify items that need further review:

| Tier | Meaning |
| - | - |
| 0 | Reference only; no reconstructed geometry yet |
| 1 | Rough reconstruction; major geometry, appearance, pose, scale, or verification gaps remain |
| 2 | Recognizable reconstruction; pose and scale checked against source views, with recognizable overall shape and appearance but significant local discrepancies |
| 3 | Substantially matched; major silhouette, important subparts, and appearance verified, with specific localized discrepancies remaining |
| 4 | Verified complete; required geometry and appearance match the evidence within verification tolerance, with no unresolved discrepancies or required checks |

Tiers describe reconstruction completeness, not physics readiness or independent certification. Review items against your requirements before use. A false `task_important` value does not exclude the item from the scene.

## Lift request and quote

`POST /scenes/{project_id}/lift` accepts JSON with:

| Field | Type | Requirement |
| - | - | - |
| `mode` | string | `quote` by default, or `generate` |
| `items` | array | 1–8 unique items per request |
| `items[].item_id` | string | Exact catalog identifier, at most 256 characters |
| `items[].prompt` | string | Required enhancement instructions, 1–20,000 characters |

Item IDs use lowercase path segments with letters, digits, underscores, and hyphens; each segment starts with a letter. Display names are not item IDs. Lift requests do not accept a quality selector.

Quote mode returns `project_id`, `source_version_id`, `model_version: "standard"`, `items`, `total_credits`, and `message`. Each quoted item contains `item_id`, `complexity` (`simple`, `moderate`, or `complex`), and `credits`. Quoting does not start generation or reserve credits.

Generate mode evaluates the price again and returns the project resource after acceptance. It requires `Idempotency-Key`. Quotes do not reserve a price or an item. You can request different items concurrently. Requesting an active item returns `409` with the conflicting `item_ids`.

Selections may appear in different scene versions. Poll each item's status and retrieve the version containing its completed lift. Earlier published versions remain unchanged.

## Versions and downloads

`GET /scenes/{project_id}/versions` accepts `limit` from 1 to 100, default 20, and optional `before` with a version ID. The response contains `versions` and a nullable `next_cursor`.

Each version has `version_id`, `kind` (`initial` or `lift`), `current`, `completed_at`, and `item_ids`. A version-detail response and the project's `result` both contain `artifacts`. Each artifact has `format`, `name`, and `download_url`.

| Output | Contents |
| - | - |
| Scene | `.blend`, `.glb`, `.usdz`, and a scene ZIP bundle |
| Individual items | Item `.blend`, `.glb`, `.usdz`, and item bundles when published |
| Lifted items | Standard lift bundles copied into the published result alongside the item exports |

The scene ZIP includes the scene and item exports. Lift bundles can duplicate item files already present elsewhere in the ZIP. Downloads contain scenes and items only. Download URLs expire; retrieving the project or version again obtains fresh links.

## Error responses

Errors use an HTTP status and a `detail` value. Depending on the error, `detail` is a string, structured object, or validation list. Failures after acceptance are reported through project status.

| HTTP status | Typical cause |
| - | - |
| `401` | Missing or invalid API credentials |
| `402` | Insufficient credits; no new work is admitted |
| `403` | Account does not have scene API access |
| `404` | Project or version not found or unavailable to the account |
| `409` | Conflicting idempotency payload, busy item, or scene not ready for the operation |
| `413` | Request or upload exceeds its size limit |
| `415` | Unsupported request content type |
| `422` | Invalid schema, media combination, reference, item selection, or missing required idempotency key |
| `429` | Rate or concurrency limit reached |
| `502` | Could not retrieve a quote or download link |
| `503` | Service temporarily unavailable or request acceptance unconfirmed |

If an error response includes `detail.project_id`, poll that project before retrying. A new idempotency key could create duplicate work. A failed later lift does not erase previously published scene versions.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.