Skip to content

Chatbot

The Chatbot API allows you to configure automated responses, keyword rules, conversation flows, and AI-powered responses.

Retrieve current chatbot settings.

Terminal window
GET /api/chatbot/settings
{
"status": "success",
"data": {
"id": "uuid",
"account_id": "uuid",
"chatbot_enabled": true,
"ai_enabled": true,
"ai_provider": "openai",
"ai_model": "gpt-4o-mini",
"ai_temperature": 0.7,
"ai_max_tokens": 500,
"system_prompt": "You are a helpful customer service assistant...",
"greeting_message": "Hello! Welcome to our support. How can I help you?",
"greeting_buttons": [
{"title": "Track Order"},
{"title": "Product Info"},
{"title": "Speak to Agent"}
],
"fallback_message": "Sorry, I didn't understand that. Please try again.",
"fallback_buttons": [
{"title": "Main Menu"},
{"title": "Speak to Agent"}
],
"transfer_keywords": ["agent", "human", "help"],
"business_hours_enabled": false
}
}

Both greeting_buttons and fallback_buttons support WhatsApp interactive buttons:

Button CountDisplay Type
1-3 buttonsQuick reply buttons
4-10 buttonsList menu

Each button requires only:

  • title: Display text (max 20 characters)

The id is auto-generated by the system.

Update chatbot settings.

Terminal window
PUT /api/chatbot/settings
{
"chatbot_enabled": true,
"ai_enabled": true,
"ai_provider": "anthropic",
"ai_model": "claude-3-5-sonnet-latest",
"ai_temperature": 0.7,
"system_prompt": "You are a helpful assistant for our e-commerce store...",
"greeting_message": "Welcome! How can I assist you today?",
"greeting_buttons": [
{"title": "My Orders"},
{"title": "Get Support"}
],
"fallback_message": "I'm not sure I understand. Please choose an option:",
"fallback_buttons": [
{"title": "Main Menu"}
]
}
Terminal window
GET /api/chatbot/keywords
{
"status": "success",
"data": {
"items": [
{
"id": "uuid",
"name": "Greeting Response",
"keywords": ["hello", "hi", "hey"],
"match_type": "contains",
"response_type": "text",
"response": "Hello! How can I help you today?",
"priority": 10,
"enabled": true
}
]
}
}
Terminal window
POST /api/chatbot/keywords
{
"name": "Business Hours",
"keywords": ["hours", "open", "when"],
"match_type": "contains",
"response_type": "text",
"response": "We're open Monday-Friday, 9 AM to 6 PM EST.",
"priority": 5,
"enabled": true
}
TypeDescription
exactMessage must match keyword exactly
containsMessage contains the keyword
starts_withMessage starts with the keyword
regexRegular expression pattern match
Terminal window
PUT /api/chatbot/keywords/{id}
Terminal window
DELETE /api/chatbot/keywords/{id}

AI Contexts provide additional knowledge to the AI for specific topics.

Terminal window
GET /api/chatbot/ai-contexts
{
"status": "success",
"data": {
"items": [
{
"id": "uuid",
"name": "Product Catalog",
"trigger_keywords": ["product", "price", "buy"],
"context_type": "static",
"content": "Our products include...",
"priority": 10,
"enabled": true
}
]
}
}
Terminal window
POST /api/chatbot/ai-contexts
{
"name": "Shipping Policy",
"trigger_keywords": ["shipping", "delivery", "track"],
"context_type": "static",
"content": "We offer free shipping on orders over $50. Standard delivery takes 3-5 business days...",
"priority": 5,
"enabled": true
}
TypeDescription
staticFixed text content
apiFetched from external API
Terminal window
PUT /api/chatbot/ai-contexts/{id}
Terminal window
DELETE /api/chatbot/ai-contexts/{id}
Terminal window
GET /api/chatbot/flows
Terminal window
POST /api/chatbot/flows

Flows are stored as a graph: nodes (each with an id, type, and type-specific config) connected by edges labelled with the outcome they handle. Execution starts at entry_node and walks edges until a node yields (waiting on user input) or terminates.

{
"name": "Feedback Collection",
"trigger_keywords": ["feedback", "review"],
"initial_message": "Hi! I'd like to collect your feedback.",
"completion_message": "Thank you for your feedback!",
"enabled": true,
"graph": {
"version": 2,
"entry_node": "rating",
"nodes": [
{
"id": "rating",
"type": "buttons",
"label": "Ask for rating",
"position": {"x": 0, "y": 0},
"config": {
"body": "How would you rate your experience?",
"buttons": [
{"id": "excellent", "title": "Excellent"},
{"id": "good", "title": "Good"},
{"id": "poor", "title": "Poor"}
]
}
},
{
"id": "comment",
"type": "prompt",
"label": "Collect comment",
"position": {"x": 250, "y": 0},
"config": {
"body": "Any additional comments?",
"store_as": "comment"
}
},
{
"id": "handoff",
"type": "transfer",
"label": "Transfer to team",
"position": {"x": 500, "y": 0},
"config": {
"body": "Connecting you with our team…",
"team_id": "<uuid>",
"notes": "Rating: {{rating}}"
}
}
],
"edges": [
{"from": "rating", "to": "comment", "condition": "button:excellent"},
{"from": "rating", "to": "comment", "condition": "button:good"},
{"from": "rating", "to": "handoff", "condition": "button:poor"},
{"from": "comment", "to": "handoff", "condition": "default"}
]
}
}

Every node has the shape { "id", "type", "label", "position", "config" }. The config schema depends on type.

TypePurposeKey config fieldsOutgoing edge conditions
messageSend a templated text message.messagedefault
promptSend a question; wait for and validate a reply.body, store_as, validation_regex, validation_error, max_retriesdefault, max_retries
buttonsInteractive reply buttons.body, buttons: [{id,title}]button:<id> per button
api_callHTTP request with response capture + optional templated reply.url, method, headers, body, response_mapping, message_templatehttp:2xx, http:non2xx
conditionBoolean expression branch (expr-lang syntax) over session data.expressiontrue, false
timingBusiness-hours routing.schedule: [{day,enabled,start_time,end_time}]in_hours, out_of_hours
whatsapp_flowSend a native WhatsApp Flow form.flow_id, header, body, ctadefault
transferHand off to a team / queue and end the session.body, team_id, notes(terminal)
goto_flowJump to another flow in the same org/account.flow_id(handled internally)
webhookFire-and-forget HTTP call; result ignored.url, method, headers, bodydefault
endOptionally send a final message and terminate.message(terminal)

For a node N that produces outcome O, the runtime picks the first edge in edges where from == N.id && condition == O. If no exact match exists it falls back to a condition: "default" edge. With no match at all the session terminates as completed.

A transfer node ends the flow and creates an agent transfer:

{
"id": "handoff",
"type": "transfer",
"config": {
"body": "Connecting you with our support team…",
"team_id": "<uuid>",
"notes": "From flow: {{variable_name}}"
}
}
FieldDescription
bodyOptional message sent to the user before handoff (templated).
team_idTarget team UUID. Omit or set to "_general" for the shared queue.
notesInternal notes for agents (supports {{variable}} placeholders).

Configure which session variables are displayed in the Contact Info Panel:

{
"panel_config": {
"sections": [
{
"id": "section-1",
"label": "Customer Info",
"columns": 1,
"collapsible": true,
"default_collapsed": false,
"order": 1,
"fields": [
{"key": "customer_name", "label": "Name", "order": 1, "display_type": "text"},
{"key": "status", "label": "Status", "order": 2, "display_type": "badge", "color": "success"}
]
}
]
}
}
FieldTypeDescription
idstringUnique section identifier
labelstringDisplay label for the section
columnsnumberLayout columns (1 or 2)
collapsiblebooleanAllow section to be collapsed
default_collapsedbooleanStart section in collapsed state
ordernumberSection display order
fieldsarrayFields to display in this section
FieldTypeDescription
keystringSession variable name (from store_as or response mapping)
labelstringDisplay label for the field
ordernumberField display order within section
display_typestringHow to render the value: text (default), badge, or tag
colorstringColor for badge/tag: default, success, warning, error, or info

Get agent transfer requests.

Terminal window
GET /api/chatbot/transfers
ParameterTypeDescription
statusstringFilter by status: active or resumed
team_idstringFilter by team ID, or general for general queue
{
"status": "success",
"data": {
"transfers": [
{
"id": "uuid",
"contact_id": "uuid",
"contact_name": "John Doe",
"phone_number": "1234567890",
"status": "active",
"source": "flow",
"agent_id": null,
"agent_name": null,
"team_id": "uuid",
"team_name": "Sales Team",
"notes": "Interested in enterprise plan",
"transferred_at": "2024-01-01T12:00:00Z"
}
],
"general_queue_count": 3,
"team_queue_counts": {
"team-uuid-1": 5,
"team-uuid-2": 2
}
}
}

Manually transfer a conversation to a human agent or team.

Terminal window
POST /api/chatbot/transfers
{
"contact_id": "uuid",
"team_id": "uuid",
"notes": "Customer requested human support"
}
FieldTypeRequiredDescription
contact_iduuidYesThe contact to transfer
team_iduuidNoTarget team (omit for general queue)
notesstringNoInternal notes for agents

Pick the next unassigned transfer from the queue.

Terminal window
POST /api/chatbot/transfers/pickup
ParameterTypeDescription
team_idstringPick from specific team, or general for general queue only

Assign a transfer to a specific agent.

Terminal window
PUT /api/chatbot/transfers/{id}/assign
{
"agent_id": "uuid"
}

Resume chatbot after human agent completes interaction.

Terminal window
PUT /api/chatbot/transfers/{id}/resume

View active chatbot sessions (for debugging).

Terminal window
GET /api/chatbot/sessions

Get details of a specific session.

Terminal window
GET /api/chatbot/sessions/{id}
{
"status": "success",
"data": {
"id": "uuid",
"contact_id": "uuid",
"current_flow_id": "uuid",
"current_step": "rating",
"variables": {
"name": "John"
},
"started_at": "2024-01-01T12:00:00Z",
"last_activity": "2024-01-01T12:05:00Z"
}
}