Errors
Error response format, HTTP status codes, error codes, pagination, and troubleshooting for the KaiCalls API.
Error Response Format
All errors return a consistent JSON structure with a machine-readable code and a human-readable message:
{
"error": {
"code": "unauthorized",
"message": "Invalid or expired API key"
}
}HTTP Status Codes
| Status | Meaning |
|---|---|
200 | Success |
201 | Resource created |
400 | Bad request — missing or invalid parameters |
401 | Unauthorized — invalid, expired, or revoked API key |
402 | Payment required — x402 payment needed (signup endpoint only) |
403 | Forbidden — key lacks required scope or business access |
404 | Not found — resource does not exist or is not accessible |
429 | Rate limited — too many requests |
500 | Internal server error |
Error Codes
The error.code field in every error response will be one of these values:
| Code | HTTP Status | Description |
|---|---|---|
unauthorized | 401 | API key is missing, invalid, expired, or revoked |
forbidden | 403 | Key lacks the required scope or business access |
not_found | 404 | Resource not found |
bad_request | 400 | Missing required parameters |
invalid_request | 400 | Parameter validation failed |
vapi_error | 500 | Error communicating with voice AI provider |
call_failed | 500 | Outbound call could not be placed |
payment_required | 402 | x402 payment header required |
content_blocked | 400 | SMS content failed compliance check |
number_opted_out | 400 | Recipient has opted out of SMS |
number_on_dnc | 400 | Number is on Do Not Call list |
tcpa_violation | 400 | TCPA compliance violation |
rate_limit_exceeded | 429 | Too many requests |
sms_send_failed | 500 | SMS delivery failed |
internal_error | 500 | Unexpected server error |
Pagination
All list endpoints support cursor-based pagination using these query parameters:
?after=<ISO timestamp>Cursor: pass the created_at value of the last item in the previous page.
?limit=<number>Results per page. Maximum varies by endpoint (typically 100).
has_moreEvery list response includes a has_more: boolean field. When true, fetch the next page using after.
# First page
curl "https://kaicalls.com/api/v1/calls?limit=25" \
-H "Authorization: Bearer kc_live_..."
# Next page (use created_at of last item)
curl "https://kaicalls.com/api/v1/calls?limit=25&after=2026-04-17T12:00:00Z" \
-H "Authorization: Bearer kc_live_..."Troubleshooting
Common issues and how to resolve them:
1401 on every request
Check that the key starts with kc_live_ or kc_test_ and is passed in the Authorization: Bearer header. Verify the key has not been revoked or expired.
2403 Forbidden
Your key may be scoped to a different business, or missing the required scope. Check the key's scopes in the dashboard.
3Empty results
Your key may be scoped to a business with no data for that resource. Check business_id scoping.
4Rate limited on signup
Wait 1 hour. The /v1/signup endpoint is limited to 5 requests per IP per hour.
See the Authentication guide for key setup, or return to the full API reference.