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

# Pagination

> How list endpoints page with limit, offset, has_more and next_cursor.

List endpoints in the public API share one pagination shape. It's designed to fit no-code tools like Make (limit + offset + has-more).

## Query parameters

<ParamField query="limit" type="integer" default="50">
  Page size. Range 1–100.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Number of records to skip.
</ParamField>

<Info>
  The profiles and campaigns list endpoints also accept `page` (1-based) for
  convenience, but the response is always the `limit/offset` shape below.
</Info>

## Response shape

Paginated list responses (inside the `data` envelope) look like:

```json theme={null}
{
  "success": true,
  "data": {
    "items": [ ],
    "limit": 50,
    "offset": 0,
    "total": 128,
    "has_more": true,
    "next_cursor": "50"
  }
}
```

<ResponseField name="items" type="array">
  The page of records.
</ResponseField>

<ResponseField name="limit" type="integer">
  The page size that was applied.
</ResponseField>

<ResponseField name="offset" type="integer">
  The offset that was applied.
</ResponseField>

<ResponseField name="total" type="integer">
  Total matching records.
</ResponseField>

<ResponseField name="has_more" type="boolean">
  `true` when `offset + items.length < total`.
</ResponseField>

<ResponseField name="next_cursor" type="string | null">
  The next offset as a string (e.g. `"50"`) when `has_more`, else `null`.
</ResponseField>

## Paging through results

<CodeGroup>
  ```javascript Node.js theme={null}
  let offset = 0;
  const limit = 100;
  const all = [];

  for (;;) {
    const res = await fetch(
      `https://api.senderz.app/api/v1/public/profiles?limit=${limit}&offset=${offset}`,
      { headers }
    );
    const { data } = await res.json();
    all.push(...data.items);
    if (!data.has_more) break;
    offset = Number(data.next_cursor);
  }
  ```
</CodeGroup>

<Warning>
  `next_cursor` is a stringified numeric **offset**, not an opaque token. Feed
  it back as `offset`, not `page`.
</Warning>

## Non-paginated lists

`GET /public/webhooks` returns a **raw array** of endpoints, not a paginated
envelope — there are few enough of them that paging isn't needed.
