Layers

GET /v1/projects/:projectId/events

Query the SDK event stream — filtered, paginated, PII-redacted by default.

View as Markdown
GET/v1/projects/:projectId/events
Phase 1stable
Auth
Bearer
Scope
events:read

Returns events the client SDK posted to in.layers.com/l/events, in reverse-chronological order. Use it to render a live activity feed, debug SDK wiring during install, or export raw telemetry into your own warehouse.

Identifiers that could reveal a user — email, phone, ip, and common PII property keys — are redacted to "[redacted]" by default. Create the key with the events:read+pii sub-scope and Layers returns the raw values. Keys without that sub-scope cannot opt in per-request.

Path
  • projectId
    stringrequired
    Project ID.
Query
  • appId
    stringoptional
    Filter to a single SDK app.
  • eventNames
    string[]optional
    Comma-separated event names (e.g. `purchase_success,add_to_cart`). Omitted = all events.
  • userId
    stringoptional
    Filter to a single `app_user_id`.
  • since
    string (ISO-8601)optional
    Inclusive lower bound on `occurred_at`.
  • until
    string (ISO-8601)optional
    Exclusive upper bound on `occurred_at`.
  • cursor
    stringoptional
    Opaque pagination token.
  • limit
    integeroptionaldefault: 50
    Page size, 1–200.

Example request

curl "https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/events?eventNames=purchase_success&since=2026-04-18T00:00:00Z&limit=25" \
  -H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."
const { items, nextCursor } = await layers.events.list(
  "prj_01HX9Y7K8M2P4RSTUV56789AB",
  {
    eventNames: ["purchase_success"],
    since: "2026-04-18T00:00:00Z",
    limit: 25,
  }
);
result = layers.events.list(
    project_id="prj_01HX9Y7K8M2P4RSTUV56789AB",
    event_names=["purchase_success"],
    since="2026-04-18T00:00:00Z",
    limit=25,
)

Response

receivedAt currently mirrors occurredAt (single-timestamp storage). A future schema bump will track ingest receipt independently for client-skew debugging. Today, treating either field interchangeably is safe.

200OK
{
  "items": [
    {
      "eventId": "evt_01HXA9Z2R3S4T5U6V7W8X9Y0A",
      "appId": "sdk_01HXA1NPQR5TVWXYZABCDEFGH",
      "userId": "user_a7f3c1d9",
      "eventName": "purchase_success",
      "occurredAt": "2026-04-18T19:42:08.214Z",
      "receivedAt": "2026-04-18T19:42:08.214Z",
      "platform": "ios",
      "sdkVersion": "1.4.0",
      "properties": {
        "order_id": "order_81422",
        "value": 18.5,
        "currency": "USD",
        "items": [{ "sku": "latte-12oz", "qty": 2 }]
      },
      "identity": {
        "email": "[redacted]",
        "phone": "[redacted]",
        "ip": "[redacted]"
      }
    }
  ],
  "nextCursor": "evt_01HXA9Z1QPONM..."
}

Errors

StatusCodeWhen
422VALIDATIONBad since/until, unknown appId, invalid cursor.
401UNAUTHENTICATEDMissing or invalid key.
403FORBIDDEN_SCOPEKey lacks events:read.
404NOT_FOUNDProject does not exist.
429RATE_LIMITEDRead budget exhausted.

See also

On this page