Authentication
Every request carries an API key as a bearer token in the Authorization
header:
Requests without a valid key return 401.
Key prefixes
One base URL serves both environments. The key prefix, not the URL, selects where the request lands:
ss_live_…operates on live workspace data.ss_test_…routes to the isolated developer sandbox (test mode), where uploads return premade sample extractions at no charge. Start here: sandbox calls never touch live borrower data.
Create, rotate, and revoke keys in the SpreadSpace dashboard: Settings → Live API for live keys, Settings → Sandbox API for test keys.
Scopes
Keys carry an explicit grant list checked on every request. There is no
implicit access: an API-key request to an endpoint is denied by default
unless the key holds the required scope. Missing scope → 403 with type
insufficient_scope (the message names the scope).
Format: resource:action (for example documents:read), resource:* for
all actions on a resource, or * for everything (avoid in production).
Two identity reads need no scope: GET /api/me and GET /api/organizations
only describe the caller.
Each endpoint’s reference page lists its required scope.
Scopes can be added or removed on an existing key without rotating it (dashboard → key → scopes). The change takes effect on the next request. Remove a scope to withdraw a specific permission while retaining the key’s other permissions.
Key lifecycle
A key can carry an expiry (expires_at, set when the key is created or
changed later in the dashboard). Past it the key answers 401 exactly as a
revoked key does. Rotating a key issues a replacement and keeps the old key
working for a grace period, 24 hours unless the rotation names another value
between 0 and 720 hours, so a deploy can switch credentials without a gap.
A key can also carry an allowlist of CIDR ranges. A request from any other
address answers 403 with type forbidden and no further detail, and the
attempt is recorded in the workspace’s audit log.
Keeping keys secret
API keys are server-side credentials. Never ship one in browser code, a mobile app, or a public repository: anyone holding the key can act as your integration. If a key leaks, revoke it in the dashboard and issue a replacement.
For rendering SpreadSpace inside your own app, use the
Embed flow instead: the browser gets a short-lived
ss_embed_… session token minted by your server, and your API key stays
server-side.