AI Phone 360 · Developers
Developer Platform · Beta

Build on AI Phone 360

Programmatically access your calls, transcripts, recordings and contacts, send SMS, react to events in real time with webhooks, and let your AI receptionist call your own systems live during a conversation — all over a clean REST API.

Getting access

The developer platform is a premium capability that runs on the same billing model as the rest of AI Phone 360 — a paid subscription plus metered usage.

You need three things to use the API:
  1. A paid AI Phone 360 organization with an active subscription (BASIC, PRO, or ENTERPRISE).
  2. The Developer Platform add-on enabled on your organization. During the beta this is granted by our team — request access.
  3. A positive credit balance (the same wallet that powers your calls & texts).

Once your organization has the add-on, generate API keys from the dashboard at Settings → Developer, or via the keys API.

No active subscription or out of credits → the API is blocked. Exactly like your phone calls: if your subscription lapses, or your credit balance reaches $0 and can't auto-recharge, every live API request, webhook delivery, and AI tool call stops with a 402 until you add funds. Webhooks that fire while you're blocked are queued and delivered once you reload (up to 30 days).

Quickstart

Every request goes to https://api.aiphone360.com/api/public/v1 and is authenticated with your API key as a Bearer token.

1. List your most recent calls

curl https://api.aiphone360.com/api/public/v1/calls?limit=5 \
  -H "Authorization: Bearer aip_live_your_key_here"

2. Send a text message

curl -X POST https://api.aiphone360.com/api/public/v1/messages \
  -H "Authorization: Bearer aip_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to":"+15555550123","body":"Thanks for calling!"}'

That's it. Responses are JSON in a consistent envelope (see Errors for the shape). For TypeScript/Node, the official SDK wraps all of this with types, retries, and webhook verification.

Authentication

Authenticate every request with an API key, sent as a Bearer token:

Authorization: Bearer aip_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

(The header x-api-key: <key> is also accepted.) Keys come in two modes, distinguished by prefix:

PrefixModeBehavior
aip_live_LiveReal data, real side-effects, metered & billed.
aip_test_Test (sandbox)Never bills, never sends real SMS or triggers real side-effects. See Test mode.
Keep keys secret. A key is shown once at creation — store it in a secret manager. Keys are scoped (least-privilege) and can be rotated or revoked instantly. Never embed a live key in client-side / browser / mobile code.

Billing & credits

The platform bills like everything else in AI Phone 360: your monthly subscription is required for access, and usage is metered against your credit wallet on top of a generous monthly free quota.

Metered actionUnitNotes
API requestper 1,000 requestsBilled in 1,000-request blocks after your monthly free quota.
Webhook deliveryper delivery attemptEvery attempt counts (including retries) so you can rely on at-least-once delivery.
Custom-tool invocationper callEach time the AI calls one of your endpoints (voice or chat).
SMS sent via APIper segmentBilled through your existing SMS usage (carrier passthrough) — same rate as the app.

Exact per-unit rates and free quotas depend on your plan and are shown on your dashboard. Everything is recorded — you (and our team) can see every billed request, webhook, and tool call, tagged by API key, in usage reporting.

Test-mode is always free. Requests made with an aip_test_ key are counted for visibility but never charged and never debit your wallet.

Scopes & keys

Each API key is granted a set of least-privilege scopes. A request to an endpoint whose scope your key lacks returns 403 INSUFFICIENT_SCOPE. Grant a key only what it needs.

ScopeGrants
read:callsList & read calls.
read:transcriptsRead call transcripts.
read:recordingsRead call recording URLs.
read:contactsList & read contacts.
write:contactsCreate & update contacts.
write:smsSend SMS via POST /messages.
read:usageRead config & list your keys.
manage:configUpdate AI config; create/revoke keys.
manage:webhooksManage webhook endpoints & deliveries.
manage:toolsManage custom tools.
manage:agentsManage specialized AI agents.

Test mode

Use a aip_test_ key to build and test safely:

  • Reads return your real data (read-only is safe).
  • POST /messages returns a synthetic success — no real SMS is sent, no carrier charge.
  • Webhooks & tool calls triggered in test mode are flagged and never billed.
  • Test usage never debits your wallet and never blocks on balance.

Switch to a aip_live_ key when you're ready for real side-effects.

Pagination

List endpoints are cursor-paginated. Pass limit (max 100) and the cursor from the previous page's pagination.nextCursor:

let cursor;
do {
  const page = await client.calls.list({ cursor, limit: 100 });
  for (const call of page.data) { /* … */ }
  cursor = page.pagination.nextCursor;
} while (cursor);

Errors

Every response uses a consistent envelope. Success:

{ "success": true, "data": { …payload… }, "message": "…" }

Failure carries a stable machine code and HTTP status:

{ "success": false, "error": { "message": "…", "code": "INSUFFICIENT_SCOPE", "status": 403 } }
CodeStatusMeaning
API_KEY_REQUIRED401No key supplied.
INVALID_API_KEY401Key not found, revoked, or expired.
PLATFORM_ADDON_REQUIRED402Developer add-on not enabled for this org.
SUBSCRIPTION_REQUIRED402No active paid subscription.
INSUFFICIENT_CREDITS402Wallet is out of credits — add funds to resume.
INSUFFICIENT_SCOPE403Key lacks a required scope.
BUSINESS_SUSPENDED403Organization suspended for abuse/compliance.
RESOURCE_NOT_FOUND404The id doesn't exist (or isn't yours).
VALIDATION_ERROR400Request body/query failed validation.
RATE_LIMIT_EXCEEDED429Too many requests — back off (honor Retry-After).

Rate limits

Requests are rate-limited per API key. On 429, honor the Retry-After header and back off. The official SDK retries 429 and 5xx automatically with exponential backoff.

Calls

GET/calls

List calls (newest first). Scope read:calls. Query: limit, cursor, direction, dateRange, search.

GET/calls/{callSessionId}

Full detail for one call. Scope read:calls.

GET/calls/{callSessionId}/transcript

The call transcript (speaker-attributed turns). Scope read:transcripts.

GET/calls/{callSessionId}/recording

A recording URL (when available). Scope read:recordings.

Contacts

GET/contacts

List contacts. Scope read:contacts. Query: limit, cursor, search.

GET/contacts/{id}

One contact. Scope read:contacts.

POST/contacts

Create a contact. Scope write:contacts. Body: phoneNumber (required), name, email, company.

PATCH/contacts/{id}

Update a contact. Scope write:contacts.

Messages (SMS)

POST/messages

Send an SMS from your AI Phone 360 number. Scope write:sms. Body: to, body.

TCPA / DNC is enforced server-side. A send to a number that opted out (replied STOP), or that you have no established relationship with, is blocked with a 422. This is the same compliance chokepoint the app uses — it protects your number's reputation. Pass an Idempotency-Key header so retries never double-send.

AI config

GET/config

Read a curated subset of your AI configuration. Scope read:usage.

PATCH/config

Update a curated, safe subset of config (e.g. language, timezone, call-handling mode). Scope manage:config. Sensitive settings (payments, spam, PII) are never writable via the API.

Webhooks (manage)

Scope manage:webhooks for all of these. See the Receiving webhooks guide for the delivery format.

GET/webhooks
POST/webhooks

Register an endpoint. Body: url (public HTTPS), events (array). Returns a whsec_… signing secret — store it to verify deliveries.

PATCH/webhooks/{id}
DELETE/webhooks/{id}
POST/webhooks/{id}/test

Send a test delivery to verify your endpoint.

GET/webhooks/{id}/deliveries
POST/webhook-deliveries/{id}/redeliver

Inspect delivery history and replay any delivery.

API keys (manage)

GET/keys

List your keys (masked). Scope read:usage.

POST/keys

Create a key — returns the secret once. Scope manage:config. Body: name, mode (test|live), scopes.

DELETE/keys/{id}
POST/keys/{id}/rotate

Revoke, or rotate with a grace window so you can roll the new key out with zero downtime.

Custom tools (manage)

Scope manage:tools. See the AI calls your systems guide.

GET/tools
POST/tools
PATCH/tools/{id}
DELETE/tools/{id}

AI agents (manage)

Scope manage:agents. Define multiple specialized AI agents for one business — e.g. a billing agent that can send a payment link and collect an invoice number, and a product-support agent that collects a serial number and searches only that product's knowledge. A main greeter agent (isDefault: true) answers every call and hands off in-call to the right specialist; the caller goes AI → AI in the same call, no redial. Define no agents and your single AI agent handles everything (default).

GET/agents
POST/agents
PATCH/agents/{id}
DELETE/agents/{id}

Create body: agentKey (lowercase id, unique per business), displayName, instructions (the specialist's focused role — knowledge comes from your knowledge base via RAG, don't paste it here), matchHints[] (caller-intent phrases the greeter routes on), tools ({ useCustomToolIds[], allowPayments, allowBooking, allowTransfer, allowKnowledgeSearch }useCustomToolIds empty = the agent may use all your custom tools), knowledgeBaseIds[] (RAG scope — empty = all business knowledge), isDefault, enabled. Tool and knowledge-base ids must belong to your business. To make an agent collect specific fields, create a data-collection field with that agent's agentId.

curl -X POST https://api.aiphone360.com/api/public/v1/agents \
  -H "Authorization: Bearer aip_live_…" -H "Content-Type: application/json" \
  -d '{"agentKey":"billing","displayName":"Billing","instructions":"You handle billing. Collect the invoice number and offer a secure payment link.","matchHints":["bill","invoice","refund"],"tools":{"allowPayments":true}}'

Receiving webhooks

Register an HTTPS endpoint and AI Phone 360 will POST a JSON event the instant something happens. Delivery is at-least-once — dedupe on event.id. Each event:

{
  "id": "evt_…",
  "type": "call.completed",
  "createdAt": "2026-06-28T20:00:00Z",
  "businessId": "…",
  "data": { …event-specific payload… }
}

Event types

EventFires when
call.startedAn inbound call begins.
call.completedA call ends & post-call processing finishes (incl. summary).
transcript.readyThe transcript is available.
sms.receivedAn inbound text arrives.
sms.sentAn outbound text is sent.
voicemail.createdA voicemail is recorded.
contact.created / contact.updatedA contact is created / meaningfully changed.
appointment.bookedAn appointment is booked.

Retries use exponential backoff; an endpoint that fails repeatedly is auto-disabled (you'll see it in delivery logs). Every delivery attempt is metered.

Verifying webhook signatures

Every delivery carries an X-AIP-Signature header: t=<unix>,v1=<hex> where v1 is HMAC-SHA256(secret, "<t>.<rawBody>"). Always verify before trusting the payload, using the whsec_ secret from when you created the endpoint. The SDK does this for you:

import { AiPhone360 } from "@aiphone360/sdk";
import express from "express";

app.post("/webhooks/aiphone", express.raw({ type: "application/json" }), (req, res) => {
  try {
    // Pass the RAW body bytes, not a parsed object.
    AiPhone360.verifyWebhook(req.body.toString("utf8"), req.headers["x-aip-signature"], process.env.AIP_WEBHOOK_SECRET);
  } catch {
    return res.status(400).send("bad signature");
  }
  const event = JSON.parse(req.body.toString("utf8"));
  // handle event.type …
  res.sendStatus(200);
});

Verification rejects a timestamp older than 5 minutes to stop replay attacks. Doing it manually in another language? Recompute the HMAC over `${t}.${rawBody}` and compare in constant time.

Let the AI call your systems

Custom tools let your AI receptionist call your API live during a phone call or text — to look up an order, check availability, create a ticket, anything. You describe the tool; AI Phone 360 calls your HTTPS endpoint when the conversation needs it and relays the result back to the AI.

  1. Register a tool (dashboard or POST /tools) with a name, description, JSON-schema for its inputs, your HTTPS endpointUrl, and optional auth.
  2. During a call, the AI decides to use it and AI Phone 360 POSTs { arguments, callSessionId, tool } to your endpoint.
  3. Your endpoint responds with JSON within ~10 seconds; the AI uses it as data (never as instructions — results can't change call control flow).
Secure by construction. Your endpoint must be public HTTPS (internal/private addresses are rejected). Your auth secret is stored encrypted and never exposed to the AI. The AI never reads card numbers or your secrets. Each invocation is metered.
Make your endpoint fast and resilient. If your endpoint is slow (>10s) or errors, the call degrades gracefully (the AI moves on) — it never hangs the caller. Return concise JSON; large responses are truncated.

Official SDK

The TypeScript/Node SDK wraps the API with types, automatic retries, cursor pagination, and webhook verification.

npm install @aiphone360/sdk
import { AiPhone360 } from "@aiphone360/sdk";

const client = new AiPhone360({ apiKey: process.env.AIP_KEY });
// mode is auto-detected from the key prefix (aip_test_ / aip_live_)

const { data } = await client.calls.list({ limit: 25 });
await client.sms.send({ to: "+15555550123", body: "Hi from our app" });
const contact = await client.contacts.create({ phoneNumber: "+15555550123", name: "Jordan" });

Errors throw a typed AiPhone360Error with code, status, and a requestId (give that to support). 429/5xx are retried automatically.