API documentation
Pull your calls, transcripts and recordings into your own tools, update your agent programmatically, place outbound calls, and receive a webhook after every call. Create a key under Settings → API.
Authentication
Send your key as a Bearer token. All requests are scoped to your account. Rate limit: 120 requests/minute.
curl https://aiphonez.com/api/v1/me \
-H "Authorization: Bearer apz_live_..."Endpoints
GET/api/v1/me
GET/api/v1/agents
GET/api/v1/agents/:id
PATCH/api/v1/agents/:id
system_prompt, voice_id, transfer_number, transfer_routes (up to 8 {label, number}), notification_email, notification_phone.curl -X PATCH https://aiphonez.com/api/v1/agents/AGENT_ID \
-H "Authorization: Bearer apz_live_..." \
-H "Content-Type: application/json" \
-d '{"transfer_routes":[{"label":"Sales","number":"+15125550134"}]}'GET/api/v1/calls
agent_id, since, until (ISO 8601), limit (max 100), starting_after (a call id, for paging). Each call includes duration, caller, summary, transcript, recording URL, sentiment and a 1-3 word conclusion.GET/api/v1/calls/:id
GET/api/v1/usage
POST/api/v1/outbound-calls
{agent_id, to_number, variables?}. The agent’s number is the caller ID; talk time bills at your per-minute rate. Limit 30/hour — use the dashboard’s Outbound studio for campaigns.curl -X POST https://aiphonez.com/api/v1/outbound-calls \
-H "Authorization: Bearer apz_live_..." \
-H "Content-Type: application/json" \
-d '{"agent_id":"AGENT_ID","to_number":"+15125550134","variables":{"name":"Sam"}}'Webhooks
Set a webhook URL under Settings → API and we POST a call.completed event to it after every call (same fields as the calls API). Verify authenticity with the signing secret shown in settings: the x-aiphonez-signature header is t=<unix>,v1=<hex> where v1 = HMAC-SHA256("t.body", secret). Reject events older than 5 minutes.
// Node.js verification
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const [t, v1] = [/t=(\d+)/, /v1=([0-9a-f]+)/].map((r) => (header.match(r) || [])[1]);
if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}Errors
Non-2xx responses return {"error": {"message": "..."}}. 401 bad/revoked key · 404 not yours or doesn’t exist · 429 rate limited · 400 validation.
Questions or need an endpoint we don’t have yet? Message us from Support — we ship fast.