Poll for agent replies
Returns agent-side messages (AI replies and human operator replies from the dashboard) created at or
after since, oldest first, at most 50 per call. Visitor messages are not included, because the UI
already shows what the visitor typed. Before the visitor’s first message there is no conversation
and messages is empty.
Loop: pass the returned now as the next since. The boundary is inclusive, so a message can come back
twice; de-duplicate by id (and against message_id from POST /widget/message). If 50 messages come
back, poll again immediately with since set to the last message’s created_at.
Credentials, origin check and limits are the same as POST /widget/init. The session must belong to
the widget named by the credential. Each poll counts against the per-IP and per-widget budgets, so
poll every few seconds, not continuously.
Idempotency. Read-only; safe to retry.
Access
- Required scope: None;
jl_API keys are not used. The widget credential plus a matchingx-widget-parent-originauthorise the call. - Rate limit: Widget public — 60 requests/min per IP, plus the widget’s
rate_limit_rpmper credential and 300 requests/min per workspace. See Rate limits. - Plan: Available on every plan.
Headers
Secret widget API key (plaintext_api_key from POST /api/widgets). Takes precedence over
x-widget-id and wid. Send one of the three. Never expose it in a browser.
Public widget id, the credential the embed script uses. Used when x-widget-api-key is absent.
Origin of the page embedding the widget. Must match one of the widget’s allowed_origins; see POST /widget/init.
Query parameters
Session id from POST /widget/init. Not a UUID returns 400 Invalid query.
ISO 8601 UTC timestamp (for example the previous response’s now). Messages created at or after it
are returned. Omitted means from the start of the conversation. A value that is not an ISO datetime
with Z returns 400 Invalid query.
Response
New agent messages (possibly none).

