Light AIDocs Beta Open Light AI

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

POSThttps://api.light-ai.app/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 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).

Scopemockups:write
CredentialAPI key: Authorization: Bearer lai_live_… (or lai_test_…). Partner keys add Light-AI-Organization.
Test modeWorks with test keys against simulated test objects.
IdempotencyIdempotency-Key required. See Idempotency.

Path parameters#

project_idstringrequired#
The project id (prj_…). Id prefix prj_.

Headers#

Light-AI-Organizationstring#
Partner keys: the connected organization to act for (org_…). Organization keys may omit it. Id prefix org_.
Light-AI-Versionstring#
Pin a dated API version (defaults to the key's version). One of: 2026-11-01.
Idempotency-Keystringrequired#
Required: one key per logical request. A retry with the same key and body returns the same operation and never charges again (permanently, not only for 24 hours); the same key with a different body is 422 idempotency_key_reused. 8–128 characters.

Request body#

modelstring#
Light AI Gen 3.0 (the only model). Always light-ai-gen-3.0.
imagesinteger#
Number of images, 1–4 (default 1). 5 credits each. 1–4.
sourceobject#
Default: the project's front view with its guide lines. Variants by type: front_view, photo_url, photo_upload.
source.typestring#
Always front_view.
source.front_view_idstring#
The project's front view (default: the first one with a photo). Its measured guide lines place the lights, as in the app. 1–128 characters.
source.urlstring#
A public https URL of the front photo (JPEG, PNG or WebP, at most 10 MB; no redirects). At most 2048 characters.
source.upload_idstring#
A photo uploaded with POST /v1/projects/{project_id}/photo_uploads. Id prefix upl_.
featuresstring[]#
front_view only: the measured features to light (template line-item ids). Default: every feature measured on the view. 1–40 items.
style_presetstring#
A starting point for bulb colors and pattern: 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.
bulb_colorsobject#
Bulb colors for C9 lines and mini-light areas, as in the app.
bulb_colors.c9string[]#
One of: Warm White, Cool White, Red, Green, Blue, Multicolor, Purple, Orange, Pink, Yellow. 1–4 items.
bulb_colors.ministring[]#
One of: Warm White, Cool White, Red, Green, Blue, Multicolor, Purple, Orange, Pink, Yellow. 1–4 items.
c9_patternstring#
One of: all-same, alternating, double-alternating, other.
c9_pattern_descriptionstring#
With c9_pattern other: the pattern in words. 1–200 characters.
ambianceobject#
Ambiance toggles of the project's template, e.g. {"snow": true, "fullMoon": true} (default: the template's defaults).
instructionsstring#
Extra preferences in words (at most 500 characters), as in the app's prompt box. At most 500 characters.

Response 202#

The generation (queued, or the earlier answer for a retried Idempotency-Key).

idstringrequired#
Id prefix mgen_.
objectstringrequired#
Always mockup_generation.
livemodebooleanrequired#
false for objects created with a test key.
statusstringrequired#
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.
project_idstring | nullrequired#
Id prefix prj_.
modelstringrequired#
Always light-ai-gen-3.0.
model_namestringrequired#
images_requestedintegerrequired#
1–4.
images_succeededintegerrequired#
images_failedintegerrequired#
sourceobjectrequired#
source.typestringrequired#
One of: front_view, photo_url, photo_upload.
source.front_view_idstring | null#
optionsobjectrequired#
The options the generation used (preset, bulb colors, pattern, ambiance, features, instructions).
creditsobjectrequired#
credits.per_imageintegerrequired#
Credits per image (5, as in the app).
credits.reservedintegerrequired#
Held for images still generating.
credits.chargedintegerrequired#
Spent on succeeded images.
credits.refundedintegerrequired#
Returned for failed images.
imagesobject[]required#
images[].indexintegerrequired#
1–4.
images[].statusstringrequired#
One of: queued, processing, succeeded, failed.
images[].mockup_idstring | nullrequired#
The mockup in the project's mockup history (mk_…), once succeeded. Id prefix mk_.
images[].urlstring | nullrequired#
Signed image URL (WebP), valid until expires_at. null in webhook payloads: GET the generation for a fresh URL.
images[].expires_attimestamp | nullrequired#
RFC 3339 timestamp (UTC, milliseconds).
images[].removedbooleanrequired#
true when the image was generated but has since been deleted from the project.
images[].failure_codestring | nullrequired#
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.
images[].sampleboolean#
Test mode: a fixed sample image, nothing was generated.
failure_codestring | nullrequired#
One of: generation_failed, generation_paused, generation_interrupted, generation_unavailable, queue_timeout, source_photo_unavailable, project_deleted.
generated_viastringrequired#
The requester label in the contractor's credit and project history: "Generated via API by <partner>" or "Generated via API key "<name>"". The organization and the partner that made the request see it; any other partner sees "Generated via API".
created_attimestamprequired#
RFC 3339 timestamp (UTC, milliseconds).
updated_attimestamprequired#
RFC 3339 timestamp (UTC, milliseconds).
completed_attimestamp | nullrequired#
RFC 3339 timestamp (UTC, milliseconds).
simulatedboolean#
Test mode only.

Errors#

StatusMeaning
400Bad request. bad_request, test_mode_mismatch, test_mode_unsupported, unsupported_api_version
401Missing or invalid credential. authentication_required, invalid_api_key, api_key_revoked, api_key_expired, api_key_suspended
402Not 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.
403Not allowed. insufficient_scope, plan_upgrade_required, organization_paused, organization_off_season, api_disabled, api_access_not_enabled, ip_not_allowed, forbidden
404Not found (also for objects of other organizations and for organizations without an active grant).
409Conflict. stale_state, conflict, idempotency_in_progress, idempotency_scope_mismatch, quote_already_decided, quote_not_current, billing_review_required
413Request bodies are limited to 256 KB.
415The body is not JSON: send Content-Type: application/json. unsupported_media_type
422Validation failed. idempotency_key_reused
429Rate limited or daily cap reached. See Retry-After and the RateLimit headers. rate_limited, daily_cap_reached
500Unexpected server error. Safe to retry with exponential backoff; quote the Request-Id to support. internal_error
503Temporarily unavailable. Retry with exponential backoff. service_unavailable