> ## Documentation Index
> Fetch the complete documentation index at: https://synthetiq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Automatic multi-page API fetching with cursor, page number, and offset strategies

Many APIs return data in pages. Workflow service steps handle pagination automatically — you configure the strategy and the engine fetches all pages, appending results to the output table.

## Pagination types

### Cursor-based

Used by GraphQL APIs, Shopify, Slack, and similar services that return a cursor pointing to the next page:

```typescript theme={null}
{
  service: "shopify",
  operation: "listProducts",
  params: { status: "active" },
  outputTable: "raw_products",
  outputSchema: {
    id: "VARCHAR",
    title: "VARCHAR",
    vendor: "VARCHAR",
  },
  paginate: {
    type: "cursor",
    cursorField: "pageInfo.endCursor",
    cursorParam: "after",
    hasMoreField: "pageInfo.hasNextPage",
  },
}
```

| Field          | Description                                                      |
| -------------- | ---------------------------------------------------------------- |
| `cursorField`  | Path to the cursor value in the response (supports dot notation) |
| `cursorParam`  | Parameter name to pass the cursor on the next request            |
| `hasMoreField` | Path to a boolean indicating more results exist                  |

### Page number

Used by GitHub REST, Rails, Django, and APIs that accept a page number parameter:

```typescript theme={null}
{
  service: "github",
  operation: "listRepos",
  params: {},
  outputTable: "raw_repos",
  outputSchema: {
    id: "VARCHAR",
    name: "VARCHAR",
    full_name: "VARCHAR",
  },
  paginate: {
    type: "pageNumber",
    pageParam: "page",
    startPage: 1,
  },
}
```

| Field       | Description                        |
| ----------- | ---------------------------------- |
| `pageParam` | Parameter name for the page number |
| `startPage` | First page number (typically `1`)  |

### Offset

Used by Elasticsearch, SQL-style APIs, and services that accept offset and limit parameters:

```typescript theme={null}
{
  service: "elasticsearch",
  operation: "search",
  params: { query: "*" },
  outputTable: "raw_results",
  outputSchema: {
    id: "VARCHAR",
    title: "VARCHAR",
    score: "DOUBLE",
  },
  paginate: {
    type: "offset",
    offsetParam: "from",
    limitParam: "size",
    limitValue: 100,
    startOffset: 0,
  },
}
```

| Field         | Description                            |
| ------------- | -------------------------------------- |
| `offsetParam` | Parameter name for the starting offset |
| `limitParam`  | Parameter name for the page size       |
| `limitValue`  | Number of records per page             |
| `startOffset` | Initial offset value (typically `0`)   |

## Stop conditions

Pagination stops automatically when there are no more results:

* **Cursor**: `hasMoreField` returns `false`, or the cursor is `null`/`undefined`
* **Page number / Offset**: The response returns an empty result set

## Retry configuration

In addition to step-level retries (when the entire step fails), you can configure retries per page when a single page request fails:

```typescript theme={null}
paginate: {
  type: "cursor",
  cursorField: "nextCursor",
  cursorParam: "cursor",
  maxRetries: 5,
  retryDelayMs: 2000,
}
```

| Field          | Default | Description                                              |
| -------------- | ------- | -------------------------------------------------------- |
| `maxRetries`   | `3`     | Retry attempts per page                                  |
| `retryDelayMs` | `1000`  | Base delay in milliseconds (exponential backoff applied) |
