Lists transactional emails created through the API, newest first. Campaign sends and test emails are excluded (`campaignId` null, `isTest` false). Permission: `emails`.

List rows are metadata plus `last_event`. They do not include `html`, `text`, or `tags`. Fetch the body with [Get Email](/docs/api-reference/v2/emails-get).

## Query Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `limit` | integer | Page size. Default `20`. Min `1`, max `100`. |
| `after` | string | Return emails older than this id (next page, walking backward in time). |
| `before` | string | Return emails newer than this id. |

Pass `after` or `before`, not both. The cursor must be an email id that exists in this organization.

## Response Fields

| Field | Type | Description |
| ----- | ---- | ----------- |
| `object` | `"list"` | Discriminator. Always `list`. |
| `has_more` | boolean | `true` when another page exists in the same direction. |
| `data` | array | Email objects, newest first. Same fields as Get Email except `object`, `html`, `text`, and `tags`. |

`last_event` uses the same mapping as [Get Email](/docs/api-reference/v2/emails-get#last-event).

## Errors

| Status | `name` | When |
| ------ | ------ | ---- |
| 401 | `missing_api_key` | Missing or invalid bearer token |
| 403 | `validation_error` | Token lacks the `emails` permission |
| 422 | `validation_error` | Both `after` and `before`, or cursor id not found |

## Related

- [Send Email](/docs/api-reference/v2/emails-send)
- [Get Email](/docs/api-reference/v2/emails-get)


## API Reference
**Method:** GET
**Endpoint:** /api/v2/emails

### SDK
```ts
import { Lumail } from "lumail";

const lumail = new Lumail({ apiKey: process.env.LUMAIL_API_KEY });
const { data: page, error } = await lumail.emails.list({ limit: 20 });
if (error) {
  throw error;
}

for (const email of page.data) {
  console.log(email.id, email.last_event);
}

if (page.has_more) {
  const next = await lumail.emails.list({
    limit: 20,
    after: page.data.at(-1)?.id,
  });
  console.log(next.data?.data.length);
}
```

### cURL
```bash
curl "https://lumail.io/api/v2/emails?limit=20" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

curl "https://lumail.io/api/v2/emails?limit=20&after=eml_abc123def456" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### JavaScript
```javascript
const response = await fetch("https://lumail.io/api/v2/emails?limit=20", {
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
  },
});
const page = await response.json();

const next = await fetch(
  `https://lumail.io/api/v2/emails?limit=20&after=${page.data.at(-1).id}`,
  { headers: { Authorization: "Bearer YOUR_API_TOKEN" } },
);
await next.json();
```

### Success Response
```json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "eml_abc123def456",
      "message_id": "0100018f3c2a1b2c-d4e5f6a7-89ab-cdef-0123-456789abcdef-000000",
      "to": ["user@example.com"],
      "from": "hello@yourdomain.com",
      "created_at": "2026-09-05T10:30:00.000Z",
      "subject": "Welcome",
      "last_event": "delivered"
    }
  ]
}
```

### Error Response
```json
{
  "name": "validation_error",
  "message": "Use either after or before, not both",
  "statusCode": 422
}
```
