Sends one visitor message in a session from `POST /widget/init` and returns the agent's reply
synchronously. Operator replies typed later in the dashboard do not come back here; pick them up with
`GET /widget/poll`.
Send `application/json` for text. To attach one image (PNG, JPG, WEBP, GIF, HEIC, HEIF, AVIF, TIFF) or PDF of up
to 10 MB, send `multipart/form-data` with the file in `file` and the other fields as form fields;
`message` is still required. HEIC/AVIF/TIFF are converted and photos rotated upright before the agent
reads them. A file over 10 MB is cut off by the upload parser and currently fails with 500 rather than
the 413 body.
Credentials, origin check and per-minute limits are the same as `POST /widget/init`; see there.
**Side effects.** On the first message creates the `webchat` conversation (bound to the widget's agent)
and links it to the session; stores the visitor message and the reply; calls the language model; draws
one AI message from the workspace's monthly allowance when a model wrote the reply; if the session has
`metadata.email`, finds or creates the contact. The reply is also pushed to other open tabs of the
session over the widget WebSocket. When the workspace is out of AI messages the visitor gets a neutral
503 and the workspace owner receives an in-app notification (once per day). No webhook event is emitted
for the message itself.
**Idempotency.** Not idempotent. A retry after a timeout stores the visitor message again, generates
a second reply and spends another AI message and another unit of the daily cap. De-duplicate replies
by `message_id`.
**Access**
- **Required scope:** None; `jl_` API keys are not used. The widget credential plus a matching `x-widget-parent-origin` authorise the call.
- **Rate limit:** Widget public — 60 requests/min per IP, the widget's `rate_limit_rpm` per credential, 300 requests/min per workspace, plus a daily cap on widget messages per workspace (5,000 by default, resets at 00:00 UTC); the general limiter also counts 120 requests/min per IP. See [Rate limits](/rate-limits).
- **Plan:** Available on every plan. Replies draw from the plan's AI-message allowance.
This endpoint expects an object.
session_idstringRequiredformat: "uuid"
Session id returned by POST /widget/init.
messagestringRequired1-4000 characters
The visitor's text, 1 to 4000 characters. Required even when a file is attached.
agent_namestringOptional1-40 characters
Display name the UI shows for the agent (from branding.agent_names); the reply is signed with it and it is saved on the session.
langstringOptional2-10 characters
Primary language subtag of the visitor’s UI (es, en); used as the reply language and saved on the session.
identity_tokenstringOptional<=512 characters
Signed identity used only by Jelliu’s own in-app support widget. Integrations do not need it; an
invalid token, or one for another workspace, is ignored.
filestringOptionalformat: "binary"
multipart/form-data only. One image (PNG, JPG, WEBP, GIF, HEIC, HEIF, AVIF, TIFF) or PDF, up to 10 MB.