Send a webchat message

View as Markdown
Sends a visitor's message into a webchat conversation and returns the AI agent's reply in the same response. The call blocks while the model writes, typically a few seconds. **Choosing the thread.** Send `visitorId` to start or continue the thread keyed `webchat_<visitorId>`, or `conversationId` (from a previous response) to continue that exact conversation. At least one is required. If `conversationId` does not exist in the workspace, a thread keyed by `visitorId` (or by the id itself) is used, **creating a new conversation with a different id**. Always keep the `conversationId` from the latest response. A `closed` thread is reopened by the next message. **Agent.** `agentId` picks the agent that answers and binds it to a thread that has none yet. It never replaces an agent already bound. Without any agent, a generic assistant answers without inventing business details. A paused agent, a deleted agent or a visitor on the exclusion list get a fixed notice instead of an AI reply. Messages longer than 4000 characters are truncated to 4000 before processing. A message made only of whitespace passes validation but fails processing, so trim before sending. **Side effects.** Stores the visitor's message and the reply. Calls the LLM (or the agent's voice-engine chat agent) and may run the agent's tools and knowledge-base lookups. Each model-written reply spends **one AI message** of the plan's monthly allowance. Fixed notices spend none. Broadcasts a realtime update to the dashboard and writes an audit entry. **Idempotency.** Not idempotent. A retry stores the visitor's message again, generates a new reply and spends another AI message. **Webhook events.** `audit.log_recorded` for subscribers that selected it explicitly. See [Webhooks](/webhooks). **Access** - **Required scope:** `write`. - **Rate limit:** General API (120–600 requests/min per workspace by plan) **and** the webchat limiter — 20 requests/min per client IP. See [Rate limits](/rate-limits). - **Plan:** Available on every plan. Requires an active plan with AI messages left; otherwise 403 `BILLING_ERROR`.

Authentication

AuthorizationBearer
Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

Request

At least one of conversationId or visitorId is required.

messagestringRequired1-5000 characters
The visitor's text. Accepted up to 5000 characters, but only the first 4000 are processed and stored.
conversationIdstringOptionalformat: "uuid"

Id of the conversation to continue, as returned by a previous call. Takes precedence over visitorId when it exists in the workspace.

visitorIdstringOptionalformat: "^[a-zA-Z0-9_-]+$"1-100 characters

Your stable key for the visitor (letters, digits, _, -). Trimmed. An empty string is treated as absent.

agentIdstringOptionalformat: "uuid"

Agent that answers. Must be a non-deleted agent of the workspace, or the call returns 403. Only binds threads that have no agent yet.

metadatamap from strings to stringsOptional

Accepted for forward compatibility; currently ignored and not stored.

Response

The agent's reply.
dataobject

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
429
Too Many Requests Error
500
Internal Server Error