Skip to main content

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 return 202; 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 /v2 to coexist.
  • Errors — a single envelope { error: { code, message, details? } }; map status codes accordingly. See Errors & validation.
  • Pagination — cursor-based (keyset). Lists return { items, cursor }; pass limit and cursor to page.
  • Rate limits — a per-key throttle (default 600 req/min) returns 429 with Retry-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/events for Resend, /public/twilio/* for Twilio) — see Webhooks.
  • Short-URL resolution (/r/:slug).