# 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 or programmatically via [`PATCH /v1/projects/:id/sdk-apps/:appId`](/docs/api/reference/sdk-apps/patch-sdk-app) (which now writes through to the same `project_layers.config.capi` row — the relay's read path). This endpoint is a read-only health view derived from those rows.

For an active probe with synthetic test event + per-platform dispatch confirmation, use [`POST …/sdk-apps/:appId/verify-tracking`](/docs/api/reference/sdk-apps/verify-tracking). For a comparison of all four SDK-health signals, see the [SDK health concept page](/docs/api/concepts/sdk-health).

<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_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39/ads/capi-status" \
      -H "Authorization: Bearer lp_..."
    ```
  </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_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39",
    "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 recent errors.                                                                                  |
| `idle`     | Token valid and configured, but no recent events received. 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 forwards eligible conversion events to the configured ad platform. CAPI failures do not drop telemetry; they only affect platform forwarding. See the [SDK event pipeline](/docs/api/concepts/content-items) concept page for the full flow.

## Notes [#notes]

* `eventsLast1h`, `eventsLast24h`, and `lastEventAt` may be `null` when relay-volume rollups are unavailable. Use `status` and `lastError` for current health.
* `lastError` is the most recent forward failure. 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
