---
title: "Test mode"
url: https://docs.light-ai.app/test-mode.md
canonical_url: https://docs.light-ai.app/test-mode
last_updated: 2026-10-13
summary: "Test keys work against isolated test objects, simulate the homeowner, never e-mail anyone and never spend credits."
api_status: beta
related:
  - https://docs.light-ai.app/quickstart
  - https://docs.light-ai.app/authentication
  - https://docs.light-ai.app/mockups
---

# Test mode

> Test keys work against isolated test objects, simulate the homeowner, never e-mail anyone and never spend credits.

A `lai_test_…` key runs the same contract as a live key against separate test objects (`livemode: false`). Test objects are kept for 7 days.

|  | Test keys |
| --- | --- |
| Leads, clients, projects | Created and read as test objects; never visible in the contractor's app. |
| Quotes | Publish one for a test lead with `POST /v1/test_helpers/leads/{lead_id}/publish_quote`, optionally from your own `document`. |
| Homeowner actions | `view_quote`, `click_external_link`, `approve_quote`, `decline_quote` emit the real events. |
| Webhooks | Delivered to test endpoints only. 30 test sends an hour and 500 test deliveries a day per organization. |
| Mockups | Simulated: a finished generation with a sample image, no credits. |
| Inbound sources | Google Ads "Send test data" (`is_test`) runs in test mode. |
| Partner connect links | Live keys only (`test_mode_unsupported`). |

Each reference page states how the endpoint behaves for test keys. Mixing modes (a test key on a live object id) answers 400 `test_mode_mismatch` or 404.

## Simulate a homeowner

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()
```

Then call `view_quote`, `click_external_link`, `approve_quote` or `decline_quote` on the same lead. Each step emits the event a real homeowner would cause (`quote.viewed`, `quote.external_link_clicked`, `quote.approved`, `quote.declined`).
