Developer Docs

REST Auth

Bearer API-key authentication, route RBAC, field permissions, and version handling.

Bearer Tokens

Every public REST route uses bearer API-key auth unless the route is explicitly public health or share-token access.

Authorization: Bearer <api-key>
Accept: application/json
Content-Type: application/json

The auth layer resolves keys in this order:

  1. Provisioned environment keys in lib/auth.ts.
  2. User-generated keys stored by the API-key management surface.

Route And Field Permissions

Each key has:

  • Allowed route patterns such as GET /projects/:id or PATCH /projects/:id/workstreams.
  • fields_read and fields_write lists, or *.
  • Client and project scope.

Authorization failures return:

  • 401 when the bearer token is missing or invalid.
  • 403 when the key is valid but lacks route, field, client, or project access.

Scoped Keys

Use the narrowest key that matches the workflow:

Key familyTypical use
willa-adminInternal automation with full access.
willa-kickoffProject setup, documents, scheduling, transcripts, shot lists.
willa-exec-dashboardRead-heavy dashboard and telemetry access.
willa-shopify-appShopify embedded app bootstrap, snapshots, sessions, staged actions.
willa-qa-extensionQA extension bootstrap, page mappings, QA item intake.
willa-figma-section-ledgerFigma plugin section ledger and project resolution.
willa-granolaMeeting transcript and scope-decision ingestion.

Optimistic Concurrency

Mutable record endpoints protect against lost updates with X-Version.

X-Version: 4

If the version is missing, malformed, or stale, the route returns a validation or conflict response. Refresh the resource, read the latest version, and retry only after reconciling the change.

Public Route Hygiene

The public unauthenticated bypass list lives in proxy.ts. A route only bypasses Clerk when it performs its own auth inside the handler, is an inbound verified webhook/cron route, or is intentionally public like /api/status.