# GET /v1/credits/events (/docs/api/reference/credits/list-events)



<Endpoint method="GET" path="/v1/credits/events" auth="Bearer" phase="1" />

Returns one row per wallet movement. Use this to attribute spend by project, reconcile your own counter against ours, or build a credit-usage dashboard.

`GET /v1/credits` gives you the wallet snapshot; `/v1/credits/events` gives you the audit trail. They complement each other — the snapshot is the answer to "how much do I have right now?", events are the answer to "what happened?"

## Query parameters [#query-parameters]

<Parameters
  rows="[
  { name: 'projectId', type: 'string', description: 'Filter to events attributed to one project. `null`-projectId events (grants, purchases, admin adjustments) are excluded when this filter is set.' },
  { name: 'eventType', type: 'string', enum: ['usage', 'refund', 'grant', 'purchase', 'adjustment', 'allocation'], description: 'Filter to one event type. See &#x22;Event types&#x22; below.' },
  { name: 'since', type: 'string (ISO 8601 Z)', description: 'Only events `>= since`. UTC required (Z suffix).' },
  { name: 'until', type: 'string (ISO 8601 Z)', description: 'Only events `<= until`. UTC required (Z suffix).' },
  { name: 'cursor', type: 'string', description: 'Opaque cursor from the previous page.' },
  { name: 'limit', type: 'integer', default: '25', description: 'Page size, 1-100.' },
]"
/>

## Example request [#example-request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```bash
    curl "https://api.layers.com/v1/credits/events?projectId=prj_13fd8406-387a-4472-b6a2-531860557a6e&eventType=usage" \
      -H "Authorization: Bearer $LAYERS_API_KEY"
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts
    const url = new URL("https://api.layers.com/v1/credits/events");
    url.searchParams.set("projectId", "prj_13fd8406-387a-4472-b6a2-531860557a6e");
    url.searchParams.set("eventType", "usage");
    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${process.env.LAYERS_API_KEY}` },
    });
    const { items, nextCursor } = await res.json();
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import os, requests
    res = requests.get(
        "https://api.layers.com/v1/credits/events",
        params={"projectId": "prj_…", "eventType": "usage"},
        headers={"Authorization": f"Bearer {os.environ['LAYERS_API_KEY']}"},
    )
    data = res.json()
    ```
  </Tab>
</Tabs>

## Response [#response]

<Response status="200" description="OK">
  ```json
  {
    "items": [
      {
        "eventId": "a962df6d-2ea8-4dff-8a68-d49b1dc74d33",
        "projectId": "prj_13fd8406-387a-4472-b6a2-531860557a6e",
        "credits": -50,
        "eventType": "usage",
        "format": "slideshow-builder",
        "containerId": "cnt_a861adb5-3a48-48a4-a18d-c70129ebefa7",
        "workflowId": "partner-content-a861adb5-3a48-48a4-a18d-c70129ebefa7-v0",
        "balanceAfterPrepaid": 4200,
        "usageAfterPeriod": 3000,
        "createdAt": "2026-05-12T21:17:15.903Z"
      },
      {
        "eventId": "1133c79a-e49e-4e52-81e7-ac13ef77d72a",
        "projectId": null,
        "credits": 1000,
        "eventType": "grant",
        "format": null,
        "containerId": null,
        "workflowId": null,
        "balanceAfterPrepaid": null,
        "usageAfterPeriod": null,
        "createdAt": "2026-05-12T15:00:00.000Z"
      }
    ],
    "nextCursor": null
  }
  ```
</Response>

### Event types [#event-types]

| Type         | Sign of `credits` | When                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `usage`      | always negative   | Content-generation charge (slideshow-builder, slideshow-remix, video-remix, ugc-remix). Charged synchronously when the workflow starts rendering.                                                                                                                                                                                                                                                                                                                                                                                              |
| `refund`     | always positive   | Automatic refund when a paid generation fails post-charge, OR an admin-initiated reversal.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `grant`      | always positive   | Free credits granted by Layers — onboarding, promo, velocity bonus, manual admin grant.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `purchase`   | always positive   | Prepaid credit pack purchased via Stripe.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `adjustment` | either sign       | Admin manual adjustment. Direction is on the sign of `credits`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `allocation` | either sign       | A sub-org credit transfer between you and one of your children. On your own ledger it's **negative** when you fund a child ([allocate](/docs/api/reference/organizations/credits/allocate)) and **positive** when an archived child's unspent credits are reclaimed to you. `metadata.direction` is `allocate` or `reclaim`; `metadata.counterpartyOrgId` (`org_`-prefixed) names the child, and `metadata.transferId` (`txn_`-prefixed) matches the `id` the [allocate](/docs/api/reference/organizations/credits/allocate) response returns. |

### Field notes [#field-notes]

* `credits` is **signed** — debits negative, credits positive. Sum them for a wallet-level reconciliation.
* `projectId` is `null` for org-level events (grants, purchases, admin adjustments, allocations). When filtering by `projectId`, those rows are excluded by design.
* `format` and `containerId` populate when the event is tied to a partner-API content-generation workflow. In-app generations from the Layers dashboard also charge but don't surface a `format` / `containerId` here.
* `balanceAfterPrepaid` / `usageAfterPeriod` are reconciliation breadcrumbs — what the wallet looked like immediately after this event. `null` when the event didn't touch that side of the wallet.
* Ordered newest first, paginated via `nextCursor`. The cursor is opaque — pass it back verbatim on the next call.

### Common patterns [#common-patterns]

**Project spend this billing period:**

```bash
curl "https://api.layers.com/v1/credits/events\
?projectId=prj_…&eventType=usage&since=$(date -u +%Y-%m-01T00:00:00Z)" \
  -H "Authorization: Bearer $LAYERS_API_KEY" \
| jq '[.items[] | .credits] | add'
```

**Per-format breakdown for a project:**

```bash
curl "https://api.layers.com/v1/credits/events?projectId=prj_…&eventType=usage" \
  -H "Authorization: Bearer $LAYERS_API_KEY" \
| jq -r '.items | group_by(.format) | map({format: .[0].format, total: ([.[].credits] | add)})'
```

## Errors [#errors]

| Status | Code              | When                                                                                                                           |
| ------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 422    | `VALIDATION`      | Bad `projectId` shape, malformed timestamp (offset form like `+00:00` is rejected — `Z`-suffix UTC only), invalid `eventType`. |
| 401    | `UNAUTHENTICATED` | Missing or invalid key.                                                                                                        |
| 503    | `KILL_SWITCH`     | Key or org disabled.                                                                                                           |

## See also [#see-also]

* [GET /v1/credits](/docs/api/reference/credits/get-credits) — wallet snapshot (the answer to "how much do I have now?")
