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).
A few narrower scopes exist for key inventory and compliance evidence; the dashboard’s scope picker is the complete catalog.
Scopes can be added or removed on a live key without rotating it
(dashboard → key → scopes). The change takes effect on the next request. The
intended use is surgically cutting a leaked capability (for example removing
embed:write) while the key’s other traffic keeps flowing.
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.