# GET /v1/projects/:projectId/conversions (/docs/api/reference/telemetry/conversions)



<Endpoint method="GET" path="/v1/projects/:projectId/conversions" auth="Bearer" scope="events:read" phase="1" />

Aggregates conversion events over a time window. Use it to render conversion widgets without walking the raw [event stream](/docs/api/reference/telemetry/events) and re-bucketing client-side.

Totals count every event matching the filter in the window. `groups` is present when `groupBy` is set — buckets are sparse, so zero-volume groups are omitted. `value` sums only events that carry a numeric `value` property; currency mixing is not normalized — pass a single-currency filter if you need a clean sum.

<Parameters
  title="Path"
  rows="[
  { name: 'projectId', type: 'string', required: true, description: 'Project ID.' },
]"
/>

<Parameters
  title="Query"
  rows="[
  { name: 'since', type: 'string (ISO-8601)', required: true, description: 'Inclusive lower bound on `occurred_at`.' },
  { name: 'until', type: 'string (ISO-8601)', required: true, description: 'Exclusive upper bound on `occurred_at`.' },
  { name: 'eventNames', type: 'string[]', description: 'Event names. Comma-separated (`eventNames=a,b`) or repeat the param (`eventNames=a&eventNames=b`). Defaults to the built-in conversion set: `purchase_success`, `subscribe_success`, `trial_start`.' },
  { name: 'groupBy', type: 'string[]', description: 'Bucketing dimensions. Comma-separated (`groupBy=day,eventName`) or repeat the param (`groupBy=day&groupBy=eventName`).', enum: ['platform', 'appId', 'eventName', 'day', 'hour'] },
  { name: 'appId', type: 'string', description: 'Filter to a single SDK app.' },
]"
/>

## Example request [#example-request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```bash
    curl "https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/conversions?since=2026-04-11T00:00:00Z&until=2026-04-18T00:00:00Z&groupBy=day,eventName" \
      -H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    const { totals, groups } = await layers.conversions.list(
      "prj_01HX9Y7K8M2P4RSTUV56789AB",
      {
        since: "2026-04-11T00:00:00Z",
        until: "2026-04-18T00:00:00Z",
        groupBy: ["day", "eventName"],
      }
    );
    ```
  </Tab>

  <Tab value="Python">
    ```python
    result = layers.conversions.list(
        project_id="prj_01HX9Y7K8M2P4RSTUV56789AB",
        since="2026-04-11T00:00:00Z",
        until="2026-04-18T00:00:00Z",
        group_by=["day", "eventName"],
    )
    ```
  </Tab>
</Tabs>

## Response [#response]

<Response status="200" description="OK">
  ```json
  {
    "window": {
      "since": "2026-04-11T00:00:00Z",
      "until": "2026-04-18T00:00:00Z"
    },
    "totals": {
      "count": 1284,
      "uniqueUsers": 912,
      "value": 22647.4,
      "currency": "USD"
    },
    "groups": [
      {
        "key": { "day": "2026-04-11", "eventName": "purchase_success" },
        "count": 142,
        "uniqueUsers": 131,
        "value": 2501.85
      },
      {
        "key": { "day": "2026-04-11", "eventName": "subscribe_success" },
        "count": 38,
        "uniqueUsers": 38,
        "value": 380.00
      },
      {
        "key": { "day": "2026-04-12", "eventName": "purchase_success" },
        "count": 201,
        "uniqueUsers": 185,
        "value": 3487.20
      }
    ]
  }
  ```
</Response>

## Errors [#errors]

| Status | Code              | When                                                                                 |
| ------ | ----------------- | ------------------------------------------------------------------------------------ |
| 422    | `VALIDATION`      | Missing or malformed `since`/`until`, unknown `groupBy` dimension, window > 92 days. |
| 401    | `UNAUTHENTICATED` | Missing or invalid key.                                                              |
| 403    | `FORBIDDEN_SCOPE` | Key lacks `events:read`.                                                             |
| 404    | `NOT_FOUND`       | Project does not exist.                                                              |
| 429    | `RATE_LIMITED`    | Read budget exhausted.                                                               |

## See also [#see-also]

* [`GET /v1/projects/:projectId/events`](/docs/api/reference/telemetry/events) — raw event stream
* [`GET /v1/projects/:projectId/apple-ads-attribution`](/docs/api/reference/telemetry/apple-ads-attribution) — ASA-attributed installs
