POST /v1/projects/:projectId/sdk-apps/:appId/verify-tracking
Active probe — sends a synthetic test event tagged `test_event_code`; returns whether tracking is healthy and which platforms would forward it.
/v1/projects/:projectId/sdk-apps/:appId/verify-tracking- Auth
- Bearer
- Scope
- sdk:write
Active probe of an SDK install. Sends a synthetic test event into the ingest pipeline; returns a structured health report including per-platform CAPI dispatch confirmation.
This is the "is tracking healthy right now?" check. The probe sends a synthetic event tagged test_event_code (visible in Meta's Event Manager debugger and TikTok's Event Manager test view), waits up to 30 seconds for round-trip confirmation, and returns a structured report.
Use this for:
- A "Test connection" button in your partner dashboard.
- Post-deploy verification — fire after rolling a new SDK install.
- Customer support — a structured diagnostic better than "send me a screenshot of Meta's debugger."
For passive signals (no synthetic event), see SDK health — lastEventAt, the events list, and capi-status are the right tools when you don't want to inject a test event.
Path parameters
projectIdstring (uuid)requiredProject the SDK app belongs to.appIdstringrequiredSDK app id.
Body
expectedEventsstring[]optionalEvent names you expect the SDK to be firing. Default: `["app_open"]`. The probe checks the timeline for each in the recent past and reports any missing in `missing[]`.sampleEventNamestringoptionaldefault: "layers_test_event"Event name for the synthetic test. Pick one your team can recognize in platform debuggers.
Request
curl -X POST https://api.layers.com/v1/projects/$PROJECT_ID/sdk-apps/$APP_ID/verify-tracking \
-H "Authorization: Bearer $LAYERS_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"expectedEvents": ["app_open", "Purchase"]
}'Response
{
"status": "healthy",
"lastEventAt": "2026-05-08T17:02:11.123Z",
"expectedEvents": ["app_open", "Purchase"],
"observedEvents": ["app_open", "Purchase", "session_start"],
"missing": [],
"samples": [
{
"name": "Purchase",
"receivedAt": "2026-05-08T17:01:55.000Z",
"platforms": [
{ "platform": "meta", "forwarded": true, "fbtrace_id": "AbCDeFg..." },
{ "platform": "tiktok", "forwarded": true, "request_id": "abc123" }
]
}
],
"checks": [
{ "name": "ingest_endpoint_reachable", "passed": true },
{ "name": "app_id_recognized", "passed": true },
{ "name": "capi_meta_configured", "passed": true },
{ "name": "capi_tiktok_configured", "passed": true },
{ "name": "test_event_round_trip", "passed": true }
],
"testEventCode": "TEST123"
}{
"status": "no_install",
"lastEventAt": null,
"expectedEvents": ["app_open"],
"observedEvents": [],
"missing": ["app_open"],
"checks": [
{ "name": "ingest_endpoint_reachable", "passed": true },
{ "name": "app_id_recognized", "passed": true },
{ "name": "capi_meta_configured", "passed": false, "remedy": "Patch the SDK app's CAPI config: PATCH /v1/projects/:id/sdk-apps/:appId with capi.meta.{enabled, pixel_id, access_token_vault_id}." },
{ "name": "test_event_round_trip", "passed": false }
]
}status values
| Status | Meaning | Typical remedy |
|---|---|---|
healthy | Synthetic event arrived, expected events recently observed, all relays configured and dispatching. | None — you're done. |
missing_events | Test event arrived but one or more expectedEvents is absent from the recent timeline. | The SDK is installed but is not firing the events you expect. Check the SDK init code. |
schema_drift | Events arrive but with property shapes Meta / TikTok will reject (missing revenue on Purchase, missing currency, etc.). | Update the SDK call sites to include canonical properties. |
no_install | No events ever, or test event never arrived. | The SDK is not installed or not initialized. Walk through the install guide. |
Per-check breakdown
Every response carries checks[] regardless of status. Each check has name, passed, and (when failed) remedy — a one-line fix description.
| Check | What it confirms |
|---|---|
ingest_endpoint_reachable | Layers' ingest URL responds with 2xx. (Almost always passes — fails only during a Layers outage.) |
app_id_recognized | The appId exists in sdk_apps and is not soft-deleted. |
capi_meta_configured | If the project has a Meta CAPI config, it's complete (pixel id, vault token resolvable, enabled). Skipped if no Meta layer. |
capi_tiktok_configured | Same for TikTok. |
test_event_round_trip | The synthetic event arrived and was visible in sdk_events within the timeout. |
Probe semantics
- The probe injects a synthetic
sample_eventwithtest_event_codeset so Meta and TikTok render it in their debugger UIs only — production reporting ignores it. - The probe does NOT count against the project's daily event quota.
- Multiple concurrent probes are fine — each uses a unique
testEventCode.
Errors
| Code | When |
|---|---|
NOT_FOUND | :projectId or :appId doesn't exist in this org. |
FORBIDDEN_SCOPE | Key lacks sdk:write (or legacy projects:write). |
RATE_LIMITED | More than 10 probes per minute per app. |
See also
- SDK health concept
GET /v1/projects/:id/ads/capi-status— passive CAPI healthPATCH /v1/projects/:id/sdk-apps/:appId— wire up CAPI configPOST /v1/events— server-side event forwarding