---
title: "Connect links & grants"
url: https://docs.light-ai.app/partners/connect.md
canonical_url: https://docs.light-ai.app/partners/connect
last_updated: 2026-10-13
summary: "Create single-use connect links, handle the redirect, confirm unbound grants and manage grant states."
api_status: beta
related:
  - https://docs.light-ai.app/partners
  - https://docs.light-ai.app/api-reference/partners/create-connect-link
  - https://docs.light-ai.app/api-reference/partners/list-partner-grants
---

# Connect links & grants

> Create single-use connect links, handle the redirect, confirm unbound grants and manage grant states.

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/partner/connect_links" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "scopes": [
    "leads:read",
    "leads:write",
    "clients:read",
    "projects:read",
    "quotes:read",
    "quotes:write",
    "events:read"
  ],
  "client_label": "Frosty Lights LLC",
  "external_reference": "ghl-location-7Qx2",
  "redirect_uri": "https://app.partner.example/light-ai/connected"
}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/partner/connect_links', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "scopes": [
      "leads:read",
      "leads:write",
      "clients:read",
      "projects:read",
      "quotes:read",
      "quotes:write",
      "events:read"
    ],
    "client_label": "Frosty Lights LLC",
    "external_reference": "ghl-location-7Qx2",
    "redirect_uri": "https://app.partner.example/light-ai/connected"
  }),
});
const data = await response.json();
```

Python:

```python
import os, uuid, requests

response = requests.post(
    "https://api.light-ai.app/v1/partner/connect_links",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "scopes": [
            "leads:read",
            "leads:write",
            "clients:read",
            "projects:read",
            "quotes:read",
            "quotes:write",
            "events:read"
        ],
        "client_label": "Frosty Lights LLC",
        "external_reference": "ghl-location-7Qx2",
        "redirect_uri": "https://app.partner.example/light-ai/connected"
    },
)
data = response.json()
```

- The `url` is returned only in this response (and on an `Idempotency-Key` replay). Never e-mail API keys; send connect links.
- **Bound** link: pass `organization` (`org_…`) when you already know it. **Unbound** link: `client_label` is required and the grant waits for your confirmation.
- `expires_in_hours`: 1–168 (default 7 days). Live partner keys only.
- `redirect_uri` must be HTTPS on your verified domain. Light AI appends `connect_link`, `grant`, `organization` and `grant_status` (`active` or `pending`) and keeps your own query parameters.

## Grant states

| Status | Meaning |
| --- | --- |
| `pending` | Approved through an unbound link; waiting for your confirm or decline. |
| `active` | Data flows (while the contractor is on Pro). |
| `suspended` | Temporarily carrying no data (for example the contractor dropped below Pro). |
| `superseded` | Replaced by a new grant after the contractor re-consented with new scopes (`replaces_grant_id`). |
| `revoked` | The contractor disconnected you. |
| `expired` | The grant expired. |

## Confirm or decline

curl:

```bash
curl -X POST "https://api.light-ai.app/v1/partner/grants/grant_…/confirm" \
  -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/partner/grants/grant_…/confirm', {
  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/partner/grants/grant_…/confirm",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
    json={},
)
data = response.json()
```

Decline a pending grant that reached the wrong organization with `/decline`. Revoke an unused link with `POST /v1/partner/connect_links/{id}/revoke`.

## Your reference

curl:

```bash
curl -X PATCH "https://api.light-ai.app/v1/partner/grants/grant_…" \
  -H "Authorization: Bearer $LIGHT_AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "external_reference": "ghl-location-7Qx2",
  "metadata": {
    "plan": "agency-gold"
  }
}'
```

JavaScript:

```javascript
const response = await fetch('https://api.light-ai.app/v1/partner/grants/grant_…', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.LIGHT_AI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "external_reference": "ghl-location-7Qx2",
    "metadata": {
      "plan": "agency-gold"
    }
  }),
});
const data = await response.json();
```

Python:

```python
import os, requests

response = requests.patch(
    "https://api.light-ai.app/v1/partner/grants/grant_…",
    headers={
        "Authorization": f"Bearer {os.environ['LIGHT_AI_API_KEY']}",
    },
    json={
        "external_reference": "ghl-location-7Qx2",
        "metadata": {
            "plan": "agency-gold"
        }
    },
)
data = response.json()
```

`external_reference` and `metadata` are echoed in every event of that organization.
