<!-- https://developers.silktide.com/v1/concepts/pagination | Concepts -->

# Pagination

Results that can hold many rows, such as [tables](https://developers.silktide.com/v1/concepts/tables.md) and the list of a website's content, answer one page of rows at a time.

## Arguments

| Argument | What it does |
| --- | --- |
| `page` | The page to return, from `1`. Defaults to `1`. |
| `rowsPerPage` | How many rows a page holds. Defaults to `100`. |

## The answer

Beside its `rows`, a paginated answer says where they sit:

| Field | What it is |
| --- | --- |
| `page` | The page returned. A `page` past the last one returns the last page, and one below `1` returns the first, so this is not always the page you asked for. |
| `minPage` | The first page. Always `1`. |
| `maxPage` | The last page at this `rowsPerPage`. |
| `numRows` | How many rows there are across every page. |
| `rowsPerPage` | How many rows a page holds. |

## Reading every page

Ask for page 1, then each next page until `page` reaches `maxPage`. Stop as well when a page comes back with no rows: an empty table reports a `maxPage` of `0` or `1`.

```javascript
async function allRows(url) {
  const rows = [];
  for (let page = 1; ; page++) {
    const response = await fetch(`${url}&page=${page}&rowsPerPage=100`, {
      headers: { Authorization: `silktide token=${process.env.SILKTIDE_API_KEY}` },
    });
    const body = await response.json();
    if (body.error) throw new Error(body.error.message);
    const { rows: pageRows, maxPage } = body.result.contents ?? body.result;
    rows.push(...pageRows);
    if (pageRows.length === 0 || page >= maxPage) return rows;
  }
}
```

Each operation's page says where its rows are: directly in `result`, or inside a field of it such as `contents`.

## Limit

A few results that are not paginated, such as a list of the top sources, take `limit` instead: the most entries to return. Their pages say what it defaults to.
