Light AIDocs Beta Open Light AI

API reference

PATCHUpdate a website request form

PATCH /v1/forms/{form_id}: Pause or resume, rename, edit the wording, replace the allowed websites, or change the instant preview (on/off; one image per request at 5 credits, images_per_lead 1 or 2 is accepted for compatibility and stored as 1; monthly credit cap 5

PATCHhttps://api.light-ai.app/v1/forms/{form_id}

Pause or resume, rename, edit the wording, replace the allowed websites, or change the instant preview (on/off; one image per request at 5 credits, images_per_lead 1 or 2 is accepted for compatibility and stored as 1; monthly credit cap 5–5000; turning previews on without a cap sets 250). expected_updated_at is required (409 stale_state when the form changed). Changing the websites or turning previews on sends the account owners a notice and appears in Developers → Activity. Pro only; test keys are refused. Needs forms:write, which is never part of a preset.

Scopeforms:write
CredentialAPI key: Authorization: Bearer lai_live_… (or lai_test_…). Partner keys add Light-AI-Organization.
Test modeLive keys only (answers 400 test_mode_unsupported to a test key).

Path parameters#

form_idstringrequired#
The form id (form_…). Id prefix form_.

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.

Request body#

expected_updated_attimestamprequired#
The form's updated_at you last read (409 stale_state otherwise).
namestring#
1–120 characters.
statusstring#
One of: active, paused.
domainsstring[]#
Replaces the allowed websites (origins). At most 25 items.
copyobject#
copy.headingstring#
1–120 characters.
copy.subheadingstring#
1–300 characters.
copy.button_labelstring#
1–80 characters.
copy.success_messagestring#
1–300 characters.
instant_previewobject#
instant_preview.enabledboolean#
instant_preview.images_per_leadnumber#
instant_preview.monthly_credit_capinteger#
5–5000.

Response 200#

The updated form.

idstringrequired#
Id prefix form_.
objectstringrequired#
Always form.
namestringrequired#
statusstringrequired#
One of: active, paused, archived.
service_typestringrequired#
One of: christmas_lights, custom.
public_idstringrequired#
The id in the install snippet (ec_…).
installobjectrequired#
install.scriptstringrequired#
The snippet to paste on the website.
install.iframe_urlstringrequired#
install.hosted_urlstring | nullrequired#
Top-level page link (null unless the hosted page is on).
domainsstring[]required#
Websites allowed to show the form (origins; https://*.example.com wildcards).
hosted_page_enabledbooleanrequired#
fieldsobjectrequired#
photoobjectrequired#
questionsobject[]required#
In the order the form asks them (the owner can drag questions in the editor; follow-ups always come right after their parent question). The fixed address & photo card follows surfaces and primary_color, then contact details; the request is sent from the last question.
questions[].keystringrequired#
questions[].promptstringrequired#
questions[].typestringrequired#
One of: color, choice, multi_choice, toggle, text.
questions[].enabledbooleanrequired#
questions[].requiredbooleanrequired#
questions[].choicesobject[]required#
questions[].choices[].valuestringrequired#
questions[].choices[].labelstringrequired#
questions[].choices[].fullWidthboolean#
Shown across the whole row when it starts one (e.g. ASAP).
questions[].choices[].availableUntilobject#
The last day of the year it can be picked (recurring, the contractor's timezone); afterwards the form greys it out and a submitted pick is refused. Example: October until { month: 10, day: 31 }.
mockup_revealobject#
How the request's AI mockup appears on the form (it starts on the homeowner's photo): slider (default, a draggable before/after divider), flicker, day_night, bloom, sweep or curtain; slider_after hands the five other styles over to the slider when they end. The form's own choice, else the company default. Set in the app.
mockup_reveal.stylestringrequired#
One of: slider, flicker, day_night, bloom, sweep, curtain.
mockup_reveal.slider_afterbooleanrequired#
copyobjectrequired#
copy.headingstring | nullrequired#
copy.subheadingstring | nullrequired#
copy.button_labelstring | nullrequired#
copy.success_messagestring | nullrequired#
instant_previewobjectrequired#
instant_preview.enabledbooleanrequired#
instant_preview.images_per_leadintegerrequired#
AI mockup previews per request: always 1 (one AI mockup per request since October 2026). Kept for compatibility: PATCH still accepts 1 or 2 and stores 1.
instant_preview.credits_per_imageintegerrequired#
Always 5.
instant_preview.monthly_credit_capinteger | nullrequired#
instant_preview.used_this_monthintegerrequired#
Credits used or held by previews this UTC month.
created_attimestamprequired#
RFC 3339 timestamp (UTC, milliseconds).
updated_attimestamprequired#
RFC 3339 timestamp (UTC, milliseconds).

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
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