Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vorel.ai/llms.txt

Use this file to discover all available pages before exploring further.

The Vorel public API is a REST surface at 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

1

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. Copy the key — it’s shown only once (bcrypt-hashed in storage).The key format is vapk_<env>_<48 hex chars> (60 chars total).
2

Make your first request

curl https://app.vorel.ai/api/v1/conversations \
  -H "Authorization: Bearer vapk_live_..." \
  -H "Content-Type: application/json"
Returns a paginated list of your tenant’s conversations.
3

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.
For the complete endpoint catalog, see the API Reference tab.

Conventions

Auth

All endpoints require Authorization: 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:
{
  "data": [
    /* array of resources */
  ],
  "pagination": {
    "next_cursor": "uuid-or-null",
    "has_more": false
  }
}
Single-resource endpoints return the resource directly.

Error envelope

Every error returns a consistent shape:
{
  "error": {
    "code": "rate_limited",
    "message": "Per-key rate limit exceeded; retry after 60s."
  }
}
Codes: unauthorized, forbidden, rate_limited, bad_request, not_found, conflict, internal_error. The HTTP status code matches the semantic.

Idempotency

Mutating endpoints accept an optional Idempotency-Key header. We dedupe by (tenant_id, idempotency_key) for 24 hours. Re-playing the same request returns the original response.

Webhooks

The API also emits outbound webhooks to URLs you register at /(dashboard)/settings/integrations/webhooks. 9 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-signed; idempotency-key in the envelope. See Webhooks for the full spec.

Rate limits

The API enforces rate limits at four layers — the most-restrictive applicable layer wins:
LayerLimitTriggers when
Per-IP webhook500 req/minCalls to your tenant’s /api/webhooks/* receivers
Per-Clerk-user dashboard200 req/minAuthenticated dashboard sessions
Per-(tenant, tool)50 req/minPer-tool API endpoint (e.g. book_appointment)
Per-tenant aggregate5000 req/minTotal across all surfaces in your tenant
Hitting a limit returns 429 rate_limited with Retry-After + X-RateLimit-* headers. See Rate limits for the detailed stack.

SDKs

TypeScript / JavaScript

@vorel/sdk — full coverage, typed, zero runtime deps. npm i @vorel/sdk.

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

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.
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.
Use the n8n post-booking-confirmation template — wires a booking.created webhook to a delay node + POST /v1/conversations/{id}/send for the reminder.
Use the n8n lead-nurture-3-day template — daily cron + GET /v1/leads?status=qualified&stale_for_days=3 + POST /v1/conversations/{id}/send for re-engagement.
Use the n8n weekly-qa-rollup template — Monday cron + GET /v1/analytics/weekly-rollup + format + send via SendGrid/Slack.

Status

The API is live and stable. All v1/* 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).