---
title: "Quickstart"
url: https://docs.light-ai.app/quickstart.md
canonical_url: https://docs.light-ai.app/quickstart
last_updated: 2026-10-13
summary: "Create a test key, send your first lead, and receive your first signed webhook."
api_status: beta
related:
  - https://docs.light-ai.app/authentication
  - https://docs.light-ai.app/test-mode
  - https://docs.light-ai.app/webhooks
  - https://docs.light-ai.app/webhooks/verify
---

# Quickstart

> Create a test key, send your first lead, and receive your first signed webhook.

> **Note:** You need an organization on **Pro** or **Enterprise** (or a Pro trial), and you must be its owner (or an admin the owner allowed). Test keys never touch real customers, send no e-mails and spend no credits.

## 1. Create a test key

In Light AI open **Settings → Developers → API keys** and create a key with the **Integration partner** preset. Choose **Test**. The key (`lai_test_…`) is shown once: store it in your secret manager.

```bash
export LIGHT_AI_API_KEY="lai_test_…"
```

## 2. Check the key

`GET /v1/me` returns the organization, the key's effective scopes and its limits.

curl:

```bash
curl "https://api.light-ai.app/v1/me" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY"
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/me', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
  },
});
const data = await response.json();
```

Python:

```python
import os, requests

response = requests.get(
    "https://api.light-ai.app/v1/me",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
)
data = response.json()
```

## 3. Send a lead

A lead needs a name and an e-mail or phone. Add an address so Light AI can create the project. Send an `Idempotency-Key` so a retry never creates a second lead.

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/leads" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "source": "api",
  "contact": {
    "first_name": "Dana",
    "last_name": "Reyes",
    "email": "dana@example.com",
    "phone": "+1 512 555 0134"
  },
  "address": {
    "line1": "4102 Oak Hollow Dr",
    "city": "Austin",
    "region": "TX",
    "postal_code": "78731",
    "country": "US"
  },
  "service_interest": "christmas_lights",
  "message": "Roofline and the two front trees, warm white.",
  "external_ref": {
    "system": "mycrm",
    "id": "lead-1001"
  }
}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/leads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "source": "api",
    "contact": {
      "first_name": "Dana",
      "last_name": "Reyes",
      "email": "dana@example.com",
      "phone": "+1 512 555 0134"
    },
    "address": {
      "line1": "4102 Oak Hollow Dr",
      "city": "Austin",
      "region": "TX",
      "postal_code": "78731",
      "country": "US"
    },
    "service_interest": "christmas_lights",
    "message": "Roofline and the two front trees, warm white.",
    "external_ref": {
      "system": "mycrm",
      "id": "lead-1001"
    }
  }),
});
const data = await response.json();
```

Python:

```python
import os, uuid, requests

response = requests.post(
    "https://api.light-ai.app/v1/leads",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "source": "api",
        "contact": {
            "first_name": "Dana",
            "last_name": "Reyes",
            "email": "dana@example.com",
            "phone": "+1 512 555 0134"
        },
        "address": {
            "line1": "4102 Oak Hollow Dr",
            "city": "Austin",
            "region": "TX",
            "postal_code": "78731",
            "country": "US"
        },
        "service_interest": "christmas_lights",
        "message": "Roofline and the two front trees, warm white.",
        "external_ref": {
            "system": "mycrm",
            "id": "lead-1001"
        }
    },
)
data = response.json()
```

The answer is `201` with the lead (`lead_…`) and its project (`prj_…`). The same address and service again becomes a **touch** on the open lead (`200`), and the same `external_ref` replays the original lead.

## 4. Receive a webhook

Point an endpoint at a public HTTPS URL (for a quick look, a request-bin service works). Create it in **Settings → Developers → Webhooks**, or with a key that holds the opt-in `webhooks:manage` scope:

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/webhook_endpoints" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://hooks.example.com/light-ai",
  "events": [
    "lead.created",
    "quote.published",
    "quote.approved",
    "quote.declined"
  ]
}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/webhook_endpoints', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "url": "https://hooks.example.com/light-ai",
    "events": [
      "lead.created",
      "quote.published",
      "quote.approved",
      "quote.declined"
    ]
  }),
});
const data = await response.json();
```

Python:

```python
import os, uuid, requests

response = requests.post(
    "https://api.light-ai.app/v1/webhook_endpoints",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "url": "https://hooks.example.com/light-ai",
        "events": [
            "lead.created",
            "quote.published",
            "quote.approved",
            "quote.declined"
        ]
    },
)
data = response.json()
```

Save the `secret` (`whsec_…`): it is returned once. Send a `ping` to check delivery, then [verify the signature](https://docs.light-ai.app/webhooks/verify) on every request you receive.

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/webhook_endpoints/we_…/test" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/webhook_endpoints/we_…/test', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});
const data = await response.json();
```

Python:

```python
import os, requests

response = requests.post(
    "https://api.light-ai.app/v1/webhook_endpoints/we_…/test",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
    json={},
)
data = response.json()
```

## 5. Simulate a quote

Test mode can play the homeowner. Publish a test quote for your test lead, then approve it: your endpoint receives `quote.published` and `quote.approved` exactly as in live mode.

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/test_helpers/leads/lead_…/publish_quote" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/test_helpers/leads/lead_…/publish_quote', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});
const data = await response.json();
```

Python:

```python
import os, requests

response = requests.post(
    "https://api.light-ai.app/v1/test_helpers/leads/lead_…/publish_quote",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
    json={},
)
data = response.json()
```

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/test_helpers/leads/lead_…/approve_quote" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/test_helpers/leads/lead_…/approve_quote', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});
const data = await response.json();
```

Python:

```python
import os, requests

response = requests.post(
    "https://api.light-ai.app/v1/test_helpers/leads/lead_…/approve_quote",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
    json={},
)
data = response.json()
```

## 6. Go live

Create a **Live** key (`lai_live_…`) with only the scopes you need, and a live endpoint. Live and test objects never mix: a test key cannot read live data and the other way around.

## Next

- [Inbound leads](https://docs.light-ai.app/inbound.md): Connect ad forms and CRMs without writing code.
- [Verify webhooks](https://docs.light-ai.app/webhooks/verify.md): Node.js, Python and n8n snippets.
- [Pagination & sync](https://docs.light-ai.app/pagination.md): Initial sync and gapless polling.
