public
POST /v1/public/chat-agents/{publicKey}/messages
One visitor turn — a question, and the answer from that site's own pages.
Authentication
This endpoint is public. It takes no credential and no organisation — it is what our own marketing site and AI answer engines read.
This endpoint takes no organisation id. Your key already identifies the organisation it belongs to, and the response is scoped to it.
Try it
Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.
curl -X POST https://api.zinndigital.com/v1/public/chat-agents/{publicKey}/messages \
-H "Content-Type: application/json" \
-d '{ "message": <string> }'Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console
Details
The agent answers only from content belonging to this one site. That is enforced in the database query, not by instructing the model, so there is no phrasing a visitor can use to reach another customer's content. handoff_suggested is its own field and is not an error. It is true when the agent could not find the answer on the site — nothing is broken, those pages simply do not say — and the right response is to offer a person, never a guess. refusal is present only when the turn was refused rather than answered, and names the class so a widget can render the right thing: provider_outage, credential_problem, refused (a deliberate decline, such as a monthly cap reached) or unavailable (our fault, and no vendor is named). Answers 404 for an unauthorised Origin, exactly as the config route does and for the same reason.
Parameters
| Name | Type | Required | What it is |
|---|---|---|---|
publicKey (path) | string | Yes | The agent's public key, as carried in the embed snippet. |
Request body
| Name | Type | Required | What it is |
|---|---|---|---|
message | string | Yes | — |
conversation_id | string | No | Continue an existing thread. Omit to start one. |
locale | string | No | The visitor's language. The agent answers in this, not in the site owner's language. |
page_url | string | No | — |
Response
| Name | Type | Required | What it is |
|---|---|---|---|
conversation_id | string | Yes | — |
reply | string | Yes | — |
citations | object[] | Yes | The pages of this site the answer was drawn from. |
handoff_suggested | boolean | Yes | ⛔ Not an error. true means the agent could not answer from this site's content and a person should take over. Rendering it as a fault would blame a vendor outage for an… |
refusal | string<provider_outage, credential_problem, refused, unavailable> | No | Present only when the turn was refused rather than answered. refused is a deliberate decline of ours (a monthly cap reached, an agent switched off) and names no vendor;… |
failure | VendorFailure | No | The classified §2.57 failure behind a refusal — which vendor, whose key, which door. ⛔ Returned ONLY by the owner's preview endpoint; the public widget endpoint never carries it,… |
Errors this endpoint can return
404 · 429