Concepts
Errors
Problem-details errors with a stable code, what each code means and when to retry.
Errors are RFC 9457 problem details (application/problem+json). Branch on code, never on title or detail. Every error links here with doc_url.
{
"type": "https://docs.light-ai.app/errors#validation_failed",
"title": "Validation failed",
"status": 422,
"detail": "The request is invalid. See errors[] for each field.",
"instance": "/v1/leads",
"code": "validation_failed",
"doc_url": "https://docs.light-ai.app/errors#validation_failed",
"request_id": "req_8bW2kq0xT4mZp9LcQ1vR7sYd",
"errors": [
{
"pointer": "/contact/email",
"detail": "An email or a phone number is required."
}
]
}Retrying#
- Retry
429,500and503with exponential backoff, honoringRetry-After. Reuse the sameIdempotency-Keyso a retry never duplicates a write. - Do not retry other
4xxanswers unchanged: fix the request first. - Quote
request_id(also theRequest-Idheader) when you contact support.
Codes#
| Code | Status | Title |
|---|---|---|
bad_request | 400 | Bad request |
test_mode_mismatch | 400 | Test mode mismatch |
test_mode_unsupported | 400 | Not available in test mode |
unsupported_api_version | 400 | Unsupported API version |
api_key_expired | 401 | API key expired |
api_key_revoked | 401 | API key revoked |
api_key_suspended | 401 | API key suspended |
authentication_required | 401 | Authentication required |
invalid_api_key | 401 | Invalid API key |
insufficient_credits | 402 | Insufficient credits |
partner_spend_cap_reached | 402 | Partner spend cap reached |
api_access_not_enabled | 403 | API access not enabled |
api_disabled | 403 | API disabled for this organization |
forbidden | 403 | Forbidden |
insufficient_scope | 403 | Insufficient scope |
ip_not_allowed | 403 | IP address not allowed |
organization_off_season | 403 | Organization on Off-Season |
organization_paused | 403 | Organization paused |
plan_upgrade_required | 403 | Plan upgrade required |
not_found | 404 | Not found |
method_not_allowed | 405 | Method not allowed |
billing_review_required | 409 | Billing review in progress |
conflict | 409 | Conflict |
idempotency_in_progress | 409 | Idempotent request in progress |
idempotency_scope_mismatch | 409 | Idempotency scope mismatch |
limit_reached | 409 | Limit reached |
quote_already_decided | 409 | Quote already decided |
quote_not_current | 409 | Quote is not current |
stale_state | 409 | Stale state |
payload_too_large | 413 | Payload too large |
unsupported_media_type | 415 | Unsupported media type |
idempotency_key_reused | 422 | Idempotency key reused |
validation_failed | 422 | Validation failed |
step_up_required | 428 | Recent sign-in required |
daily_cap_reached | 429 | Daily cap reached |
rate_limited | 429 | Rate limited |
internal_error | 500 | Internal error |
service_unavailable | 503 | Service unavailable |
bad_request#
400 Bad request. The request is malformed (JSON, headers or query). Read detail.
test_mode_mismatch#
400 Test mode mismatch. A test key used a live object, or the other way around.
test_mode_unsupported#
400 Not available in test mode. This endpoint works with live keys only.
unsupported_api_version#
400 Unsupported API version. The Light-AI-Version header names an unknown version. Use 2026-11-01.
api_key_expired#
401 API key expired. Create or roll a key. Subscribe to api_key.expiring to hear about it 14 and 3 days ahead.
api_key_revoked#
401 API key revoked. The key was revoked or rolled past its grace period. Use the current key.
api_key_suspended#
401 API key suspended. The organization dropped below Pro (the key works again after an upgrade), or the key was suspended because its creator left or lost the role, or by a security reset (an owner re-affirms it in Settings → Developers).
authentication_required#
401 Authentication required. Send Authorization: Bearer <key>.
invalid_api_key#
401 Invalid API key. The key is malformed or unknown. Check for truncation or whitespace.
insufficient_credits#
402 Insufficient credits. Not enough credits for a mockup generation. required and top_up_url say how many and where to buy (organization keys also see balance). Nothing was charged.
partner_spend_cap_reached#
402 Partner spend cap reached. A partner hit the mockup spend cap the contractor set. The contractor can raise or remove it.
api_access_not_enabled#
403 API access not enabled. API access is not turned on for the organization (or your partner organization). E-mail support@light-ai.app.
api_disabled#
403 API disabled for this organization. Light AI turned API access off for this organization (or your partner organization). E-mail support@light-ai.app.
forbidden#
403 Forbidden. The credential cannot do this here (for example a grant without access to that object).
insufficient_scope#
403 Insufficient scope. The key (or grant) lacks the scope named in detail. Create a key with that scope or ask the contractor to re-consent.
ip_not_allowed#
403 IP address not allowed. The key has an IP allowlist that does not include this address.
organization_off_season#
403 Organization on Off-Season. The organization is on Off-Season: new leads (POST /v1/leads, inbound sources) are still accepted, every other write answers this until the owner resumes the plan in Light AI.
organization_paused#
403 Organization paused. The organization is paused: it is read-only and inbound leads are held until it resumes.
plan_upgrade_required#
403 Plan upgrade required. API access is included on Pro. The organization must upgrade (Free and Plus have no API access).
not_found#
404 Not found. No such object for this credential (it may belong to another organization or mode).
method_not_allowed#
405 Method not allowed. This path does not support the method. The Allow header lists those it does.
billing_review_required#
409 Billing review in progress. A billing review is in progress for the organization. Retry later or contact support.
conflict#
409 Conflict. The request conflicts with the current state. Read detail, refetch and retry.
idempotency_in_progress#
409 Idempotent request in progress. A request with the same Idempotency-Key is still running. Retry after a short wait.
idempotency_scope_mismatch#
409 Idempotency scope mismatch. The key was used for another organization or credential. Use a new key.
limit_reached#
409 Limit reached. A standing count limit was reached (limit says which: webhook_endpoints, photo_uploads open at once, or open_connect_links). Retrying does not help: delete or use one first.
quote_already_decided#
409 Quote already decided. The homeowner already approved or declined this quote in Light AI. Read the quote and sync its status instead.
quote_not_current#
409 Quote is not current. A newer revision of this quote exists. Use the project's current quote.
stale_state#
409 Stale state. The object changed since you read it (or is in a state that forbids this). Refetch and retry.
payload_too_large#
413 Payload too large. The body is too large. Upload big photos with a photo upload slot.
unsupported_media_type#
415 Unsupported media type. Send Content-Type: application/json.
idempotency_key_reused#
422 Idempotency key reused. The same Idempotency-Key was used with a different body. Use a new key for a new request.
validation_failed#
422 Validation failed. errors[] lists each invalid field as a JSON pointer with a message. Values are never echoed.
step_up_required#
428 Recent sign-in required. This action needs a recent sign-in in the app (management actions only).
daily_cap_reached#
429 Daily cap reached. A daily lead limit was reached: the inbound source's daily limit (limit_scope: source) or the organization's daily lead cap (limit_scope: organization). Retry-After points to midnight UTC.
rate_limited#
429 Rate limited. Too many requests. Wait for Retry-After seconds. See Rate limits.
internal_error#
500 Internal error. Something failed on our side. Retry with the same Idempotency-Key; quote the request_id to support if it persists.
service_unavailable#
503 Service unavailable. A temporary outage. Retry with backoff and the same Idempotency-Key.