---
title: "Retrieve a project"
url: https://docs.light-ai.app/api-reference/projects/get-project.md
canonical_url: https://docs.light-ai.app/api-reference/projects/get-project
last_updated: 2026-10-13
summary: "GET /v1/projects/{project_id}: Retrieve a project"
api_status: beta
related:
  - https://docs.light-ai.app/api-reference/projects
---

# Retrieve a project

> GET /v1/projects/{project_id}: Retrieve a project

`GET /v1/projects/{project_id}`

|   |   |
| --- | --- |
| Scope | `projects:read` |
| Credential | API key: `Authorization: Bearer lai_live_…` (or `lai_test_…`). Partner keys add `Light-AI-Organization`. |
| Test mode | Works with test keys against simulated test objects. |

## Path parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | string | yes | The project id (`prj_…`). Id prefix `prj_`. |

## Headers

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `Light-AI-Organization` | string |  | Partner keys: the connected organization to act for (`org_…`). Organization keys may omit it. Id prefix `org_`. |
| `Light-AI-Version` | string |  | Pin a dated API version (defaults to the key's version). One of: `2026-11-01`. |

## Response 200

The project.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Id prefix `prj_`. |
| `object` | string | yes | Always `project`. |
| `livemode` | boolean | yes | false for objects created with a test key. |
| `name` | string \| null | yes |  |
| `status` | string | yes | One of: `intake`, `measuring`, `mockup`, `quote`, `approved`, `completed`, `archived`. |
| `pipeline_stage` | string \| null | yes | The pipeline column; null for an archived project. One of: `request`, `quote_drafted`, `quote_sent`, `approved`, `completed`, `closed_lost`. |
| `client_id` | string \| null | yes | Id prefix `cli_`. |
| `property_id` | string \| null | yes | Id prefix `prop_`. |
| `lead` | object \| null | yes |  |
| `lead.id` | string | yes | Id prefix `lead_`. |
| `lead.source` | string \| null | yes | One of: `website_widget`, `api`, `google_ads_lead_form`, `google_lsa`, `meta_lead_ad`, `highlevel`, `hubspot`, `jobber`, `service_autopilot`, `realgreen`, `sweepandgo`, `deeplawn`, `zapier`, `n8n`, `make`, `crm_import`, `other`, `manual`. |
| `lead.external_refs` | object[] | yes |  |
| `lead.external_refs[].system` | string | yes |  |
| `lead.external_refs[].namespace` | string \| null | yes |  |
| `lead.external_refs[].id` | string | yes |  |
| `lead.external_refs[].owner` | string | yes | `self`: written by your integration (editable); others are read-only. One of: `self`, `organization`, `partner`. |
| `lead.external_refs[].read_only` | boolean | yes |  |
| `assigned_rep` | object \| null | yes |  |
| `assigned_rep.id` | string | yes |  |
| `assigned_rep.name` | string \| null | yes |  |
| `assigned_rep.email` | string \| null | yes |  |
| `lighting_type` | string \| null | yes |  |
| `notes` | string \| null | yes |  |
| `current_quote_id` | string \| null | yes | Id prefix `qt_`. |
| `request_offer` | object \| null |  | The offer of the website request this project came from, as the request kept it (the same object as lead.offer); null otherwise. The quote builder pre-fills the quote discount from it once; the published quote shows it as `discount.label`. |
| `request_offer.template` | string \| null |  | The Light AI campaign template that filled the offer; null or absent for the contractor's own. One of: `classic`, `early_bird`, `black_friday`, `last_chance`. |
| `request_offer.headline` | string | yes |  |
| `request_offer.discount_type` | string | yes | One of: `percent`, `amount`. |
| `request_offer.discount_percent` | integer \| null | yes |  |
| `request_offer.discount_amount` | integer \| null | yes |  |
| `request_offer.label` | string | yes |  |
| `request_offer.ends_at` | string \| null | yes |  |
| `request_offer.book_by` | string \| null | yes |  |
| `request_offer.captured_at` | string \| null | yes |  |
| `estimated_value` | Money \| null | yes |  |
| `external_refs` | object[] | yes |  |
| `external_refs[].system` | string | yes |  |
| `external_refs[].namespace` | string \| null | yes |  |
| `external_refs[].id` | string | yes |  |
| `external_refs[].owner` | string | yes | `self`: written by your integration (editable); others are read-only. One of: `self`, `organization`, `partner`. |
| `external_refs[].read_only` | boolean | yes |  |
| `app_url` | string \| null | yes |  |
| `created_at` | timestamp | yes | RFC 3339 timestamp (UTC, milliseconds). |
| `updated_at` | timestamp | yes | Last change of the project or of what the API derives for it (pipeline_stage, current_quote_id): updated_since sees a decline or a republish. |
| `fixture` | boolean |  | Always `true`. |

## Errors

| Status | Meaning |
| --- | --- |
| `400` | Bad request. [`bad_request`](https://docs.light-ai.app/errors#bad_request), [`test_mode_mismatch`](https://docs.light-ai.app/errors#test_mode_mismatch), [`test_mode_unsupported`](https://docs.light-ai.app/errors#test_mode_unsupported), [`unsupported_api_version`](https://docs.light-ai.app/errors#unsupported_api_version) |
| `401` | Missing or invalid credential. [`authentication_required`](https://docs.light-ai.app/errors#authentication_required), [`invalid_api_key`](https://docs.light-ai.app/errors#invalid_api_key), [`api_key_revoked`](https://docs.light-ai.app/errors#api_key_revoked), [`api_key_expired`](https://docs.light-ai.app/errors#api_key_expired), [`api_key_suspended`](https://docs.light-ai.app/errors#api_key_suspended) |
| `403` | Not allowed. [`insufficient_scope`](https://docs.light-ai.app/errors#insufficient_scope), [`plan_upgrade_required`](https://docs.light-ai.app/errors#plan_upgrade_required), [`organization_paused`](https://docs.light-ai.app/errors#organization_paused), [`organization_off_season`](https://docs.light-ai.app/errors#organization_off_season), [`api_disabled`](https://docs.light-ai.app/errors#api_disabled), [`api_access_not_enabled`](https://docs.light-ai.app/errors#api_access_not_enabled), [`ip_not_allowed`](https://docs.light-ai.app/errors#ip_not_allowed), [`forbidden`](https://docs.light-ai.app/errors#forbidden) |
| `404` | Not found (also for objects of other organizations and for organizations without an active grant). |
| `422` | Validation failed. [`idempotency_key_reused`](https://docs.light-ai.app/errors#idempotency_key_reused) |
| `429` | Rate limited or daily cap reached. See Retry-After and the RateLimit headers. [`rate_limited`](https://docs.light-ai.app/errors#rate_limited), [`daily_cap_reached`](https://docs.light-ai.app/errors#daily_cap_reached) |
| `500` | Unexpected server error. Safe to retry with exponential backoff; quote the Request-Id to support. [`internal_error`](https://docs.light-ai.app/errors#internal_error) |
| `503` | Temporarily unavailable. Retry with exponential backoff. [`service_unavailable`](https://docs.light-ai.app/errors#service_unavailable) |

## Examples

**Request**

curl:

```bash
curl -X GET "https://api.light-ai.app/v1/projects/{project_id}" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY"
```

JavaScript:

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

Python:

```python
import os, uuid, requests

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

**Response 200**

```json
{
  "id": "prj_3f9c2a7be41d…",
  "object": "project",
  "livemode": false,
  "name": "Dana Reyes",
  "status": "intake",
  "pipeline_stage": "request",
  "client_id": "cli_3f9c2a7be41d…",
  "property_id": "prop_3f9c2a7be41d…",
  "lead": {
    "id": "lead_3f9c2a7be41d…",
    "source": "website_widget",
    "external_refs": [
      {
        "system": "string",
        "namespace": "string",
        "id": "string",
        "owner": "self",
        "read_only": true
      }
    ]
  },
  "assigned_rep": {
    "id": "string",
    "name": "Dana Reyes",
    "email": "dana@example.com"
  },
  "lighting_type": "string",
  "notes": "string",
  "current_quote_id": "qt_3f9c2a7be41d…",
  "request_offer": {
    "template": "black_friday",
    "headline": "Black Friday: 20% off installs",
    "discount_type": "percent",
    "discount_percent": 20,
    "discount_amount": null,
    "label": "20% off",
    "ends_at": "2026-11-30T05:59:00Z",
    "book_by": "Book by Dec 1 for install before Christmas",
    "captured_at": "2026-11-27T14:03:11Z"
  },
  "estimated_value": {
    "cents": 245000,
    "decimal": "2450.00",
    "currency": "USD"
  },
  "external_refs": [
    {
      "system": "string",
      "namespace": "string",
      "id": "string",
      "owner": "self",
      "read_only": true
    }
  ],
  "app_url": "https://example.com/…",
  "created_at": "2026-10-12T14:03:11.000Z",
  "updated_at": "2026-10-12T14:03:11.000Z",
  "fixture": true
}
```
