KaiCalls API Reference

KaiCalls API

Give your AI agent a phone. Make outbound calls, manage agents, and integrate AI phone assistants into your applications.

Base URL:https://kaicalls.com/api/v1

Quick Start

1. Get your API key

Go to Dashboard → Settings → API Keys and generate a key.

2. Make your first call

curl -X POST https://kaicalls.com/api/v1/calls \
  -H "Authorization: Bearer kc_live_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "your-agent-id",
    "to": "+15125551234",
    "name": "John Smith",
    "context": "Confirm appointment for tomorrow at 2pm"
  }'

3. Check the result

curl "https://kaicalls.com/api/v1/calls?id=CALL_ID" \
  -H "Authorization: Bearer kc_live_xxxxx"

Authentication

All API requests require a Bearer token in the Authorization header.

Authorization: Bearer kc_live_xxxxx

Key Prefixes

  • kc_live_ — Production keys
  • kc_test_ — Sandbox keys (coming soon)

Scopes

Keys are created with scopes that control access. Default scopes are granted automatically.

ParameterTypeDescription
agents:readscopeList and view agents
numbers:readscopeList phone numbers
calls:readscopeList and view call records
calls:writescopeMake outbound calls
*scopeFull access (all scopes)

Agents

GET/api/v1/agentsList all agents

Returns all agents assigned to your businesses. Requires agents:read scope.

Response200
{
  "agents": [
    {
      "id": "uuid-abc123",
      "name": "Kai",
      "business_id": "uuid-biz456",
      "created_at": "2026-01-15T10:00:00Z"
    }
  ]
}
GET/api/v1/agents?id=AGENT_IDGet agent details

Returns detailed info including Vapi assistant ID and assigned phone number.

Response200
{
  "id": "uuid-abc123",
  "name": "Kai",
  "business_id": "uuid-biz456",
  "vapi_assistant_id": "vapi-asst-789",
  "phone_number": "+15125551234",
  "created_at": "2026-01-15T10:00:00Z"
}

Phone Numbers

GET/api/v1/numbersList phone numbers

Returns all phone numbers registered to your businesses. Requires numbers:read scope.

Response200
{
  "numbers": [
    {
      "id": "uuid-num789",
      "phone_number": "+15125551234",
      "agent_id": "uuid-abc123",
      "business_id": "uuid-biz456",
      "created_at": "2026-01-15T10:00:00Z"
    }
  ]
}

Calls

POST/api/v1/callsMake an outbound call

Initiates an outbound call using your AI agent. The system automatically enriches the call with context from your CRM — the agent will know the caller's name, lead score, interaction history, and business details.

Required scope: calls:write

Parameters

ParameterTypeDescription
agent_idrequiredstringThe agent to use for this call
torequiredstringPhone number to call (E.164 format, e.g. +15125551234)
namestringCustomer name. The agent greets them by name. Also accepts customer_name.
contextstringFreeform context the agent can reference. Use for task instructions, appointment details, or notes.
firstMessagestringOverride the agent's opening line for this call. Also accepts first_message. If omitted, uses the agent's configured outbound greeting.
lead_idstringLink this call to a lead in your CRM. Enables automatic enrichment with lead score, history, and source.
webhook_urlstringURL to receive a webhook when the call completes
max_durationintegerMaximum call duration in seconds (default: 600)

Automatic Context Enrichment

When you provide a lead_id or the to number matches an existing lead, the agent automatically receives these variables in its prompt:

VariableDescription
nameLead's first name (from name param or CRM)
lead_scoreAI-assigned quality score (0-100)
lead_statusCurrent lead status in your pipeline
interaction_countNumber of previous calls with this lead
days_since_first_contactDays since the lead was first created
lead_sourceWhere the lead came from (web form, referral, etc.)
business_nameYour business name
business_phoneYour office phone number
time_of_day"morning", "afternoon", or "evening"

These are injected automatically — you don't need to pass them.

Minimal Example

curl -X POST https://kaicalls.com/api/v1/calls \
  -H "Authorization: Bearer kc_live_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "uuid-abc123", "to": "+15125559876"}'

Full Example (with context and lead)

curl -X POST https://kaicalls.com/api/v1/calls \
  -H "Authorization: Bearer kc_live_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "uuid-abc123",
    "to": "+15125559876",
    "name": "John Smith",
    "lead_id": "uuid-lead123",
    "context": "Following up on car accident case",
    "firstMessage": "Hey John, this is Kai from Smith Law — do you have a minute?"
  }'
Response201
{
  "id": "uuid-call789",
  "conversation_id": "vapi-conv-xyz",
  "status": "queued",
  "agent_id": "uuid-abc123",
  "to": "+15125559876",
  "name": "John Smith",
  "created_at": "2026-02-15T14:30:00Z"
}
GET/api/v1/callsList calls

Returns calls across all your businesses, ordered by most recent. Requires calls:read scope.

Query Parameters

ParameterTypeDescription
limitintegerMax results per page (default: 50, max: 100)
agent_idstringFilter by agent ID
statusstringFilter by call status
afterstringCursor-based pagination. Pass the created_at of the last result to get the next page.
Response200
{
  "calls": [
    {
      "id": "uuid-call789",
      "conversation_id": "vapi-conv-xyz",
      "status": "completed",
      "duration": 127,
      "agent_id": "uuid-abc123",
      "agent_name": "Kai",
      "created_at": "2026-02-15T14:30:00Z"
    }
  ],
  "has_more": true
}
GET/api/v1/calls?id=CALL_IDGet call details

Returns full details for a single call including summary, recording, and quality analysis.

Response200
{
  "id": "uuid-call789",
  "conversation_id": "vapi-conv-xyz",
  "status": "completed",
  "direction": "inbound",
  "duration": 127,
  "agent_id": "uuid-abc123",
  "agent_name": "Kai",
  "business_id": "uuid-biz456",
  "lead_id": "uuid-lead123",
  "summary": "Confirmed appointment with John for tomorrow at 2pm.",
  "recording_url": "https://storage.example.com/recordings/call_xyz.mp3",
  "quality_dimensions": {
    "professionalism": 92,
    "empathy": 88,
    "information_gathering": 95,
    "resolution": 90
  },
  "created_at": "2026-02-15T14:30:00Z"
}

API Keys

Key management uses session authentication (dashboard login), not API key auth.

GET/api/v1/keysList your API keys
Response200
{
  "keys": [
    {
      "id": "uuid-key123",
      "prefix": "kc_live_abc1",
      "name": "Production Key",
      "scopes": ["agents:read", "calls:read", "calls:write", "numbers:read"],
      "business_id": null,
      "created_at": "2026-01-15T10:00:00Z",
      "last_used_at": "2026-02-15T14:30:00Z",
      "expires_at": null,
      "is_active": true
    }
  ]
}
POST/api/v1/keysCreate a new key

The full key is returned only once — store it securely.

ParameterTypeDescription
namestringHuman-readable name (default: "Untitled Key")
business_idstringScope key to a single business. If omitted, key accesses all your businesses.
scopesstring[]Permission scopes. Defaults to ["agents:read", "numbers:read", "calls:read", "calls:write"].
Response201
{
  "key": "kc_live_abc123def456...",
  "id": "uuid-key123",
  "prefix": "kc_live_abc1",
  "name": "My Integration Key",
  "scopes": ["agents:read", "calls:read", "calls:write", "numbers:read"],
  "business_id": "uuid-biz456",
  "created_at": "2026-02-15T14:30:00Z"
}
DELETE/api/v1/keys?id=KEY_IDRevoke a key

Revokes an API key. The key immediately stops working.

Response200
{ "success": true }

Account

GET/api/v1/balanceGet subscription info

Returns usage and subscription status for each of your businesses.

Response200
{
  "businesses": [
    {
      "business_id": "uuid-biz456",
      "minutes_used": 412,
      "phone_numbers": 2,
      "subscription_status": "active"
    }
  ]
}
GET/api/v1/usageGet API usage log

Returns your API call history.

ParameterTypeDescription
startstringISO 8601 start date filter
endstringISO 8601 end date filter
limitintegerMax results (default: 100, max: 500)
Response200
{
  "usage": [
    {
      "id": "uuid-log123",
      "endpoint": "/v1/calls",
      "method": "POST",
      "status_code": 201,
      "call_id": "uuid-call789",
      "cost_cents": 15,
      "created_at": "2026-02-15T14:30:00Z"
    }
  ],
  "has_more": false
}

Webhooks

Pass a webhook_url when making a call to receive events when the call completes or fails.

call.completed

{
  "event": "call.completed",
  "call_id": "uuid-call789",
  "status": "completed",
  "duration": 127,
  "recording_url": "https://...",
  "summary": "Confirmed appointment for tomorrow at 2pm.",
  "timestamp": "2026-02-15T14:32:12Z"
}

call.failed

{
  "event": "call.failed",
  "call_id": "uuid-call789",
  "status": "failed",
  "error": "no_answer",
  "timestamp": "2026-02-15T14:31:00Z"
}

Errors

All errors follow a consistent format:

{
  "error": {
    "code": "error_code",
    "message": "Human-readable description"
  }
}
CodeStatusDescription
unauthorized401Invalid, missing, expired, or revoked API key
forbidden403Key doesn't have the required scope
not_found404Agent, call, or resource not found
invalid_request400Missing required fields or invalid JSON
call_failed500Vapi failed to initiate the call
internal_error500Unexpected server error
rate_limited429Too many requests — slow down

Rate Limits

EndpointLimit
POST /v1/calls60 requests/minute
All GET endpoints300 requests/minute

SDKs

Python

pip install kaicalls
from kaicalls import KaiCalls

kai = KaiCalls(api_key="kc_live_xxx")

# Simple call — agent auto-enriches with CRM data
call = kai.calls.create(
    agent_id="uuid-abc123",
    to="+15125551234",
    name="John Smith"
)

# Full call with lead linking and custom opening
call = kai.calls.create(
    agent_id="uuid-abc123",
    to="+15125551234",
    name="John Smith",
    lead_id="uuid-lead123",
    context="Following up on car accident case",
    first_message="Hey John, this is Kai — do you have a minute?"
)

result = kai.calls.wait(call.id)
print(result.summary)

JavaScript / TypeScript

npm install kaicalls
import { KaiCalls } from 'kaicalls';

const kai = new KaiCalls({ apiKey: 'kc_live_xxx' });

// Simple call
const call = await kai.calls.create({
  agentId: 'uuid-abc123',
  to: '+15125551234',
  name: 'John Smith',
});

// Full call with lead linking and custom opening
const call = await kai.calls.create({
  agentId: 'uuid-abc123',
  to: '+15125551234',
  name: 'John Smith',
  leadId: 'uuid-lead123',
  context: 'Following up on car accident case',
  firstMessage: 'Hey John, this is Kai — do you have a minute?',
});

const result = await kai.calls.get(call.id);
console.log(result.summary);
    API Reference | KaiCalls Developer Docs