# GET /v1/projects/:projectId/ads/capi-status (/docs/api/reference/ads/capi-status)



<Endpoint method="GET" path="/v1/projects/{projectId}/ads/capi-status" auth="Bearer" scope="ads:read" phase="1" />

Returns the configured state of Layers' Conversions API relay for a project: which platforms are configured, whether a pixel and an access token are present, and any recent error captured on the layer config. Use this endpoint to confirm the relay is wired up before you start firing SDK events.

Configuration itself lives on the Meta Ads Manager / TikTok Ads Manager project layer (`config.capi`) and is provisioned via the Layers dashboard. This endpoint is a read-only health view derived from those rows.

<Parameters
  title="Path"
  rows="[
  { name: 'projectId', type: 'string (UUID)', required: true, description: 'Project to report on.' },
]"
/>

<Parameters
  title="Query"
  rows="[
  { name: 'platforms', type: 'string[]', description: 'Restrict to one or more platforms. Returns all by default.', enum: ['meta_ads', 'tiktok_ads'] },
]"
/>

## Example request [#example-request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```bash
    curl "https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/ads/capi-status" \
      -H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    const res = await fetch(
      `https://api.layers.com/v1/projects/${projectId}/ads/capi-status`,
      { headers: { Authorization: `Bearer ${apiKey}` } },
    );
    const { platforms } = await res.json();

    const unhealthy = platforms.filter((p) => p.status !== "healthy");
    if (unhealthy.length) {
      console.warn("CAPI issues:", unhealthy);
    }
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import httpx

    r = httpx.get(
        f"https://api.layers.com/v1/projects/{project_id}/ads/capi-status",
        headers={"Authorization": f"Bearer {api_key}"},
    )
    payload = r.json()
    ```
  </Tab>
</Tabs>

## Response [#response]

<Response status="200" description="OK">
  ```json
  {
    "projectId": "prj_01HX9Y7K8M2P4RSTUV56789AB",
    "platforms": [
      {
        "platform": "meta_ads",
        "enabled": true,
        "status": "healthy",
        "pixelId": "123456789012345",
        "accessTokenValid": true,
        "accessTokenLastValidatedAt": "2026-04-18T18:00:00Z",
        "eventsLast1h": null,
        "eventsLast24h": null,
        "lastEventAt": null,
        "lastError": null
      },
      {
        "platform": "tiktok_ads",
        "enabled": true,
        "status": "degraded",
        "pixelId": "C4A9P2Q7R5S8T1U6",
        "accessTokenValid": true,
        "accessTokenLastValidatedAt": "2026-04-18T18:00:00Z",
        "eventsLast1h": null,
        "eventsLast24h": null,
        "lastEventAt": null,
        "lastError": {
          "at": "2026-04-18T19:21:12Z",
          "code": "PLATFORM_ERROR",
          "message": "TikTok Events API rate-limit (429). Backing off 60s.",
          "platformCode": 40002
        }
      }
    ]
  }
  ```
</Response>

<Response status="404" description="Project does not exist in your organization." />

## Status values [#status-values]

| Status     | Meaning                                                                                                                                  |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `healthy`  | Token valid, events flowing, no errors in the last hour.                                                                                 |
| `idle`     | Token valid and configured, but no events received in over an hour. Common if the app has no live traffic — not automatically a problem. |
| `degraded` | Token valid but recent forwards failed. See `lastError`. Usually transient (rate limits, platform hiccups).                              |
| `broken`   | Token invalid or pixel misconfigured. Events are being stored but not forwarded. Requires reconnection.                                  |
| `disabled` | CAPI is turned off in the layer config. Nothing is being forwarded by design.                                                            |

## What CAPI actually does [#what-capi-actually-does]

Layers' SDK captures client events and batches them to the ingest pipeline. For each configured platform, the relay looks up the project's pixel and access token, maps event names (`purchase_success` → Meta `layers_purchase_success`, TikTok `Purchase`), decrypts the vault-stored token, and forwards the event. Events are always stored in `sdk_events` whether or not the relay succeeds — CAPI failures don't drop telemetry. See the [SDK event pipeline](/docs/api/concepts/content-items) concept page for the full flow.

## Notes [#notes]

* `eventsLast1h`, `eventsLast24h`, and `lastEventAt` are reserved for a future relay-volume rollup. They are always `null` in Phase 1 — counting forwarded events on every health-poll would scan `sdk_events` on a hot path. For now, attribution-flow health is derived from the layer config (`enabled`, `pixelId`, `accessTokenValid`, `lastError`).
* `lastError` is the most recent forward failure recorded on the layer config. For the full audit trail, query [`/v1/audit`](/docs/api/reference/audit-log/list) with `subjectType=capi_forward`.
* `platformCode` is the raw code the platform returned (Meta error code, TikTok `code`). Treat Layers' own `error.code` as stable; the platform code is passthrough.
* `accessTokenValid` and `tokenStatus` on [`/ads/ad-accounts`](/docs/api/reference/ads/list-ad-accounts) are independent. An ad account can have a valid OAuth token for placements while its system-user access token for CAPI has expired. Check both.
* `meta_ads` and `tiktok_ads` CAPI are supported. Apple Search Ads uses a different attribution model; there is no CAPI to report on.

## See also [#see-also]

* [`GET /v1/projects/:projectId/ads/ad-accounts`](/docs/api/reference/ads/list-ad-accounts) — ad account credential health
* [SDK event pipeline](/docs/api/concepts/content-items) — how events flow and where CAPI fits
