https://app.vorel.ai/api/v1/*. It’s the same surface our @vorel/sdk TypeScript client uses, the same surface n8n around-the-brain workflows use, and the same surface your custom integrations should target.
Quickstart
Generate an API key
Sign in at
app.vorel.ai, navigate to Settings → Integrations → API keys, click Create API key. Pick the scopes your integration needs: read, leads:write, appointments:write, offerings:write, conversations:write, crm:write. Copy the key; it’s shown only once (scrypt-hashed in storage).The key format is vapk_live_<48 hex chars> (58 chars total). See Authentication for the full lifecycle.Browse the full reference
The API Reference tab in this docs site auto-renders from our live OpenAPI spec: every endpoint, every parameter, every response shape, with interactive “try it” examples per route.
What the API exposes
Conversations
Read inbound conversations across voice + chat. List, get-by-id, create (pre-create from your
CRM webhook), update.
Leads
Read + write leads. Update qualification state, attach attributes, trigger handoff, mark stale.
Appointments
Read + write appointments. Schedule, reschedule, cancel, complete. Lifecycle webhooks emit on
every transition.
Offerings
Read + write your catalog (properties / services / treatments / menu items, vertical-specific).
Soft-delete supported.
Analytics
GET /v1/analytics/weekly-rollup: aggregate metrics for the prior N days. Powers
around-the-brain digest workflows.CRM proxy
POST /v1/crm/create-record: write into your tenant’s connected CRM via Vorel’s per-tenant
driver layer. Same path the agent uses.Conventions
Auth
All endpoints requireAuthorization: Bearer <api_key>. Keys are tenant-scoped; one key only sees its own tenant’s data, enforced via Postgres RLS.
Endpoints that mutate state require a write scope (leads:write, appointments:write, offerings:write, conversations:write). Endpoints that only read accept the read scope. A key without the matching scope returns a 403 forbidden envelope.
Response shapes
Successful responses are JSON. List endpoints use cursor pagination:next_cursor and has_more are top-level fields alongside data (not nested under a pagination object). Pass next_cursor back as ?cursor=<uuid> to fetch the next page; has_more is false and next_cursor is null when you’ve reached the end.
Single-resource endpoints return the resource directly.
Error envelope
Every error returns a consistent shape:unauthorized, forbidden, rate_limited, bad_request, not_found, conflict, internal_error. The HTTP status code matches the semantic.
Idempotency
POST /v1/crm/create-record accepts an idempotency_key field in the request body. The value is forwarded into the per-tenant CRM driver so the underlying CRM can dedupe its own write. Other write endpoints don’t currently accept an idempotency key; safe-retry semantics there rely on the resource’s natural unique constraints (e.g. (tenant_id, channel, customer_identifier) for conversations).
Webhooks
The API also emits outbound webhooks to URLs you register at/(dashboard)/settings/integrations/webhooks. 12 event types: lead.created, lead.updated, lead.qualified, conversation.created, conversation.handoff_requested, conversation.closed, booking.created, booking.rescheduled, booking.cancelled, booking.completed, offering.created, offering.updated. Bodies are HMAC-SHA256 signed via X-Webhook-Signature; the envelope id field doubles as the consumer’s idempotency key.
See Webhooks for the full spec.
Rate limits
API requests are gated by a layered rate-limit stack. The most-restrictive applicable layer wins:| Layer | Limit | Triggers when |
|---|---|---|
| Per-API-key | 200 req/min | Each issued vapk_* key has its own bucket (apk:<key_id>) |
| Per-tenant aggregate | 5000 req/min | Total across every authenticated surface in your tenant |
| Per-(tenant, tool) | 50 req/min | Each internal tool endpoint (e.g. book_appointment) consumed by the agent |
| Per-dashboard-user | 200 req/min | Authenticated dashboard sessions (separate from API keys) |
| Per-IP webhook | 500 req/min | Inbound calls to /api/webhooks/* (WhatsApp / voice / auth webhook receivers) |
429 rate_limited with Retry-After + X-RateLimit-Limit + X-RateLimit-Remaining + X-RateLimit-Reset headers. See Rate limits for the detailed stack.
SDKs
TypeScript / JavaScript
@vorel/sdk is a full-coverage, typed client with zero runtime deps. Today the REST API plus
the live OpenAPI spec are the supported integration path; a published @vorel/sdk package is
on the roadmap.OpenAPI (any language)
Live OpenAPI 3.1 spec. Import into Postman / Insomnia / Bruno, or generate a client in any
language via
openapi-generator / oazapfts / etc.Common integration patterns
Push a lead from your website form
Push a lead from your website form
Call
POST /v1/conversations to pre-create the conversation from your form’s
customer-identifier (phone/email), then POST /v1/leads to attach the qualification data. The
next time the customer calls or WhatsApps, Vorel matches them to the existing conversation by
(channel, customer_identifier). No fragmentation.Get notified when a new lead qualifies
Get notified when a new lead qualifies
Subscribe to the
lead.qualified webhook event. Vorel POSTs to your URL with the lead row + the
conversation’s last 10 messages. HMAC-signed; verify the signature before acting.Send a 24h booking reminder
Send a 24h booking reminder
Use the n8n post-booking-confirmation template: wires a
booking.created
webhook to a delay node + POST /v1/conversations/{id}/send for the reminder.Daily lead-nurture cadence
Daily lead-nurture cadence
Use the n8n lead-nurture-3-day template: daily cron +
GET /v1/leads?stale_for_days=3 + POST /v1/conversations/{id}/send for re-engagement. The
stale_for_days filter already scopes to qualified leads whose conversation has gone quiet
for more than N days, so no separate status filter is needed (and none is supported today).Weekly analytics digest
Weekly analytics digest
Use the n8n weekly-qa-rollup template: Monday cron +
GET /v1/analytics/weekly-rollup + format + send via an email provider or Slack.Status
The API is live and stable. Allv1/* endpoints have stable contracts; we’ll version-bump (/v2) before any breaking change.
Public status page: app.vorel.ai/status. Expect ~99.9% on the API surface (per our SLOs).