Private BetaInvite only. 3 spots daily.

← Back to Documentation

API Reference

Integrate KestrelVoice into your applications

Authentication

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.

Example: Fetch Call Logs

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));

How Authentication Works

  1. Sign up or log in at kestrelvoice.com/login
  2. Supabase creates a JWT session stored in an HTTP-only cookie
  3. All fetch requests to /api/* must include credentials: 'include'
  4. The server validates the session, resolves your tenant, and returns data scoped to your account
  5. Expired or invalid sessions return 401 Unauthorized — redirect to login

API Keys (Third-Party Integrations Only)

For 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).

  • Include in header: X-API-Key: YOUR_KEY
  • Keys are scoped to your tenant and can be revoked anytime
  • Store keys in environment variables — never expose in client-side code

Base URL & Architecture

https://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.

Backend Services (Internal)

Two Modal backend services power the platform behind the scenes:

  • Voice Agent: Handles Twilio IVR, real-time call streams, voicemail, and call routing
  • Demand Engine: Handles AI chats, call intelligence, analytics, CRM sync, and lead processing

Frontend developers do not call these directly — use the Next.js API routes above.

API Endpoints

GET
/api/call-logs

Retrieve a list of calls for your account. Requires active tenant session.

Query Parameters

limitNumber of results (default: 20, max: 100)
offsetPagination offset
statusFilter by status: completed, in-progress, missed
from_dateISO 8601 date (e.g., 2024-01-01)

Example Response

{
  "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
  }
}
GET
/api/call-logs/{id}

Retrieve details for a specific call including transcript, recording URL, and metadata.

Example Request

GET /api/call-logs/550e8400-e29b-41d4-a716-446655440000
GET
/api/appointments

Retrieve appointments booked through your AI agent. Data sourced from your connected calendar integration.

Query Parameters

statusscheduled, completed, cancelled
from_dateFilter appointments from this date
to_dateFilter appointments until this date
GET
/api/analytics

Retrieve analytics data for your account. Business Plus plan required for 90-day range.

Available Metrics

  • Total calls (by day, week, month)
  • Appointment booking rate
  • Average call duration
  • Emergency call detection rate
  • Missed call recovery

Webhooks

Receive real-time notifications when events occur in your account.

Available Events

call.completed

Triggered when a call ends

appointment.booked

Triggered when an appointment is scheduled

emergency.detected

Triggered when emergency keywords are detected

call.missed

Triggered when a call is not answered

Example Webhook Payload

{
  "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://..."
  }
}

Webhook Configuration

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.

Rate Limits

KestrelVoice API routes are hosted on Vercel Edge and Serverless functions. Standard limits apply:

  • Edge Routes: No practical rate limit (global edge network)
  • Serverless Routes: Subject to your Vercel plan concurrency limits
  • Long-running operations (transcript generation, AI summary): up to 60s timeout

For high-volume integrations, batch requests and use the limit / offset parameters. Contact support for enterprise throughput requirements.

Error Codes

CodeDescription
400Bad Request — Invalid or missing parameters
401Unauthorized — Session expired or invalid. Redirect to /login to refresh.
402Payment Required — Feature requires plan upgrade (error: upgrade_required)
403Forbidden — Insufficient permissions or wrong tenant scope
404Not Found — Resource does not exist or you lack access
429Too Many Requests — Vercel or backend rate limit exceeded
500Internal Server Error — Contact support with request ID

Need API Support?

Our developer team is here to help with your integration