Light AIDocs Beta Open Light AI

API reference

POSTReceive a lead (inbound source, header secret)

POST /v1/inbound/{source_id}: For HighLevel workflows, Zapier, Make, n8n, Sweep&Go and form tools.

POSThttps://api.light-ai.app/v1/inbound/{source_id}

For HighLevel workflows, Zapier, Make, n8n, Sweep&Go and form tools. Authenticate with Authorization: Bearer lai_whin_… or X-Light-AI-Source-Secret. The body is either the POST /v1/leads shape or any JSON your source's field map understands. Always receipt-only. Per-source limits: 60/min and the daily limit. Only the contact can refuse a lead (a name, and an email or a phone): a country name is normalized (United States → US), and an address or other optional part that cannot be used is left out (its raw value kept in custom_fields.inbound_*) instead of losing the lead.

CredentialInbound source secret: Authorization: Bearer lai_whin_… or X-Light-AI-Source-Secret: lai_whin_….
Test modeWorks with test keys (test objects only).
IdempotencyIdempotency-Key supported. See Idempotency.

Path parameters#

source_idstringrequired#
The inbound source id (src_…). Id prefix src_.

Headers#

Idempotency-Keystring#
Retry-safe writes: the same key and body replay the first response for 24 hours (Idempotent-Replayed: true). 8–128 characters.

Request body#

sourcestringrequired#
Where the request came from. One of: api, google_ads_lead_form, google_lsa, meta_lead_ad, highlevel, hubspot, jobber, service_autopilot, realgreen, sweepandgo, deeplawn, zapier, n8n, make, crm_import, other.
source_detailstring | null#
At most 200 characters.
external_refobject | null#
Your id for this request. Retrying with the same ref returns the original lead.
external_ref.systemstringrequired#
Lowercase system name, e.g. jobber, hubspot, highlevel.
external_ref.namespacestring | null#
Optional sub-namespace in that system (e.g. an account id). null or "": none. At most 120 characters.
external_ref.idstringrequired#
1–255 characters.
contactobjectrequired#
A name, and an email or a phone. null or "" in an optional field is the same as leaving it out.
contact.first_namestring | null#
At most 100 characters.
contact.last_namestring | null#
At most 100 characters.
contact.emailstring | null#
Normalized when valid. An address that is not a valid email is kept as contact.email_raw when the phone works. At most 254 characters.
contact.phonestring | null#
Any common format; normalized to E.164. A number that cannot be normalized is kept as phone_raw when the email works. At most 40 characters.
contact.phone_verifiedboolean | null#
addressobject | null#
Optional. A lead without a street address is stored (a partial address as a hint) and becomes a project when one is added.
address.line1string | null#
At most 200 characters.
address.line2string | null#
At most 200 characters.
address.citystring | null#
At most 120 characters.
address.regionstring | null#
State or region, e.g. TX. At most 120 characters.
address.postal_codestring | null#
At most 20 characters.
address.countrystring | null#
ISO 3166-1 alpha-2 in any case, or a common name ("USA", "United States"); normalized to alpha-2. Defaults to US. At most 60 characters.
address.formattedstring | null#
A one-line address, when components are not available. At most 500 characters.
address.latnumber | null#
-90–90.
address.lngnumber | null#
-180–180.
address.place_idstring | null#
Google place id, when known (best dedupe key). At most 300 characters.
service_intereststring | null#
One of christmas_lights, permanent_lighting, landscape_lighting, custom; other text is kept and filed as custom. At most 200 characters.
messagestring | null#
At most 5000 characters.
attributionobject | null#
utm_*, gclid, campaign ids and similar.
custom_fieldsobject | null#
submitted_attimestamp | null#
RFC 3339 date-time with offset.
is_testboolean | null#
Live keys reject true (use a test key for test data).

Response 202#

Received (identical for new, repeat and replayed leads).

objectstringrequired#
Always receipt.
idstringrequired#
Id prefix rcpt_.
statusstringrequired#
Always received.
livemodebooleanrequired#
false for objects created with a test key.

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