Scope contract notice: API key scopes are enforced for public routes; see Scope reference for required grants.

Pagination

List endpoints use opaque cursor pagination.

Request

Pass limit to control page size and cursor to request the next page. Cursors are opaque; do not parse, edit, or construct them.

GET /api/v1/agents?limit=50
GET /api/v1/agents?cursor=opaque_cursor_value&limit=50

Response

List responses use this envelope:

{
  "items": [
    {}
  ],
  "pagination": {
    "nextCursor": "opaque_cursor_value"
  }
}

pagination.nextCursor is null when there are no more pages. Totals are not part of the common list envelope.

Load More Loop

async function listAllAgents() {
  const agents = [];
  let cursor;

  do {
    const url = new URL("https://api.voiceagent.example/api/v1/agents");
    url.searchParams.set("limit", "50");

    if (cursor) {
      url.searchParams.set("cursor", cursor);
    }

    const response = await fetch(url, {
      headers: {
        Authorization: `Bearer ${process.env.VOICEAGENT_API_KEY}`,
      },
    });

    const body = await response.json();

    if (!response.ok) {
      throw new Error(`${response.status} ${body.error?.code}: ${body.error?.message}`);
    }

    agents.push(...body.items);
    cursor = body.pagination.nextCursor;
  } while (cursor);

  return agents;
}

Store cursors only long enough to fetch the next page. They are not stable resource IDs and may change as data changes.