Skip to main content
A human OAuth token is limited by its issued scopes, the app’s current scope selection, the current consent, and the person’s live company permissions. Platform API keys and new company automations also follow their creator’s current access. See Team and integration permissions for dashboard setup and lifecycle behavior. Scope enforcement is identical for every scope: a request without the required scope fails with 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.
Signature and standard-claim checks can run offline. The live permission, client, and consent checks cannot: SideShift also checks revocation and subscription eligibility when a token calls its resources. A cryptographically valid token can still receive 401, 402, or 403 insufficient_scope. Do not use offline JWT verification as proof of current company access.
Do not treat a token as valid purely because it parses. A revoked grant produces a token that still verifies cryptographically until it expires.

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.scopes array 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:read permits credential inspection; settings:write permits creation and revocation. team:write cannot grant capabilities beyond the caller or credential, and a scoped credential cannot promote Owners or propagate team changes to siblings.
Agency credentials may delegate no subaccounts, selected subaccounts, or all current and future subaccounts. Each delegated call verifies the current parent relationship, user access, and the target’s scope ceiling. Aggregate reports filter to that same permitted set. Set 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 on kid 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 through POST /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
A member with an explicit 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.