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." }
| Status | Error | Meaning |
|---|---|---|
401 | missing_api_key | No Authorization header sent |
401 | invalid_api_key | Key doesn't exist or has been rotated |
403 | plan_not_supported | Account is not on Enterprise |
404 | not_found | Resource ID doesn't exist |
500 | fetch_failed | Upstream 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 50after— 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 →