Developer Portal
API keys, playground, connected apps, OAuth clients, and activity
The Developer Portal is where you manage credentials and try the API without writing code. Sign in with the same Servicebay account you use in the app.
Active admin + TOTP
Only active organisation admins (userRole === 'admin' and
active === true) can use the portal. Invited-but-not-yet-activated
members and deactivated admins do not appear in the org list. TOTP is
required on every management call — a Firebase ID token without
sign_in_second_factor === 'totp' returns 403. Enrol an
authenticator in the Servicebay app, then sign in again. See
Two-Factor Authentication.
Pro or in-app trial
The selector lists organisations that are Pro or in an in-app trial and that you actively admin. Empty states distinguish the two cases:
- No Pro organisations — you are an admin, but none of those orgs qualify. Upgrade in the Servicebay app.
- No organisations — you need the admin role (and to be activated). Pro alone is not enough without admin.
Organisation selector
Every tab acts on a single organisation. Pick yours from the dropdown in
the top bar. The choice is stored in localStorage (selectedOrg:v1)
so it persists across visits.
API keys, playground requests, connected-app grants, OAuth clients, and activity are all scoped to the selected org — switch before creating a key or sending a test request.
Tabs: API Keys, Connected Apps, OAuth Clients, Activity, API Playground.
API Keys
Create a key
Click Create API Key. Three steps:
- Label and optional description
- Permissions — presets Read only (default), Read & write,
Full, or Custom. The matrix is the same v2 model as
OAuth (
write≠delete) - Expiry (default 90 days; 30 / 90 / 365 / never), optional IP allowlist (CIDR, plus Add my current IP), and REST / MCP use (both on by default)
Copy the secret and the MCP install snippet. The secret is shown only once.
Edit, rotate, revoke
Each row shows created, last used, request count, prefix, scopes,
allowedUses, and status (Active / Revoked / Paused / Expired).
- Edit —
PATCHname, description, scopes (widen or narrow), uses, IP allowlist, expiry, or pause (active: false) - Rotate —
POST …/rotatewith grace immediate, 15 minutes, 1 hour, or 24 hours. A new secret is shown once; the old one works until grace ends - Revoke — soft-revoke. The next API call returns
401. The row stays listed. When an admin leaves, rotate every key they created
An organisation may have 50 active keys.
Playground tab cache
When you create a key in this browser tab, the portal caches its value in session storage (cleared when you close the tab). The API Playground can then auto-select that key. Keys created in other tabs still require a manual paste. The cache is never written to disk and never stored server-side.
API Playground
Call any documented endpoint with your own key and inspect status, headers, body, and round-trip time.
The playground is scope-aware. Selecting a key whose scopes cannot
call the chosen method/path disables Send and explains why
(insufficient_scope with requiredScopes, unknown_resource, or
use_not_allowed for an MCP-only key). After a live 403, the same
codes are surfaced from the response.
orgId is filled from the organisation selector. Rate-limit headers
appear next to the JSON body.
Keys you did not create in this tab
If you select a key whose value is not cached, paste it manually or create a fresh key from API Keys. Never paste production keys into shared browsers.
Connected Apps
Lists every OAuth grant for the selected organisation, including apps other admins connected. Columns include the app, Connected by, scopes (effective vs granted), registration kind, and expiry.
- Narrow permissions without reconnecting. The override can only remove scopes — widening requires the app to ask again
- Revoke — effective within seconds (Worker tombstone). If the
connecting admin is removed or deactivated, the grant is revoked
automatically and subsequent API calls return
403 - Remembered approvals — registered and CIMD clients the admin told us to skip next time (90 days). Forget clears the skip; it does not revoke the current grant. DCR clients cannot be remembered
Filter to "Show only my connections" when the list is long.
OAuth Clients
Pro admins pre-register up to 10 confidential clients per org. These never expire (unlike 365-day DCR clients).
- Redirect URIs (https or loopback; presets for known hosts)
- Confidential toggle and one-time secret
- Rotate secret — the new secret is shown once
Use this for hosts that reject public DCR (Perplexity, Copilot Studio, static Cursor/VS Code OAuth). See OAuth.
Activity
90-day audit log of API traffic for the selected org
(organisations/{orgId}/apiAuditLog). Each row: time, actor (API key,
OAuth client / grant, uid), method, path, status, IP.
Management list endpoints prefer startAfter / nextCursor. cursor
is accepted as an alias for one release.
What is written (exactly once from the route's finish(response)):
- Every non-GET (and non-HEAD)
- Every 401 and 403
- A 1-in-20 sample of GETs (derived from
requestId)
Filter by method, status class (2xx / 4xx / 5xx), grantId, or
keyId. Retention is 90 days (expiresAt); deploy a Firestore TTL
policy on that field so documents are actually deleted.