Pagination

The conversations, deals, accounts, messages, rows, and documents list endpoints use cursor-based pagination. This provides efficient sequential access without relying on page numbers. Records added or deleted while you paginate can affect later pages, so complete an iteration promptly when you need a consistent snapshot.

How it works

Every list endpoint returns the same pagination object alongside the results:

{
  "conversations": [ ... ],
  "pagination": {
    "nextCursor": "eyJzZWFyY2hBZnRlciI6...",
    "hasMore": true
  }
}
FieldTypeDescription
nextCursorstring or nullAn opaque token pointing to the next page. null when there are no more results.
hasMorebooleantrue if additional pages exist beyond the current one.

Fetching the next page

Pass the nextCursor value as the cursor query parameter in your next request:

# First request
curl -H "Authorization: Bearer sk_live_YOUR_KEY" \
  "https://api.sybill.ai/v1/conversations?limit=10"

# Next page
curl -H "Authorization: Bearer sk_live_YOUR_KEY" \
  "https://api.sybill.ai/v1/conversations?limit=10&cursor=eyJzZWFyY2hBZnRlciI6..."
Cursor stability

Cursors are opaque strings. Do not parse, decode, construct, or store them as bookmarks. Always use the exact value returned by the API for the next request in the same iteration. On document lists, records with identical creation timestamps at a page boundary may be repeated or skipped.

Controlling page size

Use the limit parameter to control how many results are returned per page. The maximum is 50 for every paginated endpoint; the per-endpoint default differs:

EndpointDefaultMax
GET /v1/conversations2050
GET /v1/deals2050
GET /v1/accounts2050
GET /v1/messages5050
GET /v1/rows5050
GET /v1/documents5050

Combining with filters

Filters and pagination work together. Repeat the same filters and page size on every request in an iteration; cursors identify a position but do not contain the original filters.

# First page: external meetings after Jan 1
curl -H "Authorization: Bearer sk_live_YOUR_KEY" \
  "https://api.sybill.ai/v1/conversations?type=EXTERNAL&startedAfter=2024-01-01T00:00:00Z&limit=20"

# Second page: repeat the filters and pass the cursor
curl -H "Authorization: Bearer sk_live_YOUR_KEY" \
  "https://api.sybill.ai/v1/conversations?type=EXTERNAL&startedAfter=2024-01-01T00:00:00Z&limit=20&cursor=eyJ..."

Full iteration example

import requests

API_KEY = "sk_live_YOUR_KEY"
BASE = "https://api.sybill.ai/v1/conversations"
headers = {"Authorization": f"Bearer {API_KEY}"}
base_params = {
    "limit": 50,
    "type": "EXTERNAL",
    "startedAfter": "2024-01-01T00:00:00Z",
}

cursor = None
all_conversations = []

while True:
    params = base_params.copy()
    if cursor:
        params["cursor"] = cursor

    resp = requests.get(BASE, headers=headers, params=params)
    resp.raise_for_status()
    data = resp.json()

    all_conversations.extend(data["conversations"])

    if not data["pagination"]["hasMore"]:
        break
    cursor = data["pagination"]["nextCursor"]

print(f"Fetched {len(all_conversations)} conversations")

Paginated endpoints

These endpoints use cursor-based pagination:

Best practices