Skip to content

Pagination

Every list endpoint is newest first and cursor paginated. Pass meta.next_cursor back as cursor to walk through the pages.

List endpoints such as GET /calls, GET /leads and GET /chats return the newest records first and use cursor pagination: each page tells you where the next one starts, so records created while you page through never shift or repeat.

Parameters

Parameter Description
per_page How many records per page, from 1 to 100. Defaults to 25.
cursor The meta.next_cursor (or meta.prev_cursor) of the page you just read. Leave it out for the first page.

Most lists also take filters, such as since and until (ISO 8601 times) or a status. Keep the same filters on every page. The API reference lists the filters of each endpoint.

Response shape

JSON
{
  "data": [
    { "id": 311, "name": "Jordan Smith", "source": "chat", "created_at": "2026-10-02T14:05:40+00:00" }
  ],
  "links": {
    "first": null,
    "last": null,
    "prev": null,
    "next": "https://vocenya.com/api/public/v1/leads?cursor=eyJpZCI6MzExLCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9"
  },
  "meta": {
    "path": "https://vocenya.com/api/public/v1/leads",
    "per_page": 25,
    "next_cursor": "eyJpZCI6MzExLCJfcG9pbnRzVG9OZXh0SXRlbXMiOnRydWV9",
    "prev_cursor": null
  }
}

meta.next_cursor is null on the last page. Treat cursors as opaque strings: pass them back exactly as you received them.

Fetching every page

async function fetchAllLeads() {
  const leads = [];
  let cursor = null;

  do {
    const url = new URL('https://vocenya.com/api/public/v1/leads');
    url.searchParams.set('per_page', '100');
    if (cursor) url.searchParams.set('cursor', cursor);

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

    leads.push(...page.data);
    cursor = page.meta.next_cursor;
  } while (cursor);

  return leads;
}

Syncing new records

To keep another system up to date, prefer webhooks: they tell you about new leads, calls, bookings and chats as they happen. If you poll instead, pass since with the time of your last sync and page until next_cursor is null, staying within the rate limit.