Skip to Content
Kumoda Docs

API reference

The API channel (send a customer message, read the reply) with an OpenAPI file, and the endpoints the website chat window uses.

Kumoda has one API you build on: the API channel. Your own system sends a customer's message to one of your agents and reads the reply. It is the same conversation as on WhatsApp or the website chat window, with the same credits and the same handover to a person.

The OpenAPI file is at /openapi.json. Import it into Postman, Insomnia or any OpenAPI tool.

The API channel is for servers. It gives no browser (CORS) access, so call it from your backend, not from a web page. To put a chat on a web page, use the website chat window.

Set it up

Create the connection in the app: Channels, Add channel, API, choose the agent, Create the API connection (see Channels). You get two things:

  • the address, which has the form https://agents.kumoda.io/api/v1/agents/<key>/messages, where <key> is the letter a and 24 lowercase hex characters, and
  • the secret, which starts with ksk_. It is shown only once and only a hash is kept. New secret replaces it, and the old one stops working at once.

Every call carries the secret as a bearer token: Authorization: Bearer ksk_…. A wrong key and a wrong secret get the same answer, so neither can be guessed from it.

An agent has one API connection, and an account can have up to 10. A paused connection refuses new messages (503).

Send a message

POST /api/v1/agents/<key>/messages with a JSON body.

FieldRequiredWhat it is
contactyesYour own id for the customer: 3 to 60 letters, numbers, dots, dashes, colons or underscores. Each contact is one conversation.
textyesThe customer's message. Over 4,000 characters is refused (413). Only the first 1,500 characters are given to the agent.
namenoThe customer's name, up to 80 characters.
emailnoThe customer's email. Ignored if it is not a valid address.
phonenoThe customer's phone number, up to 30 characters. Only digits, +, spaces, brackets and dashes are kept.
messageIdnoYour id for this message (up to 64 letters, numbers, dots, dashes, colons or underscores). Sending the same one again is not answered twice, so a retry is safe.
waitnoSeconds to wait for the reply, up to 25. The default is 20. Use 0 to return straight away and read the reply later.

Give an email or phone and the customer becomes a contact in Kumoda.

curl -X POST https://agents.kumoda.io/api/v1/agents/YOUR_KEY/messages \
  -H "Authorization: Bearer YOUR_SECRET" -H "Content-Type: application/json" \
  -d '{"contact":"customer-123","text":"Hi, are you open today?","name":"Ada","email":"ada@example.com"}'

The message is saved before the call answers. The answer is a JSON object with a status:

statusMeaning
repliedThe reply is in reply. from says who wrote it (agent or human), and id is its message id.
pendingNo reply yet (the wait ran out). Read it with GET.
duplicateThis messageId was already sent. Nothing new was saved.
with_a_personA person has taken the conversation over, so the agent will not answer.
{ "status": "replied", "reply": "Yes, we are open until 6pm today.", "from": "agent", "id": 1042 }

Read a conversation

GET /api/v1/agents/<key>/messages?contact=customer-123&after=0

Returns the contact's messages after a message id, oldest first, up to 100. Pass the largest id you have seen as after to read only what is new.

{
  "messages": [
    { "id": 1041, "from": "customer", "text": "Hi, are you open today?", "at": "2026-11-12T09:30:02.114Z" },
    { "id": 1042, "from": "agent", "text": "Yes, we are open until 6pm today.", "at": "2026-11-12T09:30:05.870Z" }
  ]
}

from is customer, agent or human (a person from your team).

Errors and limits

Errors are a JSON object with a message: { "error": "…" }.

StatusWhen
400A field is wrong or missing (for example contact, text, messageId), or the body is not JSON.
401The key or the secret is wrong.
404The address is not an API channel address.
405A method other than POST and GET.
413The text is over 4,000 characters, or the request body is over 16,000 bytes.
429More than 120 requests a minute on this connection (sending and reading share it).
503The connection is paused or not connected.

Beyond these:

  • Every reply uses your credits. When credits run out, the agent stops answering and a short note goes to the customer (see Plans, credits and billing).
  • Each conversation is answered at most 6 times a minute and 150 times a day. After that, messages are saved but not answered, and the channel shows a note.
  • You can take over any conversation from Conversations. While a person has it, POST answers with with_a_person.

The website chat window's endpoints

The chat window is one small script that you paste into your site (see Channels). It talks to these routes, which are listed here so you can see what it does. They are for that script, and you do not need to call them yourself.

RouteWhat it does
GET /widget.jsThe script itself.
GET /widget/<key>/configThe window's title, greeting, colour, whether it asks for a name, and whether it is online. Public: nothing secret is in it.
POST /widget/<key>/messagesA visitor wrote. Takes visitor (a random 32-character hex id the script keeps in the visitor's browser), text (up to 1,000 characters), and optionally name, email and phone. Answers { "ok": true }.
GET /widget/<key>/messages?visitor=…&after=…The visitor's messages after an id, each from visitor, team or agent, with human (a person has the chat) and online.

The <key> here is a letter w and 24 hex characters. If you list Websites that may show it in the window's settings, a request from any other website is refused (403). A paused window answers 503.

Visitors are limited by address and by conversation, and a window has an hourly cap on messages. The numbers are kept inside the platform and may change, so build on the API channel above if you need to send messages yourself.

On this page