API v1 · Enterprise

REST API Documentation

Programmatic access to every call, transcript, recording, and analytic for your AI receptionist. Available on the Enterprise plan ($1,997/mo). All responses are JSON. Base URL:

https://humanaddai.com/api/v1

Authentication

Authenticate every request with your API key in the Authorization header. Get your key from the Dashboard → Integrations tab → Custom API card. You can rotate it at any time; the old key dies instantly.

curl https://humanaddai.com/api/v1/calls \
 -H "Authorization: Bearer hak_your_api_key_here"

Never commit your key to version control. If it's ever exposed, rotate immediately from the dashboard.

Errors

All errors return a JSON body with an error code and a human message.

{ "ok": false, "error": "invalid_api_key", "message": "API key not recognized." }
StatusErrorMeaning
401missing_api_keyNo Authorization header sent
401invalid_api_keyKey doesn't exist or has been rotated
403plan_not_supportedAccount is not on Enterprise
404not_foundResource ID doesn't exist
500fetch_failedUpstream error - retry

Rate limits

60 requests per minute per API key. Exceeding returns 429 Too Many Requests.

GET /api/v1/calls

Returns your most recent calls. Paginated via after timestamp.

Query params

  • limit - integer, 1 - 200, default 50
  • after - unix ms timestamp; only returns calls that started after this

Example

curl "https://humanaddai.com/api/v1/calls?limit=10" \
 -H "Authorization: Bearer hak_..."

{
 "ok": true,
 "count": 10,
 "calls": [
 {
 "call_id": "call_abc123",
 "direction": "inbound",
 "from_number": "+15551234567",
 "to_number": "+15559876543",
 "started_at": "2025-01-15T18:22:04.000Z",
 "duration_seconds": 82,
 "status": "ended",
 "sentiment": "positive",
 "summary": "Caller booked an HVAC maintenance appointment for Thursday.",
 "tags": ["booking"],
 "booked": true
 }
 ]
}

GET /api/v1/calls/:id

Full call details including transcript and a proxied recording URL.

curl https://humanaddai.com/api/v1/calls/call_abc123 \
 -H "Authorization: Bearer hak_..."

{
 "ok": true,
 "call": {
 "call_id": "call_abc123",
 "direction": "inbound",
 "from_number": "+15551234567",
 "to_number": "+15559876543",
 "started_at": "2025-01-15T18:22:04.000Z",
 "ended_at": "2025-01-15T18:23:26.000Z",
 "duration_seconds": 82,
 "status": "ended",
 "disconnection_reason": "user_hangup",
 "sentiment": "positive",
 "summary": "...",
 "transcript": "AI: Hello...",
 "transcript_object": [...],
 "recording_url": "/api/v1/calls/call_abc123/recording"
 }
}

GET /api/v1/calls/:id/recording

Streams the call audio as audio/wav. Proxied so you never see the upstream URL.

GET /api/v1/stats

Aggregate metrics for a rolling period.

Query params

  • days - integer, default 30
{
 "ok": true,
 "period_days": 30,
 "stats": {
 "totalCalls": 426,
 "avgDuration": "1:22",
 "answered": 402,
 "missed": 24,
 "inbound": 410,
 "outbound": 16,
 "sentimentDistribution": { "positive": 380, "neutral": 32, "negative": 14 },
 "busiestDay": "Tuesday",
 "peakHours": "9am - 12pm",
 "topQuestions": [...]
 }
}

POST /api/v1/kb

Update your AI's knowledge base programmatically. Changes are queued for review and pushed within minutes.

curl https://humanaddai.com/api/v1/kb \
 -H "Authorization: Bearer hak_..." \
 -H "Content-Type: application/json" \
 -d '{"text": "Our new hours are 8am-7pm M-F.", "replace": false}'

{ "ok": true, "queued": true }

Set replace: true to wipe the existing KB before adding. Use with caution.

Receiving webhooks (outbound)

Configure a webhook URL in Dashboard → Integrations and we'll POST every call_ended event to your endpoint. See the dashboard for payload shape, or receive this JSON:

{
 "event": "call_ended",
 "call_id": "...",
 "direction": "inbound",
 "from_number": "+15551234567",
 "to_number": "+15559876543",
 "started_at": "2025-01-01T00:00:00Z",
 "duration_seconds": 82,
 "sentiment": "positive",
 "summary": "...",
 "transcript": "...",
 "recording_url": "..."
}

If you set a secret in the dashboard, it's sent as X-Webhook-Secret - verify it before processing.

Questions? Need a custom endpoint?

Contact support →
Last updated