`https://lumail.io/api/v1/subscribers/{subscriber}/events`

Retrieves the event history for a specific subscriber. This endpoint supports cursor-based pagination, filtering by event type, and date range filtering.

## Query Parameters

| Parameter    | Type   | Default | Description                                                   |
| ------------ | ------ | ------- | ------------------------------------------------------------- |
| `cursor`     | string | -       | Base64-encoded cursor for pagination                          |
| `take`       | number | 20      | Number of events to return (1-100)                            |
| `eventTypes` | string | -       | JSON array of event types to filter (e.g. `["EMAIL_OPENED"]`) |
| `order`      | string | "desc"  | Sort order by createdAt ("asc" or "desc")                     |
| `startDate`  | string | -       | ISO 8601 datetime to filter events after this date            |
| `endDate`    | string | -       | ISO 8601 datetime to filter events before this date           |
| `search`     | string | -       | Search query to filter events by data content or subscriber   |

## Response

- **Success (200 OK)** - Returns the events array with pagination cursor.
- **Error (404 Not Found)** - Returned if the subscriber does not exist.

## Response Fields

| Field                       | Type        | Description                                      |
| --------------------------- | ----------- | ------------------------------------------------ |
| `events`                    | array       | Array of event objects                           |
| `events[].id`               | string      | Unique identifier for the event                  |
| `events[].eventType`        | string      | Type of the event (see supported types below)    |
| `events[].data`             | object      | Event-specific data payload                      |
| `events[].subscriberId`     | string      | ID of the subscriber                             |
| `events[].createdAt`        | string      | ISO timestamp when the event occurred            |
| `events[].subscriber`       | object      | Subscriber details                               |
| `events[].subscriber.id`    | string      | Subscriber ID                                    |
| `events[].subscriber.email` | string      | Subscriber email                                 |
| `events[].subscriber.name`  | string/null | Subscriber name                                  |
| `nextCursor`                | string/null | Cursor for the next page (null if no more pages) |

## Supported Event Types

### Email Engagement Events

| Event Type               | Description                            | Data Fields                                                 |
| ------------------------ | -------------------------------------- | ----------------------------------------------------------- |
| `EMAIL_SENT`             | Email was sent to subscriber           | `emailId`, `campaignId`, `subject`, `workflow?`             |
| `EMAIL_RECEIVED`         | Email was successfully delivered       | `emailId`, `campaignId`, `subject`, `receivedAt?`           |
| `EMAIL_OPENED`           | Subscriber opened an email             | `emailId`, `campaignId?`, `subject`                         |
| `EMAIL_CLICKED`          | Subscriber clicked a link in an email  | `emailId`, `campaignId?`, `subject`, `targetUrl`, `linkId?` |
| `EMAIL_BOUNCED`          | Email could not be delivered           | `emailId`, `campaignId?`, `subject`, `reason`, `bounceType` |
| `EMAIL_COMPLAINED`       | Subscriber marked email as spam        | `emailId`, `campaignId?`, `subject`                         |
| `EMAIL_DELIVERY_DELAYED` | Email delivery was temporarily delayed | `emailId`, `campaignId?`, `subject`, `workflow?`            |

### Subscription Events

| Event Type     | Description                 | Data Fields                                          |
| -------------- | --------------------------- | ---------------------------------------------------- |
| `SUBSCRIBED`   | Subscriber joined your list | `tags?` (array of tag objects)                       |
| `UNSUBSCRIBED` | Subscriber opted out        | `reason?`, `campaignId?`, `campaignName?`, `status?` |

### Tag Events

| Event Type    | Description                     | Data Fields                   |
| ------------- | ------------------------------- | ----------------------------- |
| `TAG_ADDED`   | Tag was applied to subscriber   | `tagId`, `tagName`, `reason?` |
| `TAG_REMOVED` | Tag was removed from subscriber | `tagId`, `tagName`, `reason?` |

### Workflow Events

| Event Type           | Description                             | Data Fields                                                                                |
| -------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------ |
| `WORKFLOW_STARTED`   | Subscriber entered an automation        | `workflowId`, `workflowName`                                                               |
| `WORKFLOW_COMPLETED` | Subscriber completed all workflow steps | `workflowId`, `workflowName`                                                               |
| `WORKFLOW_CANCELED`  | Subscriber was removed from workflow    | `workflowId`, `workflowName`, `reason?`                                                    |
| `WEBHOOK_EXECUTED`   | Webhook step was triggered              | `workflowId`, `workflowName`, `stepId`, `webhookUrl`, `status`, `success`, `errorMessage?` |

### Revenue Events

| Event Type           | Description                | Data Fields         |
| -------------------- | -------------------------- | ------------------- |
| `SUBSCRIBER_PAYMENT` | Subscriber made a payment  | `amount`, `product` |
| `SUBSCRIBER_REFUND`  | Subscriber received refund | `amount`, `product` |

### Other Events

| Event Type      | Description                    | Data Fields                                     |
| --------------- | ------------------------------ | ----------------------------------------------- |
| `FIELD_UPDATED` | Custom field value was updated | `fieldId`, `fieldName`, `oldValue?`, `newValue` |

## Usage Examples

### Get recent activity

Retrieve the 20 most recent events for a subscriber:

```bash
curl "https://lumail.io/api/v1/subscribers/sub_123/events" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Filter by email engagement

Get only email open and click events:

```bash
curl 'https://lumail.io/api/v1/subscribers/sub_123/events?eventTypes=["EMAIL_OPENED","EMAIL_CLICKED"]' \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Date range filtering

Get events from the last 7 days:

```bash
curl "https://lumail.io/api/v1/subscribers/sub_123/events?startDate=2025-01-01T00:00:00Z&endDate=2025-01-07T23:59:59Z" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Search events

Search for events containing specific text:

```bash
curl "https://lumail.io/api/v1/subscribers/sub_123/events?search=newsletter" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Pagination

Fetch all events using cursor pagination:

```javascript
async function getAllEvents(subscriberId) {
  const events = [];
  let cursor = null;

  do {
    const params = new URLSearchParams({ take: "100" });
    if (cursor) params.set("cursor", cursor);

    const response = await fetch(
      `https://lumail.io/api/v1/subscribers/${subscriberId}/events?${params}`,
      { headers: { Authorization: "Bearer YOUR_API_TOKEN" } },
    );
    const data = await response.json();

    events.push(...data.events);
    cursor = data.nextCursor;
  } while (cursor);

  return events;
}
```

### Pagination with SDK

```typescript
import { Lumail } from "lumail";
const lumail = new Lumail({ apiKey: "YOUR_API_TOKEN" });

async function getAllEvents(subscriberId: string) {
  const events = [];
  let cursor: string | null = null;

  do {
    const result = await lumail.subscribers.listEvents(subscriberId, {
      take: 100,
      cursor: cursor ?? undefined,
    });
    events.push(...result.events);
    cursor = result.nextCursor;
  } while (cursor);

  return events;
}
```

## Related Documentation

- [Track Events API](/docs/api-reference/api-events-post) - Record new events for subscribers
- [Subscriber Events Reference](/docs/features/subscriber-events) - Complete guide to all event types and their data fields
- [Revenue Tracking](/docs/features/revenue-tracking) - Analyze payment and refund events
- [Workflows](/docs/workflows) - View workflow execution history in events


## API Reference
**Method:** GET
**Endpoint:** /api/v1/subscribers/{subscriber}/events

### SDK
```ts
import { Lumail } from "lumail";
const lumail = new Lumail({ apiKey: "YOUR_API_TOKEN" });

// Basic request
const { events, nextCursor } = await lumail.subscribers.listEvents(
  "sub_TTYPR5tWDh",
  { take: 20, order: "desc" }
);

// With filters
const filtered = await lumail.subscribers.listEvents(
  "subscriber@example.com",
  {
    eventTypes: ["EMAIL_OPENED", "EMAIL_CLICKED"],
    startDate: "2025-01-01T00:00:00Z",
    take: 50,
    order: "desc",
  }
);

// Pagination
if (filtered.nextCursor) {
  const next = await lumail.subscribers.listEvents(
    "subscriber@example.com",
    { cursor: filtered.nextCursor, take: 50 }
  );
}
```

### cURL
```bash
curl -X GET "https://lumail.io/api/v1/subscribers/sub_TTYPR5tWDh/events?take=20&order=desc" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# With event type filters (JSON array)
curl -X GET 'https://lumail.io/api/v1/subscribers/subscriber@example.com/events?eventTypes=["EMAIL_OPENED","EMAIL_CLICKED"]&startDate=2025-01-01T00:00:00Z' \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Pagination with cursor
curl -X GET "https://lumail.io/api/v1/subscribers/sub_TTYPR5tWDh/events?cursor=eyJjcmVhdGVkQXQiOiIyMDI1LTAxLTA3VDEyOjAwOjAwLjAwMFoiLCJpZCI6ImV2dF8xMjM0NSJ9" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### JavaScript
```javascript
// Basic request
const response = await fetch(
  'https://lumail.io/api/v1/subscribers/sub_TTYPR5tWDh/events?take=20',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
    },
  }
);
const data = await response.json();
console.log(data);

// With filters and pagination
const params = new URLSearchParams({
  eventTypes: JSON.stringify(['EMAIL_OPENED', 'EMAIL_CLICKED']),
  startDate: '2025-01-01T00:00:00Z',
  take: '50',
  order: 'desc',
});

const filteredResponse = await fetch(
  `https://lumail.io/api/v1/subscribers/subscriber@example.com/events?${params}`,
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
    },
  }
);
const filteredData = await filteredResponse.json();

// Handle pagination
if (filteredData.nextCursor) {
  const nextPage = await fetch(
    `https://lumail.io/api/v1/subscribers/subscriber@example.com/events?cursor=${filteredData.nextCursor}`,
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_TOKEN',
      },
    }
  );
}
```

### Python
```python
import requests
import json

# Basic request
url = "https://lumail.io/api/v1/subscribers/sub_TTYPR5tWDh/events"
headers = {
    "Authorization": "Bearer YOUR_API_TOKEN"
}

response = requests.get(url, headers=headers)
data = response.json()
print(data)

# With filters
params = {
    "eventTypes": json.dumps(["EMAIL_OPENED", "EMAIL_CLICKED"]),
    "startDate": "2025-01-01T00:00:00Z",
    "take": 50,
    "order": "desc"
}

filtered_response = requests.get(
    f"https://lumail.io/api/v1/subscribers/subscriber@example.com/events",
    params=params,
    headers=headers
)
filtered_data = filtered_response.json()

# Handle pagination
if filtered_data.get("nextCursor"):
    next_response = requests.get(
        f"https://lumail.io/api/v1/subscribers/subscriber@example.com/events",
        params={"cursor": filtered_data["nextCursor"]},
        headers=headers
    )
```

### Success Response
```json
{
  "events": [
    {
      "id": "evt_6fGhIjKl78",
      "eventType": "EMAIL_OPENED",
      "data": {
        "emailId": "eml_abc123",
        "campaignId": "cmp_xyz789",
        "subject": "Welcome to our newsletter!"
      },
      "subscriberId": "sub_TTYPR5tWDh",
      "createdAt": "2025-01-07T14:30:00.000Z",
      "subscriber": {
        "id": "sub_TTYPR5tWDh",
        "email": "subscriber@example.com",
        "name": "John Doe"
      }
    },
    {
      "id": "evt_9aBcDeFg12",
      "eventType": "EMAIL_SENT",
      "data": {
        "emailId": "eml_abc123",
        "campaignId": "cmp_xyz789",
        "subject": "Welcome to our newsletter!"
      },
      "subscriberId": "sub_TTYPR5tWDh",
      "createdAt": "2025-01-07T14:00:00.000Z",
      "subscriber": {
        "id": "sub_TTYPR5tWDh",
        "email": "subscriber@example.com",
        "name": "John Doe"
      }
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI1LTAxLTA3VDEzOjQ1OjAwLjAwMFoiLCJpZCI6ImV2dF8zSGlKa0xtTjQ1In0="
}
```

### Error Response
```json
{
  "message": "Subscriber not found"
}
```
