Envelope, errors, pages

One response format, failure codes, cursor pagination and the limits.

The response envelope #

A successful answer always puts the content into data — even when it is a single object. Lists get nextCursor and hasMore next to it. A failure arrives in the same envelope with an error field carrying a machine code and an explanation.

Every response carries Cache-Control: no-store: they contain someone's conversation.

Response
{"data": { … }}
{"data": [ … ], "nextCursor": "2026-08-22T09:15:04.281Z", "hasMore": true}
{"error": {"code": "validation_error", "message": "content must not exceed 4096 characters"}}

Failure codes #

HTTPcodeWhen
400validation_errorthe body did not parse or a value does not fit
401unauthorizedno key, revoked or belonging to someone else
403insufficient_scopethe key has no scope for the method
404not_foundno such conversation, or it belongs to another site
409conversation_closedthe conversation is closed, the visitor will not see the reply
409no_visitorthe conversation has no widget visitor
413file_too_largethe file behind the link is over the limit
429rate_limit_exceededrate limit exceeded, see Retry-After
502file_fetch_failedthe file behind your link did not download
503storage_unavailablethe database or Redis is unreachable, retry later

Pages #

Pagination is cursor based, not page numbers: while the first page is being read visitors keep writing, and numbering would push some conversations past the reader. The cursor is the time of the last shown item in RFC 3339 with nanoseconds.

Take nextCursor from the answer and pass it as the cursor parameter while hasMore is true.

FieldTypeReq.Description
limitintnopage size: 25 by default, 100 at most
cursorstringnocontinuation: the nextCursor value of the previous answer

Limits #

WhatHow much
Requests per key300 per minute, then 429 with Retry-After
Page size25 by default, 100 at most
Reply length4096 characters
Request body256 KB
File behind a link50 MB
Signed attachment link lifetime1 hour
Waiting for your webhook handler20 seconds
Webhook delivery attempts3, a 5 second pause doubling after that
Webhook signature window5 minutes