---
title: "List campaign engagement events"
method: GET
path: "/campaigns/{campaignId}/events"
tags: ["Campaigns"]
---

# List campaign engagement events

`GET /campaigns/{campaignId}/events`

## Request

- Base URL: `https://app.lettr.com/api`
- URL: `https://app.lettr.com/api/campaigns/{campaignId}/events`
- Auth: HTTP bearer

Returns engagement events (opens, clicks, bounces, etc.) for a campaign, with optional filtering by type, recipient email, and date range. Uses cursor-based pagination: keep requesting with the returned `next_cursor` until it is `null`. When a filter is applied, a page may come back with an empty `events` array **and** a non-null `next_cursor` — that means more pages remain, not that there are no matching events, so continue paginating until `next_cursor` is `null`. Requires the `campaigns:read` scope.

## Path parameters

- `campaignId` string, uuid, required

## Query parameters

- `event_type` 'injection' | 'delivery' | 'bounce' | 'spam_complaint' | 'open' | 'click' | 'list_unsubscribe'
- `email` string, email
- `start_date` string, date-time
- `end_date` string, date-time
- `limit` integer
- `cursor` string

## Response `200`

Campaign events retrieved successfully.

- ListCampaignEventsResponse
  - `message` string, required
  - `data` object, required
    - `events` CampaignEvent[], required
      - `event_id` string, required
      - `event_type` 'injection' | 'delivery' | 'bounce' | 'spam_complaint' | 'open' | 'click' | 'list_unsubscribe', required
      - `email` string, email, required
      - `timestamp` string, date-time, required
      - `bounce_class` string, nullable: SparkPost bounce classification code
      - `reason` string, nullable: Failure or bounce reason
      - `target_link_url` string, nullable: Clicked link URL (click events only)
      - `user_agent` string, nullable: Recipient user agent (open/click events)
    - `next_cursor` string, nullable, required: Opaque cursor for the next page; null when there are no more events

## Other responses

- `401`: Unauthorized - Missing or invalid API key
- `403`: Forbidden - API key does not have the required scope
- `404`: Resource not found
- `422`: Validation error
- `500`: Internal server error
- `503`: Service unavailable - the API key could not be verified, so the request was not processed. This does not mean the key is invalid; retry after the delay given in the Retry-After header.

---

[API](https://skmtc.dev/lettr/apis/lettr-api.md) · [All operations](https://skmtc.dev/lettr/apis/lettr-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lettr/apis/lettr-api/revisions/48ef0dac1ebd?raw)
