DocsText conversations

Guide

Text conversations

The same agent, the same flow and the same fields, exchanged as typed messages. Your system carries the messages between the person and the API, one turn at a time.

How it works

A text conversation is for surfaces where people type, such as a chat widget or a messaging bot. You start it, show the agent's line to the person, send back what they typed, and repeat until the flow ends.

Each request returns the agent's next line together with every field collected so far, so you always hold the current state.

A conversation
Recorded as
A call with channel "api_text"
Its id
callId, also the id in GET /v1/calls
Who speaks first
The agent
Messages
One at a time; a second gets 409
Idle limit
15 minutes, then it is closed
When it ends
call.completed is sent to your webhooks

Start a conversation

POST /v1/conversations takes the agentId and the flow's variables, and optionally a model. The response already contains the agent's opening line in reply. Keep callId: it identifies the conversation in every later request.

Warning · Variables must be strings here

Unlike POST /v1/calls, this endpoint does not convert numbers or booleans. If any value in variables is not a string, the whole object is ignored and the response is 400 Missing variables naming every variable. Send "9", not 9.

There is no metadata on a conversation. Keep the link between callId and your own record on your side.

POST /v1/conversationscURL
curl --fail-with-body "http://localhost:4000/v1/conversations" \  -X POST \  -H "Authorization: Bearer $OXUMI_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "agentId": "81ee2426-7abe-444b-96f8-b8e195ddde49",    "variables": {      "driver_name": "Ramesh",      "company": "Shakti Logistics",      "route": "Nagpur to Hyderabad",      "planned_eta": "tonight at 9 pm"    }  }'
201ResponseExample
{  "callId": "5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0",  "reply": "Namaste Ramesh ji, this is the automated assistant from Shakti Logistics, calling for a quick update on your Nagpur to Hyderabad trip. Where have you reached?",  "fields": {},  "step": "ask_location",  "ended": false,  "outcome": null}

Relay each message

Send what the person typed as text to POST /v1/conversations/:id/messages. The response is the agent's reply and the updated state.

  • fields holds everything collected so far, not only what this message added.
  • step is the id of the flow step the conversation is now on.
  • ended turns true on the final reply, and outcome is set at the same moment. Until then outcome is null.

Send one message at a time. A message that arrives while the previous one is still being answered gets 409. The reply comes back whole; it is not streamed.

POST /v1/conversations/5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0/messagescURL
curl --fail-with-body "http://localhost:4000/v1/conversations/5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0/messages" \  -X POST \  -H "Authorization: Bearer $OXUMI_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "text": "Just crossed the Adilabad toll."  }'
200ResponseExample
{  "callId": "5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0",  "reply": "Thank you. Will you reach by nine tonight?",  "fields": {    "current_location": "Adilabad toll"  },  "step": "ask_schedule",  "ended": false,  "outcome": null}

How a conversation ends

A conversation ends in one of four ways. Each of them sends the webhook.

  • The flow finishes. The reply has ended: true and the flow's outcome. Nothing more is needed from you.
  • You end it. DELETE /v1/conversations/:id closes it, for instance when the person leaves the chat. The outcome is partial if any field was collected and failed if none was.
  • It goes quiet. After 15 minutes without a message it is closed the same way. Idle conversations are swept once a minute, so this can take up to a minute longer.
  • The model cannot be reached. The request returns 502 and the conversation is closed with outcome failed.

After any of these, a message to the same id gets 410. Start a new conversation instead.

200The final replyExample
{  "callId": "5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0",  "reply": "Thank you, your update is recorded. Drive safe.",  "fields": {    "current_location": "Adilabad toll",    "on_schedule": true,    "needs_help": false  },  "step": "goodbye",  "ended": true,  "outcome": "completed"}
DEL /v1/conversations/5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0cURL
curl --fail-with-body "http://localhost:4000/v1/conversations/5d2c9a44-8e1b-4f0a-b7c3-91e6a2d4f8b0" \  -X DELETE \  -H "Authorization: Bearer $OXUMI_API_KEY"
410A message after the endCaptured
{  "message": "This call has ended or expired. Start a new one.",  "error": "Gone",  "statusCode": 410}

Limits

Text onlyThere is no audio in or out on these endpoints.
Held in one server's memoryA conversation lives on the server that started it. After a restart the next message gets 410.
One message at a timeWait for each reply before sending the next message.
A model provider must be connectedOtherwise starting returns 400 naming the provider. No telephony or speech is needed.