---
title: Pagination
description: Learn how to paginate through API responses using cursor-based pagination
---

# Pagination

All list endpoints in the Notiflows API support cursor-based pagination to efficiently navigate through large collections of resources. This pagination method uses cursors (opaque strings) to mark positions in the dataset, allowing you to fetch pages of results in either direction.

## How It Works

Cursor-based pagination provides a stable and efficient way to paginate through data. Unlike offset-based pagination, cursors remain stable even as data is added or removed, making them ideal for real-time data that changes frequently.

### Query Parameters

All list endpoints accept the following pagination parameters:

| Parameter | Type | Description |
|-----------|------|-------------|
| `after` | string | Cursor for fetching items after the last item in the current page. Use the `after` value from the `page` object in the response. |
| `before` | string | Cursor for fetching items before the first item in the current page. Use the `before` value from the `page` object in the response. |
| `limit` | integer | Number of items to return per page. Defaults to `25`, maximum is `1000`. |

### Response Format

All paginated responses follow this structure:

```json
{
  "items": [...],
  "page": {
    "limit": 25,
    "after": "cursor_string_for_next_page",
    "before": "cursor_string_for_previous_page",
    "has_more_after": true,
    "has_more_before": false
  }
}
```

### Page Object Properties

The `page` object in the response contains the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `limit` | integer | The number of items requested per page (or the default if not specified). |
| `after` | string \| null | The cursor to use for fetching the next page. Will be `null` if there are no more items after the current page. |
| `before` | string \| null | The cursor to use for fetching the previous page. Will be `null` if there are no more items before the current page. |
| `has_more_after` | boolean | Indicates whether there are more items available after the current page. |
| `has_more_before` | boolean | Indicates whether there are more items available before the current page. |

## Examples

### Fetching the First Page

To fetch the first page of results, make a request without any pagination parameters:

```bash
curl -X GET "https://api.notiflows.com/admin/v1/users" \
  -H "x-notiflows-api-key: your-api-key" \
  -H "x-notiflows-secret-key: your-secret-key"
```

Response:

```json
{
  "items": [
    { "id": "user-1", "external_id": "ext-1", ... },
    { "id": "user-2", "external_id": "ext-2", ... },
    ...
  ],
  "page": {
    "limit": 25,
    "after": "eyJpZCI6InVzZXItMjUifQ==",
    "before": null,
    "has_more_after": true,
    "has_more_before": false
  }
}
```

### Fetching the Next Page

To fetch the next page, use the `after` cursor from the previous response:

```bash
curl -X GET "https://api.notiflows.com/admin/v1/users?after=eyJpZCI6InVzZXItMjUifQ==" \
  -H "x-notiflows-api-key: your-api-key" \
  -H "x-notiflows-secret-key: your-secret-key"
```

### Fetching the Previous Page

To go back to the previous page, use the `before` cursor:

```bash
curl -X GET "https://api.notiflows.com/admin/v1/users?before=eyJpZCI6InVzZXItMjUifQ==" \
  -H "x-notiflows-api-key: your-api-key" \
  -H "x-notiflows-secret-key: your-secret-key"
```

### Customizing Page Size

You can specify a custom page size using the `limit` parameter:

```bash
curl -X GET "https://api.notiflows.com/admin/v1/users?limit=50" \
  -H "x-notiflows-api-key: your-api-key" \
  -H "x-notiflows-secret-key: your-secret-key"
```

**Note:** The maximum `limit` value is `1000`. If you specify a value greater than `1000`, it will be capped at `1000`.

## Best Practices

1. **Use `has_more_after` and `has_more_before`** to determine if there are more pages available, rather than checking if `after` or `before` are null.

2. **Store cursors securely** - Cursors are opaque strings and should be treated as sensitive data. They may contain encoded information about the position in your dataset.

3. **Handle null cursors gracefully** - When `after` or `before` are `null`, it means there are no more items in that direction.

4. **Use appropriate page sizes** - Smaller page sizes (25-50) are recommended for better performance and user experience. Only use larger page sizes when necessary.

5. **Don't modify cursors** - Cursors are generated by the API and should be used exactly as returned. Modifying them may result in unexpected behavior.

## Pagination with Filters

Pagination works seamlessly with filtering parameters. When you apply filters, pagination will only apply to the filtered results:

```bash
curl -X GET "https://api.notiflows.com/admin/v1/deliveries?status=sent&limit=50&after=cursor_string" \
  -H "x-notiflows-api-key: your-api-key" \
  -H "x-notiflows-secret-key: your-secret-key"
```

The pagination cursors will maintain their position relative to the filtered dataset, so you can paginate through filtered results just like unfiltered results.

## Error Handling

If you provide an invalid cursor (e.g., from a different query or an expired cursor), the API will return a `400 Bad Request` error. In this case, you should start pagination from the beginning by making a request without cursor parameters.
