LIVE · AUDIT-CHAINED · EU-RESIDENT
SYSTEM · 99.99% UPTIME
v 1.0 ↗ MADE IN EU

Authentication

Every public-API request carries a credential pair — nb_pub_* (public key) + nb_sec_* (secret). The secret is sent as a Bearer token. The credential is scoped to a single org + a fixed scope catalog.

Issuing credentials

  1. Sign in to your org at app.nexbasira.com.
  2. Go to Admin → API credentials.
  3. Click Issue credential, pick a name + scopes, confirm.
  4. Copy the nb_pub_* + nb_sec_* pair. The secret is shown exactly once. Store it in your secrets manager immediately — we keep only a SHA-256 hash on our side.

Using the credential

Authorization: Bearer nb_sec_AbCdEf...

The public key (nb_pub_*) identifies the credential in our logs + appears in webhook deliveries' NB-Credential-Id header. The secret authenticates.

curl https://app.nexbasira.com/api/v1/public/sessions \
  -H "Authorization: Bearer nb_sec_..."

Scope catalog

Each credential is created with an explicit scope set. Requests outside those scopes return 403. The scope catalog is fixed (no custom scopes at v1):

ScopeGrants
sessions:readList + retrieve sessions
sessions:writeCreate sessions + end them
participants:readList participants on a session
participants:writeMint field-user invites
evidence:readList + retrieve evidence rows + signed download URLs
recordings:readRead recording artefact metadata + download URLs
audit:readRead the per-session audit chain + TSA anchor coordinates
webhooks:readList registered webhook endpoints + delivery log
webhooks:writeRegister / rotate-secret / delete webhook endpoints
branding:readRead org branding (logo / colours / PDF footer)
branding:writeMutate org branding
org:readRead org metadata
whiteboards:readList whiteboards per session

Rotation

To rotate without downtime:

  1. Issue a new credential with the same scope set.
  2. Deploy the new secret to your application.
  3. Verify the new credential is taking traffic (Admin → API credentials shows last-used timestamp).
  4. Soft-revoke the old credential. Existing requests using it 401; the audit trail of past calls stays intact.

Constant-time verification

On the backend, secrets are stored as SHA-256(secret + SECRET_KEY_pepper) and compared in constant time (hmac.compare_digest). A leaked hash dump cannot be brute-forced into the plaintext without also breaking the pepper.

What this credential does NOT grant

  • SPA admin access — that's separate (operator login + RBAC).
  • Field-side join — those use one-shot signed URLs minted via sessions.invite().
  • SCIM provisioning — uses a separate per-org bearer token, see SCIM provisioning.
  • Webhook signing — that's done with the per-endpoint whsec_* secret, see Webhooks.

Audit trail

Every API call is logged with the credential's public key + the endpoint + status. Operations that mutate state additionally write audit rows in the affected org. Admin can view the credential's activity at Admin → API credentials → [credential] → Activity.