> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.usglobalmail.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.usglobalmail.com/_mcp/server.

# Pagination

Most list endpoints return a page envelope:

```json
{
  "data": [ /* … up to `limit` items … */ ],
  "next_cursor": "eyJvIjoyNX0",
  "total_count": 143
}
```

* `data` — the items in this page.
* `next_cursor` — pass this back as `?cursor=` to fetch the next page. When it is `null`, you've
  reached the end.
* `total_count` — the total number of items matching your query across all pages, so you can show a
  count or compute the number of pages up front. It reflects your filters, and is the same on every page.

> **Note**
>
> The **folders** list endpoint is not paginated — it returns the full set of folders in a single
> response and accepts no `limit` or `cursor` parameters.

## Paging through results

Request the first page, then keep passing `next_cursor` back as `cursor` until it's `null`:

```bash
# First page
curl "https://api.usglobalmail.com/v1/mails?limit=50" \
  -H "Authorization: Bearer $USGM_API_KEY"

# Next page
curl "https://api.usglobalmail.com/v1/mails?limit=50&cursor=eyJvIjoyNX0" \
  -H "Authorization: Bearer $USGM_API_KEY"
```

The SDKs handle this for you — list methods return an iterator that fetches pages transparently:

**`TypeScript`**

```typescript title="TypeScript"
for await (const mail of usgm.mails.list({ limit: 50 })) {
  console.log(mail.id);
}
```

**`Python`**

```python title="Python"
for mail in usgm.mails.list(limit=50):
    print(mail.id)
```

## Limit

| Parameter | Default | Max |
| --------- | ------- | --- |
| `limit`   | 25      | 100 |

## Cursors are opaque and scoped

Treat `next_cursor` as an **opaque token** — don't parse, build, or modify it. Each cursor is signed and
**bound to the exact endpoint and query** it came from, so:

* **Keep the other query parameters identical while paging.** Changing a filter (or using the cursor on
  a different endpoint) invalidates it — the request fails with a `422` [`validation_error`](/api/problems/validation_error).
* Only pass back a `next_cursor` you actually received; a hand-crafted or altered cursor is rejected.

## Maximum depth

Pagination reaches the first **10,000** items of a result set. Past that, `next_cursor` is `null` even
when more rows exist (and a too-deep cursor returns `422`). Use `total_count` to detect this, and
**narrow with filters** (date range, status, folder, …) to reach items deeper than the limit rather than
paging through everything.