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

# Pagination in the Launchboard API

> All Launchboard list endpoints use cursor-based pagination. Learn how to page through results using the limit and cursor query parameters.

All list endpoints in the Launchboard API use cursor-based pagination. Instead of page numbers, each response includes an opaque cursor that points to your position in the result set. Pass that cursor back on the next request to fetch the following page. This approach is stable under concurrent writes — inserting a new record won't cause you to skip or repeat rows as you page through.

## Query parameters

<ParamField query="limit" type="number" default="50">
  The number of records to return. Clamped to a minimum of 1 and a maximum of 200. Omit this parameter to use the default of 50.
</ParamField>

<ParamField query="cursor" type="string">
  An opaque string returned as `nextCursor` in the previous response. Omit on the first request. Pass verbatim — do not decode or modify the cursor value.
</ParamField>

## Response structure

List endpoints return a JSON object with two top-level fields:

<ResponseField name="data" type="object[]" required>
  The array of records for the current page, ordered by creation time descending.
</ResponseField>

<ResponseField name="nextCursor" type="string | null" required>
  An opaque cursor you can pass as `?cursor=` to fetch the next page. When this value is `null`, you have reached the last page and there are no more results.
</ResponseField>

## Example

Fetch the first page of stakeholders, then fetch the next page using the cursor from the response.

```bash theme={null}
# First page
curl "https://launchboard.xyz/api/v1/stakeholders?limit=20" \
  -H "Authorization: Bearer pg_live_..."
```

```json theme={null}
{
  "data": [
    {
      "id": "sh_01hx4k2m9b3c7nt8pqrz6v5wde",
      "name": "Alice Chen",
      "email": "alice@example.com",
      "type": "INDIVIDUAL",
      "createdAt": "2024-03-15T10:22:00.000Z"
    }
  ],
  "nextCursor": "eyJpZCI6InNoXzAxaHg0azJtOWIzYzdudDhwcXJ6NnY1d2RlIiwiY3JlYXRlZEF0IjoiMjAyNC0wMy0xNVQxMDoyMjowMC4wMDBaIn0"
}
```

```bash theme={null}
# Next page — pass the cursor from the previous response
curl "https://launchboard.xyz/api/v1/stakeholders?limit=20&cursor=eyJpZCI6InNoXzAxaHg0azJtOWIzYzdudDhwcXJ6NnY1d2RlIiwiY3JlYXRlZEF0IjoiMjAyNC0wMy0xNVQxMDoyMjowMC4wMDBaIn0" \
  -H "Authorization: Bearer pg_live_..."
```

When the response contains `"nextCursor": null`, you have fetched all records.

## Iterating through all pages

<Tip>
  To retrieve all records for a resource — for example, when building a full cap table export or syncing data into a downstream system — loop until `nextCursor` is `null`. Start with a `limit` close to the maximum (200) to minimize the number of round trips.
</Tip>

Here is a simple pattern in JavaScript:

```javascript theme={null}
async function fetchAllStakeholders(apiKey) {
  const results = [];
  let cursor = null;

  do {
    const url = new URL('https://launchboard.xyz/api/v1/stakeholders');
    url.searchParams.set('limit', '200');
    if (cursor) url.searchParams.set('cursor', cursor);

    const res = await fetch(url, {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    });
    const page = await res.json();

    results.push(...page.data);
    cursor = page.nextCursor;
  } while (cursor !== null);

  return results;
}
```

## Cursor internals

The cursor is an opaque, base64url-encoded value. Treat it as a black box — pass it back to the API verbatim. Its internal structure may change between API versions.
