API reference
POSTGenerate mockups
POST /v1/projects/{project_id}/mockups: Starts a Light AI Gen 3.0 generation of 1–4 lighting mockups for the project, exactly as the app generates them: from the project's front view and its measured guide lines (default), or from a front photo (photo_url, fetched once, or `pho
https://api.light-ai.app/v1/projects/{project_id}/mockupsStarts a Light AI Gen 3.0 generation of 1–4 lighting mockups for the project, exactly as the app generates them: from the project's front view and its measured guide lines (default), or from a front photo (photo_url, fetched once, or photo_upload). Costs 5 credits per image from the contractor's own credits, reserved now: 402 insufficient_credits (with required and top_up_url, plus balance for an organization key only: a partner key never sees the contractor's balance) when short, and nothing is charged; a partner key also needs the grant's mockups:write and stays within the spend cap the contractor set (402 partner_spend_cap_reached). Failed images are refunded. Answers 202 with the generation; poll GET /v1/mockup_generations/{id} or subscribe to mockup.completed and mockup.failed. Idempotency-Key is required: a retry with the same key never charges again. At most 3 generations per organization run at once (429 rate_limited, mockup_concurrency). Finished images join the project as one editor mockup card (named from its light colors in the app, for example Warm White or Candy Cane, unless the contractor renames it). A card generated from a front photo (photo_url or photo_upload) is not tied to one of the project's front views: the photo is a working copy, removed a few hours after the generation finishes, so the contractor chooses a front view with a photo for that card before generating more from it in the app. Test keys simulate a finished generation with a sample image (no credits).
| Scope | mockups:write |
|---|---|
| Credential | API key: Authorization: Bearer lai_live_… (or lai_test_…). Partner keys add Light-AI-Organization. |
| Test mode | Works with test keys against simulated test objects. |
| Idempotency | Idempotency-Key required. See Idempotency. |
Path parameters#
prj_…). Id prefix prj_.Headers#
org_…). Organization keys may omit it. Id prefix org_.2026-11-01.idempotency_key_reused. 8–128 characters.Request body#
light-ai-gen-3.0.type: front_view, photo_url, photo_upload.front_view.upl_.classic_warm_white, cool_white, multicolor, candy_cane (red and white, alternating) or red_and_green (alternating). bulb_colors and c9_pattern override it. One of: classic_warm_white, cool_white, multicolor, candy_cane, red_and_green.Warm White, Cool White, Red, Green, Blue, Multicolor, Purple, Orange, Pink, Yellow. 1–4 items.Warm White, Cool White, Red, Green, Blue, Multicolor, Purple, Orange, Pink, Yellow. 1–4 items.all-same, alternating, double-alternating, other.other: the pattern in words. 1–200 characters.Response 202#
The generation (queued, or the earlier answer for a retried Idempotency-Key).
mgen_.mockup_generation.succeeded when at least one image succeeded (each image has its own status), failed when none did. Every failed image is refunded. One of: queued, processing, succeeded, failed.prj_.light-ai-gen-3.0.front_view, photo_url, photo_upload.queued, processing, succeeded, failed.mk_…), once succeeded. Id prefix mk_.generation_failed (the image could not be generated), generation_paused (too many recent failures or too much at once for this account: retry in a few minutes), generation_interrupted, generation_unavailable, queue_timeout (the image could not be started within 6 hours: request it again), source_photo_unavailable, project_deleted. A failed image is always refunded. One of: generation_failed, generation_paused, generation_interrupted, generation_unavailable, queue_timeout, source_photo_unavailable, project_deleted.generation_failed, generation_paused, generation_interrupted, generation_unavailable, queue_timeout, source_photo_unavailable, project_deleted.Errors#
| Status | Meaning |
|---|---|
400 | Bad request. bad_request, test_mode_mismatch, test_mode_unsupported, unsupported_api_version |
401 | Missing or invalid credential. authentication_required, invalid_api_key, api_key_revoked, api_key_expired, api_key_suspended |
402 | Not enough credits (insufficient_credits: required and top_up_url, plus balance for organization keys only; a partner key never sees the contractor's balance), or a partner spend cap the organization set (partner_spend_cap_reached). Nothing was charged. |
403 | Not allowed. insufficient_scope, plan_upgrade_required, organization_paused, organization_off_season, api_disabled, api_access_not_enabled, ip_not_allowed, forbidden |
404 | Not found (also for objects of other organizations and for organizations without an active grant). |
409 | Conflict. stale_state, conflict, idempotency_in_progress, idempotency_scope_mismatch, quote_already_decided, quote_not_current, billing_review_required |
413 | Request bodies are limited to 256 KB. |
415 | The body is not JSON: send Content-Type: application/json. unsupported_media_type |
422 | Validation failed. idempotency_key_reused |
429 | Rate limited or daily cap reached. See Retry-After and the RateLimit headers. rate_limited, daily_cap_reached |
500 | Unexpected server error. Safe to retry with exponential backoff; quote the Request-Id to support. internal_error |
503 | Temporarily unavailable. Retry with exponential backoff. service_unavailable |