Developers

REST API and webhooks.

Read and manage everything on your agency account, and push real-time call and booking events into any outside system. A Scale-plan feature, with API keys, scoped access, and signed webhooks. Every endpoint and event below lists a short "when you would use it" so you (or an AI assistant) can wire up an integration fast.

Get API keys
Bearer API key 11 signed events Live booking data

Plan

API keys, the REST API, and webhooks are a Scale plan feature. Call-center agencies get them on any plan, and agencies on a free trial are treated as Scale while trialing. Below that, requests return upgrade_required.

Base URL

Basehttps://urchin-app-bqb4i.ondigitalocean.app/api/v1

All paths below are relative to this base.

Authentication

Every request authenticates with an API key, created in the agency dashboard under Settings → API keys. The full key is shown once at creation; only a SHA-256 hash and a short prefix are stored, so a lost key is revoked and replaced, never recovered. Keys are agency-scoped.

Authorization: Bearer YOUR_API_KEY
read

Default. All GET endpoints.

read_write

POST, PATCH, DELETE. A write with a read key returns 403.

Conventions

Errors

{ "error": { "type": "insufficient_scope", "message": "This API key is read-only." } }

Status codes: 401 authentication_error, 403 insufficient_scope, 404 not_found, 400/500 api_error.

Pagination

List endpoints take limit (1–100, default 25) and cursor. Pass the returned cursor back to page.

{ "data": [ ... ], "has_more": true, "next_cursor": "2026-10-20T14:03:00.000Z" }

Single objects return directly. Only allowlisted public fields are returned; internal IDs and secrets never leave the API.

Clients

GET/clientsList clients (paginated).WhenSync your client roster into your own CRM or billing view.
POST/clientsread_writeCreate and auto-provision a client (assistant + phone number).WhenOnboard a client straight from your own signup form or ops tool.
GET/clients/:idOne client.WhenShow a single client's details in your own dashboard.
PATCH/clients/:idread_writeUpdate client fields.WhenPush an edit (business name, notification phone) made in your system.
DELETE/clients/:idread_writeRemove a client.WhenOffboard a client automatically when they cancel in your tool.
GET/clients/:id/provisioning-status/:jobIdPoll provisioning after a create.WhenShow a live 'setting up...' state right after you create a client.

Receptionist & Knowledge base

GET/clients/:id/receptionistCurrent AI config: prompt, voice, greeting, transfer.WhenRead a client's current prompt and voice to display or audit.
PATCH/clients/:id/receptionistread_writeUpdate the AI config.WhenChange the greeting or transfer number from your own UI.
GET/clients/:id/knowledge-baseThe client's knowledge base.WhenExport what the AI knows about the business for review.
PUT/clients/:id/knowledge-baseread_writeReplace the knowledge base.WhenSync hours, services, and FAQs from your own source of truth.

Calls

GET/callsList calls (paginated). Filter by client_id and date range.WhenNightly pull of every call into your CRM or data warehouse.
GET/calls/:idOne call: outcome, captured details, summary, transcript.WhenOpen a single call's transcript and summary inside your app.
GET/calls/:id/recordingA fresh, authenticated recording URL.WhenFetch a playable recording link on demand (links expire).

Appointments (read only)

GET/appointmentsList appointments. Filter by client_id, status, since, until.WhenShow upcoming bookings on a client's ops board.
GET/appointments/:idOne appointment.WhenLook up one booking's details by id.

There is no endpoint to create or reschedule an appointment. Appointments are created by the AI during calls. See Calendar booking.

Numbers · Usage · Analytics

GET/numbersPhone numbers across the agency's clients.WhenAudit which number each client is running on.
GET/usageUsage: minutes, billable clients.WhenBill your own clients from real minute usage.
GET/analytics/callsCall analytics and aggregates.WhenFeed call volume and outcomes into a reporting dashboard.

Webhook management

GET/eventsThe event catalog.WhenDiscover the exact event names before subscribing.
POST/webhooksread_writeSubscribe a URL to events.WhenWire VoiceAI into Zapier, Make, n8n, or your own endpoint.
GET/webhooksList subscriptions.WhenSee everything you're subscribed to.
PATCH/webhooks/:idread_writeUpdate URL, events, or status.WhenMove your endpoint or change events without re-creating.
DELETE/webhooks/:idread_writeDelete a subscription.WhenTurn a subscription off.
GET/webhooks/:id/deliveriesDelivery log: status, attempts, response code.WhenDebug why your endpoint didn't receive an event.
POST/webhooks/:id/pingread_writeSend a test ping event.WhenTest your endpoint end to end before going live.

Subscribe

POST /webhooks
{
  "url": "https://yourapp.com/hooks/voiceai",
  "events": ["call.completed", "appointment.booked"],
  "description": "CRM sync"
}

Use "events": ["*"] to subscribe to everything.

Event catalog

call.startedA call begins (live event; carries a call_session_id).
WhenFlash a live-call indicator or start a screen-pop.
call.completedA call ends. Enriched with the full call (see payloads).
WhenCreate a CRM activity and text the owner the second a call ends.
call.transferredThe call was transferred to the business line. Enriched.
WhenTrack how often calls reach a human, and when.
call.escalatedA call-center agent took over a live call.
WhenAlert a manager when an agent jumps into a live call.
appointment.bookedThe AI booked an appointment. Google Calendar only.
WhenMirror the booking into your ops calendar or a confirmation flow.
client.provisionedA new client finished provisioning.
WhenKick off your own welcome sequence when a client goes live.
client.provisioning_failedProvisioning failed.
WhenPage yourself if a client setup breaks, before they notice.
client.payment_failedA client's payment failed.
WhenTrigger a dunning email from your billing tool.
client.subscription_activatedA client subscription activated.
WhenMark a client as paying in your CRM.
client.trial_expiredA client trial expired.
WhenStart a win-back sequence when a trial lapses.
client.canceledA client was canceled.
WhenUpdate churn tracking and stop your own billing.

Envelope

{ "id": "evt_uuid", "type": "call.completed", "created_at": "...", "data": { ... } }

Signature verification

Each delivery is signed. Header:

X-VoiceAI-Signature: t=<unix_ts>,v1=<hex>

where v1 = HMAC-SHA256(secret, t + "." + rawBody). Verify against the raw body before parsing JSON.

// Node
const crypto = require('crypto');
function verify(rawBody, header, secret) {
  const p = Object.fromEntries(header.split(',').map(x => x.split('=')));
  const expected = crypto.createHmac('sha256', secret)
    .update(p.t + '.' + rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(p.v1));
}

Deliveries are logged and retried on failure. Stored payloads keep a short-lived recording_url; use recording_api_url or GET /calls/:id/recording for a fresh one.

Payloads

call.completed / call.transferred

id, caller_phone, customer_name, customer_phone, customer_email,
customer_address, service_requested, urgency_level, sentiment,
appointment_booked, appointment_time,
ai_summary, summary, transcript,
recording_url      (short-lived),
recording_api_url  (durable, auth with your API key),
ended_reason, transfer_status, is_spam, spam_reason,
call_language, started_at, ended_at

Carries the whole call, so you can ingest it from the webhook alone with no follow-up GET.

appointment.booked

id, client_id, business_name, customer_name, customer_phone,
appointment_time, end_time, duration_minutes, timezone,
service_type, staff_name, notes,
status ("confirmed"), booking_source ("ai_receptionist"),
google_event_id, google_calendar_id, calendar_link, created_at

Calendar booking

Automated booking is Google Calendar only. The AI checks live availability and writes the event during the call only when the client has Google Calendar connected. Without it, the AI captures the request but does not confirm a slot, and appointment.booked does not fire.

Google Calendar

Full automated booking. appointment.booked fires with the event link.

Outlook · M365 · Acuity · Calendly · other

No native automated booking yet. Use the recipe below.

Recipe: non-Google calendars

1. Subscribe a webhook to  call.completed
2. On each event, read:    data.appointment_booked, data.appointment_time,
                           customer_name, customer_phone, service_requested
3. Create the event in your calendar (Microsoft Graph, Acuity,
   Calendly, Cal.com, iCloud) from those fields.

The AI did not check that calendar's live availability or confirm a slot on the call, so treat it as a requested appointment, not a double-book-safe confirmed one. Real-time availability against a non-Google calendar needs a native integration.

Roadmap

Not available yet:

  • Native automated booking for Microsoft 365 / Outlook, Cal.com, Calendly, Acuity.
  • A write API for appointments (create / reschedule / cancel) with matching events.