Authentication

Send a bearer token on every request:

Authorization: Bearer <token>

Two kinds of token exist. Both are bound to a user and carry that user's roles.

Sessions

The sign-in flow native clients use. No passwords, no cookies.

  1. POST /auth/link with { "email" }. If the address belongs to a user, a single-use link goes out, valid for 15 minutes. The response is always { "sent": true }, so addresses can't be enumerated. Repeat requests inside a minute are absorbed.
  2. POST /auth/confirm with the token from the link. You get back a 30-day bearer, its expiry, and the user.
  3. POST /auth/signout revokes the bearer you sent.

API keys

For scripts, integrations and CI. POST /api-keys with a label (and optionally expiresInDays, default 365) mints a long-lived bearer with the caller's roles. The key value is returned once. GET /api-keys lists your live keys, DELETE /api-keys/{id} revokes one.

Who am I

GET /me returns the user behind the token, their roles, the token's kind and expiry, and a can map:

{
  "data": {
    "id": "…", "email": "you@yourband.com", "name": "You",
    "roles": ["office"],
    "token": { "id": "…", "kind": "api_key", "expiresAt": "2027-09-27T09:18:06.110Z", "label": "calendar sync" },
    "can": { "gigs.view": true, "gigs.edit": true, "pay.view": true, "pay.edit": false, "…": "…" }
  }
}

Capabilities

Resources are grouped, and each group has two capabilities. Reading needs <group>.view; creating, updating, deleting and running operations needs <group>.edit.

Group Resources
gigs gigs, venues, gig products, gig contacts
catalog products, ensembles, ensemble roles, product ensembles, roles, teams, prices
staffing gig roles, gig role invitations, staff member roles, staff member blockouts
people staff members, contacts
pay rates, staff member product rates

Grants live on roles. * grants everything; gigs.* grants both capabilities of a group. A request without the capability gets 403 forbidden; without a valid token, 401 unauthenticated.

Push devices

Native clients register for push with POST /devices (token, platform, environment, appVersion, optional label). Registering the same token again updates the row. DELETE /devices/{token} removes it.