insufficient_scope rather than silently returning less data.
Ask for the narrowest set that does the job. Consent screens show every scope you request,
and a request for money-moving access is the most common reason a company declines.
The scope catalog
SideShift defines 71 capability scopes. 69 of them can be requested by a third-party client and consented to by a company;offline_access is a protocol signal rather than a capability, and 1 scope
(performance:read) is grantable only to SideShift’s own organisation.
16 scopes are marked sensitive: they move money or change company
configuration, the consent screen highlights them, and their tools are rejected for
sandbox tokens. Request only what your integration needs.
Sensitive scopes
Sensitive scopes are not enforced differently, but they carry extra guards further down:- Their tools and endpoints are rejected for sandbox and test grants, so a test integration cannot move money or send outbound communication.
- The MCP server can disable them globally with
MCP_SAFE_MODE. - Money-moving writes require an
Idempotency-Key, so a retried call cannot double-charge. See idempotency.
Verifying an access token
Access tokens are JWTs signed by SideShift. A resource server can verify one without calling SideShift on every request:1
Fetch the signing keys
GET /api/oauth/v1/jwks returns the public JWKS. Cache it and refresh on an unknown
kid, which is what a key rotation looks like from outside.2
Check the signature and standard claims
Verify the signature against the matching
kid, then check iss matches the issuer from
discovery, aud matches https://app.sideshift.app/api/oauth/v1, and exp is in the
future.3
Check the scope for the operation
For a human grant, SideShift intersects the token’s scopes with the app’s current scope
selection, current consent, and the subject’s live company permissions on every resource verification. A downgrade therefore takes effect immediately,
even on a token that was already issued. The grant separately retains the original consented
set, so an authorized role or permission change can take effect on the next refresh, but can
never add a scope the company did not consent to. Anything outside the effective scopes must
fail rather than degrade.
401, 402, or
403 insufficient_scope. Do not use offline JWT verification as proof of current company access.
Team role ceiling for human grants
Team members, scoped Platform API keys, OAuth grants, and MCP use the same public capability names. The dashboard groups them by page or resource with independent Read and Write selections. Signing contracts (contracts:sign), withdrawing funds
(wallet:withdraw), and paid scraping (scraper:write) are separate permissions.
- Owners retain full team access. Admin and Employee permissions can be customized.
- A saved
permissions.scopesarray is the exact grant; an empty array grants no capabilities. Legacy boolean fields are derived from that selection. - Existing memberships without a scope array retain their previous behavior. In particular, legacy restricted Employees keep their reporting-only OAuth ceiling until an authorized manager saves an explicit scope selection.
- A direct subaccount membership takes precedence over inherited agency membership. Canonical company and parent owners retain ownership authority.
- Human OAuth grants and Platform API keys are intersected with the user’s current permissions on every verification. Removing membership or reducing permissions removes access from existing credentials. Refresh cannot exceed the consented grant.
settings:readpermits credential inspection;settings:writepermits creation and revocation.team:writecannot grant capabilities beyond the caller or credential, and a scoped credential cannot promote Owners or propagate team changes to siblings.
X-Act-As-Company on each Platform API request, or
act_as_subaccount_id on each MCP tool call. Neither changes the connected company.
Switching the connection itself requires a new authorization.
Existing unscoped Integration and Scraper keys keep their legacy behavior. Create new
scoped keys in Settings → Platform API & MCP → API keys. Scoped Platform keys also
work with /api/v1 through x-api-key; delegated aggregate reports use the Platform API.
Signing a contract now requires contracts:sign; an existing grant with only
contracts:write must be authorized for that additional permission.
client_credentials tokens identify the app as their subject. New dashboard automations also
retain the creator and enforce that person’s live company permissions on issuance and resource
requests. Existing company-bound machine apps without a creator retain their binding. Dynamic
registration and human consent do not authorize machine access. Follow
Company automations for the dashboard-authorized flow.
Key rotation
Signing keys rotate. Clients that cache the JWKS should key their cache onkid and refetch
when they see one they do not recognise, rather than on a fixed timer. Both discovery
documents and the JWKS endpoint are public and unauthenticated.
Managing clients and grants from the dashboard
Registration does not have to go throughPOST /register. Settings → Platform API & MCP lets an
authorized team member:
- Register a client for their own company automation, or an app other SideShift companies can connect to
- Review every third-party app the company has connected, with granted scopes, and revoke any connection
- Browse this scope catalog interactively
- Run read-only requests against the API without writing any code
permissions.scopes array is checked against those scopes directly:
settings:read to browse and inspect registered clients and connections, settings:write to
register or revoke one. A member without a scopes array falls back to the legacy rule instead -
owners and admins always qualify, and any other member qualifies only if their manageApiKeys
permission is enabled.
That is the quickest route for a single-company integration. Dynamic client registration
remains the right path for a distributed app.
An Employee who lacks settings:read (or, on a legacy membership, manageApiKeys) cannot
register clients, manage API keys, or review connections, but can still open Get started on
the same page to connect their own MCP session. That session is subject to the team-permission
ceiling above.