Public API & integrations overview
There is one HTTP API — the /v1 surface described in the Internal API section — and external integrators reach it the same way the SPA does, except they authenticate with an API key instead of a session. The same requireTenant middleware, the same can() permission gates, the same error envelope, and the same RLS tenant isolation all apply.
What an integrator can call
Any /v1 endpoint the key's scopes permit. The catalogue is the union of the domain route groups (see the API overview route table). The high-value integration surfaces are:
- Surveys & responses — create/list surveys, capture responses server-side (
POST /v1/surveys/:id/responses), bulk-import historical responses (POST /v1/surveys/:id/responses/import), search and read responses, and create durable filtered/survey export runs. - Exports — manage survey-bound templates and schedules, create idempotent runs under
/v1/export-runs, poll their status, cancel an in-progress build, and download retained manifest/CSV parts through permission-checked Worker routes. Requests return202; no R2 credential or object key is exposed. - Distribution — invite over email/SMS/IVR (
POST /v1/surveys/:id/invite,/invite/bulk,/invite/file). See Channels. - Webhooks — register outbound webhooks to receive events (
POST /v1/webhooks), inspect the delivery ledger, replay dead-lettered deliveries. See Webhooks. - API keys — create, list, and revoke keys (
/v1/api-keys). See API keys. - Compliance & GDPR, agents, reporting/KPIs, short URLs, inbound number mapping — all under
/v1.
Each mutating endpoint is gated by a permission (e.g. POST /v1/short-urls requires surveys.distribute; POST /v1/webhooks requires integrations.manage). The key only succeeds where its scopes resolve to that permission.
Authentication
Send the plaintext key on every request, either way:
Authorization: Bearer voc_sk_xxxxxxxxxxxxxxxxxxxx
X-API-Key: voc_sk_xxxxxxxxxxxxxxxxxxxx
requireTenant routes any voc_sk_-prefixed bearer or any X-API-Key to verifyApiKey, which resolves the tenant and the key's permissions. There is no tenant header — the tenant is bound to the key. See API keys for the scope model and storage, and Authentication for the verification path.
Conventions integrators must follow
- Versioning — the surface is explicitly versioned at
/v1, allowing a future/v2to coexist. - Errors — a single envelope
{ error: { code, message, details? } }; map status codes accordingly. See Errors & validation. - Pagination — cursor-based (keyset). Lists return
{ items, cursor }; passlimitandcursorto page. - Rate limits — a per-key throttle (default 600 req/min) returns
429withRetry-After. See Rate limiting. - Least privilege — a key with no recognised scope has no access; only an
admin-scoped key has the full catalogue.
Unauthenticated public surfaces
Distinct from the integration API, several /public/* endpoints take no key at all and resolve the tenant server-side. These exist for respondents and providers, not for general integration:
- Respondent capture and survey read (
/public/surveys/*) — see the capture pipeline. - Email open/click tracking (
/public/track/o|c/:token) and the autolaunch loader (/public/embed.js). - Inbound provider webhooks (
/public/email/eventsfor Resend,/public/twilio/*for Twilio) — see Webhooks. - Short-URL resolution (
/r/:slug).