---
title: "Authentication & API keys"
url: https://docs.light-ai.app/authentication.md
canonical_url: https://docs.light-ai.app/authentication
last_updated: 2026-10-13
summary: "Bearer API keys for live and test mode, scopes, rotation, and who can create them. API access is a Pro feature."
api_status: beta
related:
  - https://docs.light-ai.app/test-mode
  - https://docs.light-ai.app/partners
  - https://docs.light-ai.app/errors
  - https://docs.light-ai.app/rate-limits
---

# Authentication & API keys

> Bearer API keys for live and test mode, scopes, rotation, and who can create them. API access is a Pro feature.

Send the key in the `Authorization` header on every request. Keys never go in query strings.

```http
GET /v1/me HTTP/1.1
Host: api.light-ai.app
Authorization: Bearer lai_live_…
```

## Who has access

API access is included on **Pro** (Pro, Enterprise and Pro trials). Free and Plus have no API access: no keys, no test mode, no webhooks and no inbound sources.

- Off-Season keeps API reads and new leads (`POST /v1/leads`, inbound sources) when the home plan is Pro or Enterprise; every other write answers 403 `organization_off_season` until the owner resumes the plan.
- A paused organization is read-only: writes answer 403 `organization_paused` and inbound leads are held until it resumes.
- A downgrade below Pro **suspends** (never deletes) every key, inbound source, webhook endpoint and partner grant, right after an `organization.entitlement_changed` event. An upgrade back to Pro restores them.
- There is nothing to request: every Pro and Enterprise organization can create keys in Settings → Developers.

## Key types

| Prefix | What it is | Created in |
| --- | --- | --- |
| `lai_live_…` | Live organization key: real data. | Settings → Developers (owner) |
| `lai_test_…` | Test organization key: isolated test objects, no e-mails, no credits. See [Test mode](https://docs.light-ai.app/test-mode). | Settings → Developers (owner) |
| `lai_live_…` / `lai_test_…` of a partner | Partner key: acts for connected contractors with `Light-AI-Organization: org_…`. See [Partners](https://docs.light-ai.app/partners). | Partner console (second factor required) |
| `lai_whin_…` | Inbound source secret: can only send leads in. See [Inbound leads](https://docs.light-ai.app/inbound). | Settings → Developers → Inbound |
| `whsec_…` | Webhook signing secret (not an API key). | Returned when an endpoint is created |

Keys carry a checksum, so a mistyped key fails fast with 401 `invalid_api_key`, and secret scanners can recognize a leaked one.

## Creating keys

- The **owner** (or an admin the owner allowed) creates and rolls keys after a recent sign-in (step-up, with MFA when enabled). Revoking needs no re-sign-in.
- Choose scopes (presets: Integration partner, Lead intake only, Read only), an expiry (30 days, 90 days, 1 year or never; partner keys 30–90 days) and optionally up to 20 allowed IP ranges.
- The key is shown **once**. Light AI stores only a hash and the last four characters.
- At most 25 active keys per organization. Owners get an e-mail for every new key.

## Scopes

A key can do only what its scopes allow (for partner keys: key ∩ grant ∩ plan). `GET /v1/me` lists the effective scopes. A missing scope answers 403 `insufficient_scope`.

| Scope | Allows |
| --- | --- |
| `leads:read` | Read leads and touches (names, e-mails, phones, addresses). |
| `leads:write` | Create and update leads. Without `leads:read` every answer is a receipt. |
| `clients:read` / `clients:write` | Read clients and properties / create, update and add properties. |
| `projects:read` / `projects:write` | Read projects and pipeline totals / move a project between stages. |
| `quotes:read` | Read published quotes, line items, totals, assets and timelines. Internal team comments and review notes on a quote are never returned by the API, MCP tools or webhooks. |
| `quotes:write` | Record approvals and declines made outside Light AI. |
| `quotes:share_link` | **Opt-in.** Receive the homeowner quote link (`customer_url`). Anyone holding it can view and approve the quote. |
| `quotes:asset_links` | **Opt-in.** Receive long-lived image links (up to 30 days). |
| `mockups:read` / `mockups:write` | Read generations / generate mockups with the contractor's credits. `mockups:write` is never in a preset. |
| `forms:read` | Read website request forms, their install snippets, settings and this month's preview use. See [Website request forms](https://docs.light-ai.app/forms). |
| `forms:write` | **Opt-in.** Pause, resume and adjust a website request form, including its instant preview spending. Owners are e-mailed when the websites change or previews are turned on. |
| `webhooks:manage` | **Opt-in.** Create and manage webhook endpoints through the API. Owners are e-mailed for each one. |
| `events:read` | Read the events feed. |

## Rotation

**Roll** a key to get a new secret while the old one keeps working for a grace period you choose (immediately, 1 hour, 24 hours or 7 days). Expiring keys trigger `api_key.expiring` 14 and 3 days ahead. Revoked, expired and suspended keys answer 401 `api_key_revoked`, `api_key_expired` or `api_key_suspended`.

## Headers

| Header | Use |
| --- | --- |
| `Authorization` | `Bearer <key>`. Required on every route except `/v1/status`, the inbound receivers (which take a source secret) and image links (`/a/…`). |
| `Light-AI-Organization` | Partner keys: the connected organization (`org_…`) to act for. |
| `Light-AI-Version` | Pin an API version (default: the key's version, `2026-11-01`). |
| `Idempotency-Key` | Safe retries for writes. See [Idempotency](https://docs.light-ai.app/idempotency). |
| `Request-Id` (response) | Unique per request. Include it when you contact support. |
