Chat API
Chat API
The Chat API runs a text conversation with an agent over plain REST — same brain, knowledge bases (RAG) and tools as a voice call, no WebSocket, no audio. Build your own chat UI or bot on top of an agent without running your own RAG pipeline.
All endpoints live under /api/v1 and authenticate with the X-API-Key header (call them from your server, never the browser) — see Authentication. Responses are flat JSON (no {success,data} envelope). Conversations appear in Call history as chat with the full transcript, billing and post-call analysis.
For a step-by-step build, see Guide: Build a chat bot. To embed a ready-made chat widget instead of building your own UI, enable Text chat in the agent's Publish panel.
Using the SDKs? The Node & Python backend SDKs wrap these endpoints —
tn.chat.send(...)/tn.chat(...), plus a built-in send-loop helper (chatLoop/chat_conversation) that handles the410restart and409retry for you. The raw REST below is the same thing without the SDK.
Send a message
POST /api/v1/chat
First message — creates the session
Omit sessionId; the response returns one. identifier is your unique id for the end user (1–128 chars) — it binds the session to that user so a leaked sessionId can't be reused by someone else.
curl -X POST https://api.telenow.ai/api/v1/chat \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "agentId": "…", "identifier": "user-42", "input": "Hello!" }'
{ "sessionId": "…", "reply": "Hi! How can I help?", "turn": 1, "identifier": "user-42" }
Subsequent messages
Send the returned sessionId (with the same identifier); the agent keeps the full conversation context.
curl -X POST https://api.telenow.ai/api/v1/chat \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "agentId": "…", "identifier": "user-42", "sessionId": "…", "input": "Tell me more" }'
Request fields
| Field | Type | Notes |
|---|---|---|
agentId | UUID | Required. Must belong to your org and be active |
identifier | string | Required. Your unique end‑user id, 1–128 chars |
input | string | Required. The user's message |
sessionId | UUID | Omit on the first message; send the returned id afterwards |
variables | object | First message only — { "name": "value" } map for the agent's context variables. Missing required variables → 400 listing their names |
Response
{ "sessionId": "…", "reply": "…", "turn": 2, "identifier": "user-42" }
turn counts the user messages the session has seen (1‑based).
Get the transcript
GET /api/v1/chat/:sessionId/messages
Returns the full user/assistant transcript (system messages are omitted). Scoped to your org by the key — a session that belongs to another org returns 404.
{
"sessionId": "…",
"messages": [
{ "role": "user", "content": "Hello!", "createdAt": "2026-06-13T10:00:01Z" },
{ "role": "assistant", "content": "Hi! How can I help?", "createdAt": "2026-06-13T10:00:03Z" }
]
}
End a conversation
POST /api/v1/chat/:sessionId/end
Ends the session through the same teardown as a widget close — duration, billing settlement and post‑call analysis all run. Idempotent: ending an already‑ended session still returns 200. Only chat-API sessions can be ended here; pointing it at a voice session returns 404.
{ "sessionId": "…", "ended": true }
Sessions you never end explicitly are closed automatically after 30 minutes of inactivity (or at the agent's configured max duration, if set). Calling end promptly is good hygiene — it settles billing and triggers analysis immediately rather than waiting for the idle timeout.
Errors
Errors return { "error": "…" } with the status code:
| Status | When | What to do |
|---|---|---|
400 | Missing/invalid field, inactive agent, missing required variables (names listed) | Fix the request |
401 | Missing or invalid API key | Check X-API-Key |
403 | identifier doesn't match the session's bound end user | Use the identifier the session was created with |
404 | Unknown agent/session, or it belongs to another org | Check the ids |
409 | { "error": "turn in progress" } — a reply is still being generated for this session | Wait for the in‑flight reply, then retry |
410 | { "error": "session expired", "code": "SESSION_EXPIRED" } — the session ended, idled out, or the server restarted | Restart: resend the message without sessionId to start a fresh session, then continue with the new id |
Notes
- Replies are synchronous — the HTTP response returns when the agent's full reply (including any tool calls) is ready. Use a generous client timeout (60 s+).
- One turn at a time per session: serialize your sends per
sessionIdand handle409by waiting. - The agent's HTTP tools, knowledge bases and context variables all work exactly as on voice calls; voice‑only native tools (transfer, hangup) are unavailable in chat.
- Chat sessions fire the same webhook events as calls —
call.startedwhen the session is created,tool.invokedper tool call, andcall.ended+call.analyzedat teardown — so you can ingest chat outcomes alongside voice.
Related
- Guide: Build a chat bot — end-to-end recipe with a loop and error handling.
- Backend SDKs → Text chat — the Node/Python wrappers (
tn.chat,chatLoop/chat_conversation). - Publishing & embedding — the ready-made chat widget if you don't want a custom UI.
- Authentication — how
X-API-Keyworks and which key roles are allowed. - Context variables · Knowledge bases · Tools.