API reference
A REST API over the same data the interface uses: conversations, the knowledge base, everything the assistant has been taught, and the work it produced. JSON in, JSON out.
Base URL
https://api.enterchat.io/v1Rate limit
600 req / min
Format
JSON · UTF-8
Demo workspaces
This deployment carries five sample businesses instead of one, each with its own conversations, knowledge base, lessons and autonomy settings. In production the workspace is determined by your API key; here you select it with a business query parameter. Omit it and you get the default workspace.
| salon | Studio Lucia | Hair salon · Zagreb | loc_8f21c |
| market | Market Klas | Grocery shop · Zagreb | loc_3d92a |
| autoparts | Auto Dijelovi Delta | Car parts · Rijeka | loc_6b41f |
| restaurant | Konoba Fjaka | Restaurant · Split | loc_9c78d |
| gym | Fit Centar Puls | Gym · Zagreb | loc_2a55e |
curl "https://api.enterchat.io/v1/conversations?business=restaurant&status=needs_human" \ -H "X-API-Key: ech_live_your_key_here"
Conversation ids are unique across workspaces, so /conversations/{id} resolves without the parameter. An unrecognised business value returns 422 rather than falling back to the default.
Authentication
Server-to-server calls use an API key. Keys are created in Settings, shown once, and scoped to a single workspace.
X-API-Key: ech_live_your_key_here
Browser sessions
Authorization: Bearer <session_token>
Pagination
List endpoints return a paginated envelope. Pass page and per_page; per_page is capped at 100.
GET https://api.enterchat.io/v1/conversations?page=2&per_page=25
{
"data": [ ... ],
"meta": {
"current_page": 2,
"per_page": 25,
"total": 8412,
"last_page": 337
}
}Errors
| 400 | bad_request | Malformed body or query string. |
| 401 | unauthenticated | Missing or invalid API key. |
| 403 | forbidden | Key is not scoped to this workspace. |
| 404 | not_found | No resource matches that identifier. |
| 422 | unprocessable | Validation failed; see error.fields. |
| 429 | rate_limited | Retry after the seconds given in Retry-After. |
{
"error": {
"code": "unknown_business",
"message": "No demo workspace with id bakery.",
"fields": {
"business": ["Must be one of: salon, market, autoparts, restaurant, gym"]
}
}
}Inbound webhook
/webhooks/whatsappReceives inbound messages in Meta's own envelope. Validates the envelope and acknowledges — which is what a production handler does before queueing, since Meta only needs a 200.
Example request
curl -X POST "https://api.enterchat.io/v1/webhooks/whatsapp" \
-H "Content-Type: application/json" \
-d '{
"object": "whatsapp_business_account",
"entry": [{
"id": "1029384756102938",
"changes": [{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"messages": [{
"from": "385914820117",
"id": "wamid.HBgLMzg1OTE0ODIwMTE3",
"timestamp": "1786139640",
"text": { "body": "Imate li slobodno u subotu?" }
}]
}
}]
}]
}'Example response
{
"accepted": true,
"applied": false,
"message": "1 inbound message(s) was accepted but not persisted — this deployment runs in demo mode.",
"demo": true
}/webhooks/whatsappMeta's subscription handshake. Real, because a webhook that cannot complete a verification challenge is not a webhook.
Query parameters
| hub.mode | string | subscribe |
| hub.verify_token | string | Your configured token |
| hub.challenge | string | Echoed back verbatim |
Example request
curl "https://api.enterchat.io/v1/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=your_token&hub.challenge=1158201444"
Example response
1158201444
Conversations
/conversationsLists conversations, newest first.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
| status | string | resolved_by_bot · booked · awaiting_customer · needs_human · handled_by_human |
| intent | string | booking · pricing · hours · availability · complaint · … |
| after_hours | boolean | true returns only what arrived while closed |
| page | integer | Default 1 |
| per_page | integer | Default 25, max 100 |
Example request
curl "https://api.enterchat.io/v1/conversations?after_hours=true&per_page=1" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "conv_sal_01",
"intent": "booking",
"status": "booked",
"afterHours": true,
"startedAt": "2026-08-06T22:14:00Z",
"lastMessageAt": "2026-08-06T22:19:00Z",
"windowExpiresAt": "2026-08-07T22:19:00Z",
"contact": { "name": "Marina Kovač", "phone": "+385 91 ••• ••42", "returning": false },
"bookingId": "bkg_sal_01",
"messages": [ ... ]
}
],
"meta": { "current_page": 1, "per_page": 1, "total": 3, "last_page": 3 }
}/conversations/{id}Returns one conversation with every message, including the confidence and sources on each assistant reply.
Example request
curl "https://api.enterchat.io/v1/conversations/conv_sal_01" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": {
"id": "conv_sal_01",
"messages": [
{
"id": "msg_sal_01_2",
"author": "bot",
"confidence": 0.96,
"heldForReview": false,
"sources": [
{ "kind": "hours", "label": { "en": "Opening hours · Saturday 09:00–14:00" } },
{ "kind": "knowledge", "refId": "kb_sal_03", "label": { "en": "Service durations" } }
],
"text": { "en": "Good evening! Cut and colour together takes…", "hr": "…" }
}
]
},
"business": "salon"
}Knowledge
/knowledgeEverything the assistant is allowed to say, with where each answer came from — written by hand, imported from a file, or learned from a correction.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/knowledge?business=salon" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "kb_sal_02",
"topic": { "en": "Price list · Colour" },
"questions": [ { "en": "How much is balayage?" } ],
"answer": { "en": "Roots €55. Full colour €70. Balayage €95 medium length…" },
"source": "imported",
"importedFrom": "src_sal_02",
"usedCount": 512
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 12, "last_page": 1 }
}/gapsQuestions customers keep asking that the knowledge base cannot answer, ranked by how often. This is the backlog that makes the assistant better.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/gaps?business=market" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "gap_mkt_02",
"question": { "en": "Is what is on the shelf today in stock?" },
"askCount": 96,
"escalations": 58,
"lastAskedAt": "2026-08-07T09:18:00Z",
"exampleConversationId": "conv_mkt_03"
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 5, "last_page": 1 }
}Training
/training/sourcesFiles the workspace has been taught from — WhatsApp exports, price list PDFs, screenshots. Imports are reversible, so this is also the list of what can be revoked.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
| status | string | queued · reading · mapping · ready · failed |
Example request
curl "https://api.enterchat.io/v1/training/sources?business=salon" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "src_sal_01",
"filename": "WhatsApp Chat - Studio Lucia.txt",
"kind": "whatsapp_export",
"status": "ready",
"stats": { "conversations": 1284, "messages": 9418, "topicsFound": 31, "gapsFound": 7 }
},
{
"id": "src_sal_04",
"filename": "stari-cjenik-2023.docx",
"kind": "docx",
"status": "failed",
"error": { "en": "Prices in this file contradict cjenik-2026.pdf on 9 services…" }
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 4, "last_page": 1 }
}/training/topicsThe topic map an import produced, least confident first. Filter status=proposed to get exactly the decisions still waiting on a person.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
| status | string | proposed · approved · edited · rejected |
| source_id | string | Narrow to one import |
Example request
curl "https://api.enterchat.io/v1/training/topics?business=salon&status=proposed" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "tm_sal_08",
"topic": { "en": "Hair extensions" },
"occurrences": 61,
"phrasings": [ { "en": "do you do extensions" } ],
"confidence": 0.19,
"status": "proposed",
"proposedAnswer": { "en": "No proposed answer — nothing in the imported chats gives a consistent answer…" }
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 3, "last_page": 1 }
}/lessonsEvery correction the workspace has taught, with what the assistant used to answer and what it answers now. Reversible by design — an assistant that changes behaviour with no visible record is one nobody can debug.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/lessons?business=gym" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "les_gym_01",
"origin": "human_takeover",
"trigger": { "en": "I want to cancel" },
"wasAnswering": { "en": "Cancellation is done in person at reception…" },
"nowAnswers": { "en": "Answer it straight and completely on the first message…" },
"appliedCount": 341,
"active": true
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 5, "last_page": 1 }
}/autonomyHow much rope each kind of question has earned. An intent climbs from draft to suggest to auto as its accuracy holds above the threshold, and falls back when corrections spike.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/autonomy?business=restaurant" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{ "intent": "booking", "state": "auto", "accuracy": 0.97, "sampleSize": 2104, "threshold": 0.94 },
{ "intent": "product_question", "state": "draft", "accuracy": 0.93, "sampleSize": 512, "threshold": 0.94, "pinned": true }
],
"meta": { "current_page": 1, "per_page": 25, "total": 10, "last_page": 1 }
}Work produced
/bookingsAppointments, delivery slots and reservations the conversations turned into.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/bookings?business=salon" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "bkg_sal_01",
"contactName": "Marina Kovač",
"service": { "en": "Cut and colour" },
"startsAt": "2026-08-08T08:30:00Z",
"durationMinutes": 150,
"status": "confirmed",
"bookedByBot": true,
"conversationId": "conv_sal_01"
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 7, "last_page": 1 }
}/leadsEverything that showed intent and did not end in a booking, with the conversation attached — including the ones lost because nobody had written the answer down.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/leads?business=autoparts" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{
"id": "led_aut_01",
"contactName": "Alen Kovačević",
"intent": "pricing",
"stage": "quoted",
"valueEur": 1574,
"conversationId": "conv_aut_07",
"sentToCrm": true
}
],
"meta": { "current_page": 1, "per_page": 25, "total": 5, "last_page": 1 }
}Workspace
/overviewThe dashboard figures, including the after-hours summary and the 24-hour window economics.
Query parameters
| business | string | Demo only. salon · market · autoparts · restaurant · gym. Defaults to salon |
Example request
curl "https://api.enterchat.io/v1/overview?business=salon" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": {
"messagesToday": 47,
"medianResponseSeconds": 8,
"deflectionRate": 84,
"conversionRate": 31,
"awaitingHuman": 2,
"afterHours": { "messages": 14, "resolved": 11, "booked": 2, "waiting": 1, "closedHours": 14 },
"window": { "resolvedInWindow": 412, "missedWindow": 23, "templateCostEur": 1.84 }
},
"business": "salon"
}/locationsEvery number the key can see. In demo mode that is all five sample workspaces, each carrying the value to pass as business elsewhere.
Example request
curl "https://api.enterchat.io/v1/locations" \ -H "X-API-Key: ech_live_your_key_here"
Example response
{
"data": [
{ "id": "loc_8f21c", "demo_business": "salon", "name": "Studio Lucia", "city": "Zagreb",
"phoneNumber": "+385 1 4820 117", "wabaId": "waba/1029384756102938" },
{ "id": "loc_9c78d", "demo_business": "restaurant", "name": "Konoba Fjaka", "city": "Split",
"phoneNumber": "+385 21 486 233", "wabaId": "waba/2049183756402918" }
],
"meta": { "current_page": 1, "per_page": 25, "total": 5, "last_page": 1 }
}/contactThe enquiry form behind the website. Validation is real; nothing is delivered.
Example request
curl -X POST "https://api.enterchat.io/v1/contact" \
-H "Content-Type: application/json" \
-d '{"name": "Lucia Marić", "email": "lucia@studiolucia.hr", "business": "Studio Lucia"}'Example response
{
"accepted": true,
"applied": false,
"message": "Your enquiry was accepted but not persisted — this deployment runs in demo mode.",
"demo": true
}