## List events

**get** `/v1/events`

Lists your brand's events, oldest first.

**Behavior**

- An event is recorded when it HAPPENS, not when it is delivered. A brand
  with no webhook endpoint still accumulates events, which is what makes
  this readable after you register one.
- Ordering is a stable total order: the event's instant paired with its
  unique id. Paging twice returns the same rows in the same places.
- Scoped to your key's brand by construction: no parameter names a brand.

### Query Parameters

- `chat_id: optional string`

  Only events for this chat. Chat events only, since a batch run is not a chat.

- `cursor: optional string`

  Resume from a previous page's `next_cursor`.

- `limit: optional number`

  Page size; absent or outside 1–100 reads as 100.

- `since: optional string`

  Only events at or after this RFC3339 instant. A value that is not a timestamp is refused, never ignored.

- `type: optional string`

  Only this event type.

### Returns

- `data: array of Event`

  - `id: string`

    Stable id, `evt_…`. Unique for the life of the event.

  - `created_at: string`

    When the event happened. For a chat event this is the instant the chat recorded it.

  - `data: unknown`

    The event body, exactly what a webhook delivery for this event carries, so the same parser reads both.

  - `seq_from: number`

    First chat `seq` this event covers.

  - `seq_to: number`

    Last chat `seq` this event covers.

  - `type: string`

    What happened, e.g. `message.received`. The same names an endpoint subscribes to.

  - `batch_id: optional string`

    The invitation-batch run this event belongs to. Present on `invitation_batch.*` events only.

  - `chat_id: optional string`

    The chat this event belongs to, on chat events. A brand-scoped event
    (`brand.escalation_handling_changed`) carries its synthetic feed id here
    instead (`brand:<brand_id>`), which is load-bearing for ordering and
    dedup exactly as a chat id is.

- `next_cursor: string`

  Pass back verbatim to read the next page. Empty string when the log is exhausted.

### Example

```http
curl https://messages.api.linqapp.com/v1/events \
    -H "Authorization: Bearer $LINQ_AMB_API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "evt_9c2f4a1b",
      "type": "message.received",
      "created_at": "2026-08-14T05:12:44Z",
      "data": {
        "body": "where is my driver?"
      },
      "chat_id": "chat_4f81b2",
      "seq_from": 13,
      "seq_to": 13
    }
  ],
  "next_cursor": ""
}
```
