# List a contact's messages

`GET /v1/contacts/{id}/messages`

Requires an API key with the `messages:read` scope. [About keys and scopes](/docs/api/authentication)

Every message sent or attempted to this contact, from any source, newest first, with its outcome. Filter by `status`, `channel` or `messageType`.

## Path parameters

- `id` (string, required, uuid)

## Query parameters

- `limit` (integer, optional, min > 0, max 100, default `20`)
- `cursor` (string, optional, 1–2048 characters)
- `status` (string, optional, one of `queued`, `sending`, `skipped`, `sent`, `failed`, `delivered`, `bounced`, `complained`) — Only messages in this status.
- `channel` (string, optional, one of `email`, `push`)
- `messageType` (string, optional, one of `marketing`, `transactional`) — Only messages of this type, such as campaign or transactional.

## Returns

Returns `200 OK` with a list of `SentMessage` objects in `data`, and the next page's cursor in `meta` (see [pagination](/docs/api/pagination)). Otherwise returns an error; [Errors](/docs/api/errors) lists every code and which to retry.

- `id` (string, required, uuid)
- `contactId` (string | null, required, uuid) — Null when the contact was erased, or the message passed the retention period: the message no longer names anyone.
- `currentContactEmail` (string | null, required) — The contact's email now, which may differ from `recipientAddress`.
- `recipientAddress` (string | null, required) — The address the message went to, frozen at the first attempt; null until then.
- `simulated` (boolean, required) — Sent to a reserved test address (`example.com` and the like): it passed every check a real send does but was never handed to the provider. Any outcome was simulated from the address, as `bounce@example.com` simulates a bounce.
- `campaignId` (string | null, required, uuid) — The campaign it came from, if any.
- `journeyId` (string | null, required, uuid) — The journey it came from, if any.
- `journeyEnrollmentId` (string | null, required, uuid) — The journey enrollment it came from, if any.
- `journeyStepIndex` (integer | null, required, min -9007199254740991, max 9007199254740991) — Position of the journey step that sent it, if any.
- `sourceName` (string | null, required) — The campaign's or journey's name; null for a transactional send.
- `messageType` (string, required, one of `marketing`, `transactional`)
- `channel` (string, required, one of `email`, `push`)
- `status` (string, required, one of `queued`, `sending`, `skipped`, `sent`, `failed`, `delivered`, `bounced`, `complained`)
- `failureReason` (string | null, required) — Why it failed, bounced or was skipped, e.g. `suppressed`, `consent_missing`.
- `correlationId` (string | null, required) — The reference a transactional send carried; null otherwise.
- `sendAt` (string | null, required, date-time) — When a timed transactional send is due; null for one sent at once.
- `sentAt` (string | null, required, date-time) — When it was handed to the provider.
- `deliveredAt` (string | null, required, date-time) — When the provider confirmed delivery.
- `failedAt` (string | null, required, date-time) — When it failed, bounced or was skipped (a cancelled send included).
- `openedAt` (string | null, required, date-time) — First open, when tracked.
- `clickedAt` (string | null, required, date-time) — First click, when tracked.
- `createdAt` (string, required, date-time)
- `template` (object | null, required) — The stored template and published version it was sent from; null for inline content. Messages sent before template versions carry `version: null`.
  - `id` (string, required, uuid)
  - `version` (integer | null, required, min > 0, max 9007199254740991)

## Example

```bash
curl https://api.kirora.io/v1/contacts/018f2a4e-6b1c-7d3e-9f40-37386ae05a6b/messages \
  -H "Authorization: Bearer $KIRORA_API_KEY"
```

Response `200`:

```json
{
  "data": [
    {
      "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
      "contactId": "018f2a4e-6b1c-7d3e-9f40-4db757ce5a6b",
      "currentContactEmail": "currentContactEmail_example",
      "recipientAddress": "recipientAddress_example",
      "simulated": true,
      "campaignId": "018f2a4e-6b1c-7d3e-9f40-3478765e5a6b",
      "journeyId": "018f2a4e-6b1c-7d3e-9f40-7cf2bf7e5a6b",
      "journeyEnrollmentId": "018f2a4e-6b1c-7d3e-9f40-eb556d965a6b",
      "journeyStepIndex": -9007199254740991,
      "sourceName": "sourceName_example",
      "messageType": "marketing",
      "channel": "email",
      "status": "queued",
      "failureReason": "failureReason_example",
      "correlationId": "order-1001",
      "sendAt": "2030-03-14T09:30:00Z",
      "sentAt": "2030-03-14T09:30:00Z",
      "deliveredAt": "2030-03-14T09:30:00Z",
      "failedAt": "2030-03-14T09:30:00Z",
      "openedAt": "2030-03-14T09:30:00Z",
      "clickedAt": "2030-03-14T09:30:00Z",
      "createdAt": "2030-03-14T09:30:00Z",
      "template": {
        "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
        "version": 1
      }
    }
  ],
  "meta": {
    "pagination": {
      "limit": 1,
      "nextCursor": "nextCursor_example"
    }
  }
}
```
