Authentication
All API requests require an active session. The platform uses NextAuth with JWT-based session tokens. Authenticate by signing in through the dashboard — all subsequent requests include the session cookie automatically.
Base URL
https://app.callcenter.ai/api Authentication Method
Session-based authentication via NextAuth JWT. All endpoints are scoped to the authenticated user's organization.
# All responses are scoped to your organization
Cookie: next-auth.session-token=<jwt>
Organization Scoping
Every endpoint automatically filters data by your organization. You can only access resources belonging to your org.
Agents
Create and manage AI agents that handle inbound calls, outbound campaigns, and web chat conversations.
/api/agents List all agents Returns all agents belonging to the authenticated user's organization, ordered by creation date.
Response
[
{
"id": "clx1a2b3c4d5e6f7g8h9i0j",
"name": "Customer Support Agent",
"type": "inbound",
"language": "en",
"voiceId": "aura-athena-en",
"twilioPhoneNumber": "+14155551234",
"enableRecording": true,
"enableHandoff": true,
"skills": ["billing", "technical-support"],
"createdAt": "2026-01-15T08:30:00.000Z",
"updatedAt": "2026-02-01T14:22:00.000Z"
}
] /api/agents Create agent Create a new AI agent with the specified configuration.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the agent |
type | string | Yes | Agent type: inbound, outbound, or chat |
systemPrompt | string | Yes | System instructions defining the agent's behavior and personality |
greetingMessage | string | No | Initial message sent when a conversation starts |
language | string | No | Language code (default: en). Supports 20 languages |
voiceId | string | No | Voice synthesis ID for call agents |
twilioPhoneNumber | string | No | Phone number in E.164 format for voice/SMS |
enableRecording | boolean | No | Enable call recording (default: false) |
enableHandoff | boolean | No | Allow escalation to human agents (default: false) |
skills | string[] | No | Array of skill tags for routing |
templateId | string | No | Deploy from an agent template |
widgetConfig | object | No | Chat widget appearance configuration |
Example Request
{
"name": "Sales Agent",
"type": "inbound",
"systemPrompt": "You are a friendly sales representative for Acme Corp...",
"greetingMessage": "Hi! Thanks for calling Acme Corp. How can I help you today?",
"language": "en",
"voiceId": "aura-athena-en",
"twilioPhoneNumber": "+14155551234",
"enableRecording": true,
"enableHandoff": true,
"skills": ["sales", "product-info"]
} Response
{
"id": "clx1a2b3c4d5e6f7g8h9i0j",
"name": "Sales Agent",
"type": "inbound",
"systemPrompt": "You are a friendly sales representative for Acme Corp...",
"greetingMessage": "Hi! Thanks for calling Acme Corp. How can I help you today?",
"language": "en",
"voiceId": "aura-athena-en",
"twilioPhoneNumber": "+14155551234",
"enableRecording": true,
"enableHandoff": true,
"skills": ["sales", "product-info"],
"organizationId": "org_abc123",
"createdAt": "2026-02-07T10:00:00.000Z",
"updatedAt": "2026-02-07T10:00:00.000Z"
} /api/agents/:id Get agent details Retrieve full details for a specific agent including configuration, knowledge bases, and metrics.
Response
{
"id": "clx1a2b3c4d5e6f7g8h9i0j",
"name": "Customer Support Agent",
"type": "inbound",
"systemPrompt": "You are a helpful customer support agent...",
"greetingMessage": "Hello! How can I assist you today?",
"language": "en",
"voiceId": "aura-athena-en",
"twilioPhoneNumber": "+14155551234",
"enableRecording": true,
"enableHandoff": true,
"skills": ["billing", "technical-support"],
"widgetConfig": null,
"templateId": null,
"organizationId": "org_abc123",
"createdAt": "2026-01-15T08:30:00.000Z",
"updatedAt": "2026-02-01T14:22:00.000Z"
} /api/agents/:id Update agent Update an existing agent's configuration. Accepts the same fields as the create endpoint. Only provided fields are updated.
Example Request
{
"name": "Updated Support Agent",
"enableRecording": false,
"skills": ["billing", "technical-support", "returns"]
} /api/agents/:id Delete agent Permanently delete an agent and all associated data. This action cannot be undone.
Knowledge Bases
Manage knowledge bases and upload documents for RAG-powered agent responses.
/api/knowledge List knowledge bases Returns all knowledge bases for the organization.
Response
[
{
"id": "kb_01hx9z3abc",
"name": "Product Documentation",
"description": "Complete product docs and FAQ",
"documentCount": 24,
"createdAt": "2026-01-10T12:00:00.000Z",
"updatedAt": "2026-02-05T09:15:00.000Z"
}
] /api/knowledge Create knowledge base Create a new knowledge base to hold documents for agent retrieval.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name for the knowledge base |
description | string | No | Description of contents |
Example Request
{
"name": "Product Documentation",
"description": "Complete product docs, FAQ, and troubleshooting guides"
} /api/knowledge/:id Get knowledge base with documents Retrieve a knowledge base along with its uploaded documents.
Response
{
"id": "kb_01hx9z3abc",
"name": "Product Documentation",
"description": "Complete product docs and FAQ",
"documents": [
{
"id": "doc_a1b2c3",
"filename": "product-manual.pdf",
"mimeType": "application/pdf",
"sizeBytes": 2048576,
"chunkCount": 47,
"uploadedAt": "2026-01-12T14:30:00.000Z"
}
],
"createdAt": "2026-01-10T12:00:00.000Z"
} /api/knowledge/:id/upload Upload document Upload a document to a knowledge base. Uses multipart/form-data encoding. Supported formats: PDF, DOCX, TXT, Markdown.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | The document file to upload |
Response
{
"id": "doc_d4e5f6",
"filename": "faq.md",
"mimeType": "text/markdown",
"sizeBytes": 15234,
"chunkCount": 12,
"uploadedAt": "2026-02-07T10:15:00.000Z"
} Conversations
Browse and retrieve conversation logs across all channels.
/api/conversations List conversations Returns conversations with optional filtering by agent, channel, and status.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
agentId | string | No | Filter by agent ID |
channel | string | No | Filter by channel: voice, chat, sms |
status | string | No | Filter by status: active, completed, transferred |
Response
[
{
"id": "conv_x1y2z3",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"channel": "voice",
"status": "completed",
"callerNumber": "+14155559876",
"sentiment": "positive",
"duration": 245,
"messageCount": 12,
"createdAt": "2026-02-06T15:30:00.000Z",
"endedAt": "2026-02-06T15:34:05.000Z"
}
] /api/conversations/:id Get conversation with messages Retrieve a full conversation including all messages and metadata.
Response
{
"id": "conv_x1y2z3",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"channel": "voice",
"status": "completed",
"callerNumber": "+14155559876",
"sentiment": "positive",
"duration": 245,
"recordingUrl": "https://api.twilio.com/recordings/RE...",
"messages": [
{
"id": "msg_001",
"role": "assistant",
"content": "Hello! How can I assist you today?",
"createdAt": "2026-02-06T15:30:00.000Z"
},
{
"id": "msg_002",
"role": "user",
"content": "I need help with my billing statement.",
"createdAt": "2026-02-06T15:30:15.000Z"
}
],
"createdAt": "2026-02-06T15:30:00.000Z",
"endedAt": "2026-02-06T15:34:05.000Z"
} Messages
Access individual messages within conversations. Messages are typically retrieved as part of a conversation, but can also be queried directly.
/api/conversations/:id/messages List messages for a conversation Returns all messages in a conversation, ordered chronologically.
Response
[
{
"id": "msg_001",
"conversationId": "conv_x1y2z3",
"role": "assistant",
"content": "Hello! How can I assist you today?",
"metadata": null,
"createdAt": "2026-02-06T15:30:00.000Z"
},
{
"id": "msg_002",
"conversationId": "conv_x1y2z3",
"role": "user",
"content": "I need help with my billing statement.",
"metadata": null,
"createdAt": "2026-02-06T15:30:15.000Z"
}
] Campaigns
Launch and manage automated outbound calling campaigns with contact management and progress tracking.
/api/campaigns List campaigns Returns all campaigns with agent details and contact statistics.
Response
[
{
"id": "cmp_abc123",
"name": "Q1 Outreach Campaign",
"description": "Follow-up calls for Q1 leads",
"status": "active",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"agent": { "id": "clx1a2b3c4d5e6f7g8h9i0j", "name": "Sales Agent" },
"callerIdNumber": "+14155551234",
"maxConcurrentCalls": 5,
"maxRetries": 3,
"retryDelayMinutes": 60,
"contactStats": { "total": 500, "completed": 234, "pending": 266 },
"createdAt": "2026-02-01T09:00:00.000Z"
}
] /api/campaigns Create campaign Create a new outbound campaign. Campaigns start in draft status.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Campaign name |
description | string | No | Campaign description |
agentId | string | Yes | Agent to use for calls |
callerIdNumber | string | Yes | Outbound caller ID in E.164 format |
maxConcurrentCalls | number | No | Max simultaneous calls (default: 1) |
maxRetries | number | No | Max retry attempts per contact (default: 0) |
retryDelayMinutes | number | No | Minutes between retries (default: 60) |
scriptOverride | string | No | Override the agent's system prompt for this campaign |
Example Request
{
"name": "Q1 Outreach Campaign",
"description": "Follow-up calls for Q1 leads",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"callerIdNumber": "+14155551234",
"maxConcurrentCalls": 5,
"maxRetries": 3,
"retryDelayMinutes": 60
} /api/campaigns/:id Get campaign with contacts Retrieve a campaign with its full contact list and per-contact outcomes.
/api/campaigns/:id Update campaign Update campaign configuration. Only draft campaigns can be fully edited; active campaigns allow limited updates.
/api/campaigns/:id Delete campaign Delete a campaign. Only campaigns with status draft, completed, or cancelled can be deleted.
/api/campaigns/:id/start Start campaign Start executing a draft or paused campaign. Begins dialing contacts.
Response
{
"id": "cmp_abc123",
"status": "active",
"startedAt": "2026-02-07T10:00:00.000Z"
} /api/campaigns/:id/pause Pause campaign Pause an active campaign. In-progress calls will complete but no new calls will be initiated.
Campaign Contacts
Manage contacts within a campaign. Bulk add contacts from CSV or API.
/api/campaigns/:id/contacts Bulk add contacts Add multiple contacts to a campaign in a single request.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
contacts | array | Yes | Array of contact objects |
contacts[].phoneNumber | string | Yes | Phone number in E.164 format |
contacts[].name | string | No | Contact name |
contacts[].email | string | No | Contact email |
contacts[].customData | object | No | Arbitrary key-value data passed to the agent |
Example Request
{
"contacts": [
{
"phoneNumber": "+14155559001",
"name": "Alice Johnson",
"email": "alice@example.com",
"customData": { "plan": "enterprise", "accountId": "ACC-001" }
},
{
"phoneNumber": "+14155559002",
"name": "Bob Smith",
"customData": { "plan": "starter" }
}
]
} Response
{
"added": 2,
"duplicatesSkipped": 0
} QA Scores
AI-powered quality assurance scoring for every conversation. Review, override, and flag scores.
/api/qa-scores List QA scores Returns QA scores with filtering options.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter: pending, reviewed, auto |
flagged | boolean | No | Only return flagged scores |
minScore | number | No | Minimum overall score (0-100) |
maxScore | number | No | Maximum overall score (0-100) |
Response
[
{
"id": "qa_score_001",
"conversationId": "conv_x1y2z3",
"overallScore": 87,
"categories": {
"greeting": 95,
"problemIdentification": 90,
"resolution": 80,
"communication": 88,
"compliance": 92,
"closing": 78
},
"flagged": false,
"status": "auto",
"feedback": null,
"createdAt": "2026-02-06T16:00:00.000Z"
}
] /api/qa-scores/:id Get QA score with conversation Retrieve a QA score with the associated conversation and messages for full review context.
/api/qa-scores/:id Update / review QA score Override or review a QA score with manual feedback.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
categories | object | No | Override individual category scores (0-100) |
overallScore | number | No | Override overall score (0-100) |
feedback | string | No | Reviewer feedback notes |
flagged | boolean | No | Flag or unflag the score |
flagReason | string | No | Reason for flagging |
status | string | No | Set status: reviewed |
Example Request
{
"overallScore": 72,
"feedback": "Agent missed upsell opportunity and had a slow closing.",
"flagged": true,
"flagReason": "Needs coaching on closing techniques",
"status": "reviewed"
} /api/qa-scores/:id/rescore Trigger re-scoring Re-run the AI scoring engine on a conversation. Useful after updating scoring criteria.
Response
{
"id": "qa_score_001",
"overallScore": 85,
"status": "auto",
"rescoredAt": "2026-02-07T10:30:00.000Z"
} Handoff Queue
Manage the live agent handoff queue. Escalate conversations from AI to humans with priority and context.
/api/handoff List handoff queue Returns pending and active handoff requests with optional filtering.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter: pending, assigned, resolved |
priority | string | No | Filter: low, medium, high, urgent |
Response
[
{
"id": "hoff_001",
"conversationId": "conv_x1y2z3",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"reason": "Customer requesting human agent",
"priority": "high",
"customerSentiment": "frustrated",
"contextSummary": "Customer has billing dispute, AI unable to resolve...",
"status": "pending",
"assignedTo": null,
"waitTimeSeconds": 45,
"createdAt": "2026-02-07T10:15:00.000Z"
}
] /api/handoff Create handoff request Escalate a conversation to the human agent queue.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
conversationId | string | Yes | Conversation to escalate |
agentId | string | Yes | AI agent handling the conversation |
reason | string | Yes | Reason for escalation |
priority | string | No | low, medium, high, or urgent (default: medium) |
customerSentiment | string | No | Current customer sentiment |
contextSummary | string | No | AI-generated summary of the conversation |
Example Request
{
"conversationId": "conv_x1y2z3",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"reason": "Customer requesting human agent for billing dispute",
"priority": "high",
"customerSentiment": "frustrated",
"contextSummary": "Customer disputes $49.99 charge on Feb statement. AI verified charge is valid but customer insists on speaking to a person."
} /api/handoff/:id Get handoff with conversation Retrieve a handoff request with the full conversation and messages for agent review.
/api/handoff/:id Update handoff Update handoff request details such as priority or notes.
/api/handoff/:id/assign Assign to current user Claim a handoff request and assign it to the currently authenticated user.
Response
{
"id": "hoff_001",
"status": "assigned",
"assignedTo": "user_me123",
"assignedAt": "2026-02-07T10:16:00.000Z"
} /api/handoff/:id/resolve Resolve handoff Mark a handoff as resolved after the human agent has handled the conversation.
/api/handoff/available List available agents Returns a list of human agents currently marked as available for handoffs.
Response
[
{
"userId": "user_me123",
"name": "Jane Smith",
"email": "jane@company.com",
"available": true,
"activeHandoffs": 1,
"lastActiveAt": "2026-02-07T10:10:00.000Z"
}
] /api/handoff/available Toggle availability Toggle the current user's availability for receiving handoff assignments.
Example Request
{
"available": true
} Automations
Create event-driven automation rules that trigger actions based on call events like conversation ended, negative sentiment, or keyword detection.
/api/automations List automation rules Returns all automation rules for the organization.
Response
[
{
"id": "auto_001",
"name": "Negative Sentiment Alert",
"description": "Send Slack notification when sentiment is negative",
"trigger": "conversation.ended",
"conditions": { "sentiment": "negative" },
"action": "webhook",
"actionConfig": {
"url": "https://hooks.slack.com/services/T.../B.../xxx",
"method": "POST"
},
"active": true,
"executionCount": 47,
"lastExecutedAt": "2026-02-06T22:15:00.000Z",
"createdAt": "2026-01-20T08:00:00.000Z"
}
] /api/automations Create automation rule Create a new automation rule.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Rule name |
description | string | No | Rule description |
trigger | string | Yes | Event trigger: conversation.ended, sentiment.negative, handoff.requested, keyword.detected |
conditions | object | No | Additional conditions to evaluate |
action | string | Yes | Action type: webhook, email, create_ticket, update_crm, tag_conversation, notify_team |
actionConfig | object | Yes | Action-specific configuration |
Example Request
{
"name": "Escalation Webhook",
"description": "Fire webhook when a handoff is requested",
"trigger": "handoff.requested",
"conditions": { "priority": "high" },
"action": "webhook",
"actionConfig": {
"url": "https://api.yourapp.com/escalation",
"method": "POST",
"headers": { "Authorization": "Bearer token123" }
}
} /api/automations/:id Get rule with recent logs Retrieve an automation rule with its most recent execution logs.
/api/automations/:id Update rule Update an automation rule's configuration. Accepts the same fields as the create endpoint.
/api/automations/:id Delete rule Permanently delete an automation rule.
/api/automations/:id/toggle Toggle active / inactive Toggle an automation rule between active and inactive states.
Response
{
"id": "auto_001",
"active": false
} Automation Logs
View paginated execution logs for automation rules to monitor success rates and debug failures.
/api/automations/:id/logs Paginated execution logs Returns paginated execution logs for a specific automation rule.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1) |
limit | number | No | Items per page (default: 20, max: 100) |
Response
{
"logs": [
{
"id": "log_001",
"automationId": "auto_001",
"conversationId": "conv_x1y2z3",
"status": "success",
"executedAt": "2026-02-06T22:15:00.000Z",
"durationMs": 342,
"result": { "statusCode": 200 }
},
{
"id": "log_002",
"automationId": "auto_001",
"conversationId": "conv_a4b5c6",
"status": "failed",
"executedAt": "2026-02-06T20:00:00.000Z",
"durationMs": 5023,
"error": "Webhook timeout after 5000ms"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 47,
"totalPages": 3
}
} Routing Rules
Configure intelligent multi-agent routing rules based on intent, sentiment, language, and keywords.
/api/routing List routing rules Returns all routing rules with associated agent details, ordered by priority.
Response
[
{
"id": "route_001",
"name": "Spanish to ES Agent",
"sourceAgent": { "id": "agent_en", "name": "English Receptionist" },
"targetAgent": { "id": "agent_es", "name": "Spanish Support Agent" },
"conditions": { "language": "es" },
"priority": 10,
"active": true,
"transferCount": 89,
"createdAt": "2026-01-18T12:00:00.000Z"
}
] /api/routing Create routing rule Create a new routing rule.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Rule name |
sourceAgentId | string | Yes | Agent that triggers the transfer |
targetAgentId | string | Yes | Agent to transfer to |
conditions | object | Yes | Conditions: intent, sentiment, language, keywords |
priority | number | No | Priority order (lower = higher priority, default: 100) |
Example Request
{
"name": "Billing Escalation",
"sourceAgentId": "agent_general",
"targetAgentId": "agent_billing",
"conditions": {
"intent": "billing",
"keywords": ["invoice", "charge", "payment", "refund"]
},
"priority": 5
} /api/routing/:id Get rule Retrieve a specific routing rule with full details.
/api/routing/:id Update rule Update a routing rule. Accepts the same fields as the create endpoint.
/api/routing/:id Delete rule Permanently delete a routing rule.
/api/routing/:id/toggle Toggle active Toggle a routing rule between active and inactive.
Response
{
"id": "route_001",
"active": true
} /api/routing/evaluate Evaluate routing Evaluate routing rules against a set of conversation attributes. Returns the matched rule and target agent, if any.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
conversationId | string | Yes | Current conversation ID |
sourceAgentId | string | Yes | Current handling agent |
intent | string | No | Detected intent |
sentiment | string | No | Current sentiment |
language | string | No | Detected language |
keywords | string[] | No | Detected keywords |
Response
{
"matched": true,
"rule": {
"id": "route_001",
"name": "Billing Escalation"
},
"targetAgent": {
"id": "agent_billing",
"name": "Billing Specialist"
},
"transferred": true
} Templates
Browse pre-built agent templates and deploy agents from them with a single request.
/api/templates List templates Returns all available agent templates, sorted by usage count.
Response
[
{
"id": "tmpl_support_01",
"name": "Customer Support Agent",
"description": "Pre-configured support agent with empathetic tone and escalation flows",
"category": "support",
"type": "inbound",
"systemPrompt": "You are a helpful and empathetic customer support agent...",
"greetingMessage": "Hello! How can I help you today?",
"skills": ["general-support", "troubleshooting"],
"usageCount": 342,
"createdAt": "2026-01-01T00:00:00.000Z"
}
] /api/templates/:id Get template Retrieve full details for a specific template.
/api/templates/:id Deploy agent from template Create a new agent using the template's configuration as a starting point.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name for the new agent |
twilioPhoneNumber | string | No | Phone number in E.164 format |
Example Request
{
"name": "My Support Agent",
"twilioPhoneNumber": "+14155551234"
} Response
{
"id": "clx_new_agent_id",
"name": "My Support Agent",
"type": "inbound",
"systemPrompt": "You are a helpful and empathetic customer support agent...",
"templateId": "tmpl_support_01",
"createdAt": "2026-02-07T10:00:00.000Z"
} Billing
Manage subscription and billing information. Powered by Stripe.
/api/billing Get billing status Returns the current organization's subscription and billing details.
Response
{
"plan": "pro",
"status": "active",
"currentPeriodStart": "2026-02-01T00:00:00.000Z",
"currentPeriodEnd": "2026-03-01T00:00:00.000Z",
"usage": {
"minutesUsed": 4230,
"minutesLimit": 10000,
"agentsUsed": 5,
"agentsLimit": 20
},
"stripeCustomerId": "cus_xxx"
} /api/billing/portal Create billing portal session Generate a Stripe billing portal URL for the customer to manage their subscription.
Response
{
"url": "https://billing.stripe.com/p/session/..."
} Widget Chat
Public endpoints for the embeddable chat widget. These power the real-time chat experience on customer websites.
/api/widget/chat Send chat message (SSE stream) Send a message to a chat agent. Returns a Server-Sent Events (SSE) stream with the agent's response tokens.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
agentId | string | Yes | Chat agent ID |
message | string | Yes | User message text |
sessionToken | string | No | Session token for conversation continuity (returned in first response) |
Example Request
{
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"message": "What are your business hours?",
"sessionToken": "sess_abc123xyz"
} SSE Response Stream
data: {"type":"token","content":"Our"}
data: {"type":"token","content":" business"}
data: {"type":"token","content":" hours"}
data: {"type":"token","content":" are"}
data: {"type":"token","content":" Monday-Friday, 9am-5pm EST."}
data: {"type":"done","sessionToken":"sess_abc123xyz"}
/api/widget/history Get conversation history Retrieve the chat history for a widget session. Requires a valid session token as a query parameter.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
sessionToken | string | Yes | Session token from a previous chat |
Response
{
"sessionToken": "sess_abc123xyz",
"agentId": "clx1a2b3c4d5e6f7g8h9i0j",
"messages": [
{ "role": "assistant", "content": "Hello! How can I help?", "createdAt": "2026-02-07T10:00:00.000Z" },
{ "role": "user", "content": "What are your hours?", "createdAt": "2026-02-07T10:00:15.000Z" },
{ "role": "assistant", "content": "Our business hours are Monday-Friday, 9am-5pm EST.", "createdAt": "2026-02-07T10:00:16.000Z" }
]
} Webhooks
Inbound webhook endpoints that receive events from external services. These are called by Twilio and Stripe, not by your application directly.
Inbound Webhooks
These endpoints are configured as callback URLs in Twilio and Stripe. They are not intended to be called directly by your application.
/api/twilio/voice Twilio voice webhook Receives incoming voice call events from Twilio. Matches the called number to an agent and initiates the AI conversation. Returns TwiML to control the call flow.
Twilio Sends
{
"CallSid": "CA1234567890abcdef",
"From": "+14155559876",
"To": "+14155551234",
"CallStatus": "ringing",
"Direction": "inbound"
} Returns
TwiML XML response to control the call (connect to AI agent via WebSocket).
/api/twilio/sms Twilio SMS webhook Receives incoming SMS messages from Twilio. Processes the message through the matched agent and returns a TwiML response with the AI reply.
Twilio Sends
{
"MessageSid": "SM1234567890abcdef",
"From": "+14155559876",
"To": "+14155551234",
"Body": "Hi, I need help with my order"
} /api/twilio/status Call status callback Receives call status updates from Twilio (ringing, in-progress, completed, failed, busy, no-answer). Updates the conversation record accordingly.
Twilio Sends
{
"CallSid": "CA1234567890abcdef",
"CallStatus": "completed",
"CallDuration": "245",
"Timestamp": "2026-02-07T10:34:05.000Z"
} /api/twilio/recording-status Recording completion callback Receives recording completion events from Twilio. Stores the recording URL and triggers QA scoring on the conversation.
Twilio Sends
{
"CallSid": "CA1234567890abcdef",
"RecordingSid": "RE1234567890abcdef",
"RecordingUrl": "https://api.twilio.com/2010-04-01/Accounts/.../Recordings/RE...",
"RecordingStatus": "completed",
"RecordingDuration": "245"
} /api/billing/webhook Stripe webhook Receives subscription lifecycle events from Stripe. Handles events like customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, and invoice.payment_failed.
Stripe Sends
{
"id": "evt_1234567890",
"type": "customer.subscription.updated",
"data": {
"object": {
"id": "sub_abc123",
"customer": "cus_xxx",
"status": "active",
"plan": {
"id": "price_pro_monthly",
"product": "prod_callcenter_pro"
},
"current_period_end": 1741046400
}
}
} HTTP Status Codes
Standard HTTP status codes used across all endpoints.
| Code | Meaning | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request body or parameters |
401 | Unauthorized | Missing or invalid session |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource does not exist |
405 | Method Not Allowed | HTTP method not supported for this endpoint |
409 | Conflict | Resource conflict (e.g. duplicate) |
500 | Internal Server Error | Unexpected server error |
Error Response Format
{
"error": "Validation failed",
"message": "Field 'name' is required",
"status": 400
} Need help integrating?
Our team is here to help you build on the platform.