This is the reference for behavior shared by every Sybill API endpoint - consult it when a call doesn't behave the way you expect.
Pagination
The conversations, deals, accounts, messages, rows, and documents list endpoints use cursor-based pagination. Every list response includes the same pagination object alongside the results:
{ "conversations": [ ... ], "pagination": { "nextCursor": "eyJzZWFyY2hBZnRlciI6...", "hasMore": true } }
To fetch the next page, pass nextCursor back as the cursor query parameter. Check hasMore - not nextCursor - to decide whether more pages exist.
curl -H "Authorization: Bearer sk_live_YOUR_KEY" \ "https://api.sybill.ai/v1/conversations?limit=50&cursor=eyJzZWFyY2hBZnRlciI6..."
Rules that keep iteration correct:
Repeat your filters on every page. Cursors mark a position; they do not remember the filters from the first request.
Cursors are opaque. Don't parse, construct, or store them as long-term bookmarks - use each one promptly, within the same iteration.
Records added or deleted while you paginate can affect later pages. On document lists specifically, records sharing a creation timestamp at a page boundary may be repeated or skipped.
Page sizes: the maximum limit is 50 everywhere. Defaults differ - conversations, deals, and accounts default to 20; messages, rows, and documents default to 50. The sources and object-types lists are not paginated.
Rate limits
Data endpoints enforce per-key limits using a moving window. All rate-limited requests made with the same key share one set of counters, regardless of scope or endpoint. Health checks (GET /v1/health) don't count.
Window | Limit |
Per minute | 60 requests |
Per hour | 1,000 requests |
Per day | 10,000 requests |
When you exceed a limit, the API returns 429 Too Many Requests with the body {"detail": "Rate limit exceeded"} and these headers:
Header | Meaning |
| Maximum requests allowed in the current window |
| Requests remaining in the current window |
| Unix timestamp when the window resets |
| Seconds to wait before retrying |
Handle 429s by waiting the Retry-After period and backing off exponentially on repeats. To stay under the limits: cache responses where you can, use the most specific endpoint for your need instead of re-polling list endpoints, and use limit=50 when iterating so you make fewer requests.
HTTP status codes
Status | Meaning |
| Malformed request, validation failure, or invalid query parameter |
| API key is invalid or revoked |
| Authorization header missing, key lacks the required scope, or the resource belongs to another organization |
| Resource doesn't exist or isn't accessible to your organization |
| Duplicate or concurrent write |
| A |
| A |
| Request validation failed |
| Rate limit exceeded |
| Unexpected server error |
Error response formats
GET endpoints generally return a simple message:
{ "detail": "Conversation not found" }
POST, PATCH, and DELETE endpoints return structured details for 400, 403, 404, 409, 411, and 413:
{ "detail": { "error": "validation_error", "message": "exactly one of url or content must be provided", "field": null, "request_id": "01HV..." } }erroris a machine-readable code:validation_error,forbidden,conflict,not_found,length_required, orpayload_too_large.fieldnames the offending field when one applies.request_idis a correlation ID - include it when you contact support about a failed request.
422 responses use a list format instead, with each entry naming the location (loc), message (msg), and type of the validation failure.
Request conventions
Field naming is camelCase -
sourceId,remoteId,createdAfter- in query parameters and resource fields alike. Two documented exceptions stay snake_case:org_idin the health response andrequest_idin structured error details.Timestamps in responses are ISO 8601 strings in UTC unless an endpoint's schema says otherwise.
Timestamps in import request bodies (
createdAt,updatedAt,startedAt,endedAt,timestamp) also accept Unix seconds and Unix milliseconds; the format is auto-detected.POSTandPATCHbodies require aContent-Lengthheader and may not exceed 10 MB.
