Private BetaInvite only. 3 spots daily.
KestrelVoice uses Next.js API routes served from the same domain. Authentication is handled via Supabase JWT sessions stored in HTTP-only cookies. When logged into the dashboard, your browser automatically sends the session cookie with every API request.
fetch('https://kestrelvoice.com/api/call-logs?limit=20', {
credentials: 'include', // Required — sends the Supabase session cookie
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(data => console.log(data.calls));fetch requests to /api/* must include credentials: 'include'401 Unauthorized — redirect to loginFor external services that cannot use cookie-based auth, generate API keys at /settings/api-keys. These are intended for server-to-server integrations (e.g., Zapier, Make, custom backends).
X-API-Key: YOUR_KEYhttps://kestrelvoice.com/api/KestrelVoice uses Next.js API routes served from the same domain. Authentication is handled via Supabase JWT sessions (HTTP-only cookies). All API responses return JSON.
Two Modal backend services power the platform behind the scenes:
Frontend developers do not call these directly — use the Next.js API routes above.
/api/call-logsRetrieve a list of calls for your account. Requires active tenant session.
| limit | Number of results (default: 20, max: 100) |
| offset | Pagination offset |
| status | Filter by status: completed, in-progress, missed |
| from_date | ISO 8601 date (e.g., 2024-01-01) |
{
"data": [
{
"id": "call_abc123",
"phone_number": "+15551234567",
"status": "completed",
"duration": 180,
"recording_url": "https://...",
"transcript": "Hello, this is...",
"created_at": "2024-03-09T10:30:00Z"
}
],
"pagination": {
"total": 150,
"limit": 20,
"offset": 0
}
}/api/call-logs/{id}Retrieve details for a specific call including transcript, recording URL, and metadata.
GET /api/call-logs/550e8400-e29b-41d4-a716-446655440000
/api/appointmentsRetrieve appointments booked through your AI agent. Data sourced from your connected calendar integration.
| status | scheduled, completed, cancelled |
| from_date | Filter appointments from this date |
| to_date | Filter appointments until this date |
/api/analyticsRetrieve analytics data for your account. Business Plus plan required for 90-day range.
Receive real-time notifications when events occur in your account.
Triggered when a call ends
Triggered when an appointment is scheduled
Triggered when emergency keywords are detected
Triggered when a call is not answered
{
"event": "call.completed",
"timestamp": "2024-03-09T10:30:00Z",
"data": {
"call_id": "call_abc123",
"phone_number": "+15551234567",
"duration": 180,
"outcome": "appointment_booked",
"transcript": "...",
"recording_url": "https://..."
}
}Webhooks are configured per integration in your dashboard. For CRM webhooks (ServiceTitan, Jobber), authentication is handled via OAuth tokens. For custom endpoint webhooks, configure your URL and secret at Settings → Integrations.
All webhook payloads include an event field and timestamp for idempotency. Retry with exponential backoff is automatic for 5xx responses.
KestrelVoice API routes are hosted on Vercel Edge and Serverless functions. Standard limits apply:
For high-volume integrations, batch requests and use the limit / offset parameters. Contact support for enterprise throughput requirements.
| Code | Description |
|---|---|
| 400 | Bad Request — Invalid or missing parameters |
| 401 | Unauthorized — Session expired or invalid. Redirect to /login to refresh. |
| 402 | Payment Required — Feature requires plan upgrade (error: upgrade_required) |
| 403 | Forbidden — Insufficient permissions or wrong tenant scope |
| 404 | Not Found — Resource does not exist or you lack access |
| 429 | Too Many Requests — Vercel or backend rate limit exceeded |
| 500 | Internal Server Error — Contact support with request ID |