Before you start
What you need- A SideShift company account with an active subscription - OAuth protected resource
calls return
402 subscription_requiredwithout one - A backend to call from. Keys and tokens must never reach the browser
Choose how to authenticate
My own company
RecommendedCreate a scoped Platform API key for an internal dashboard, scheduled job, script, or backend service. No redirect or token exchange.
Other SideShift users
OAuth 2.1Register an app and use authorization code with PKCE when a user connects their company and approves scopes.
Platform API key
For your own company, create a key in Settings → Platform API & MCP → API keys and call any resource operation withx-api-key:
sspk_live_ or sspk_test_, belongs to one company, and carries only the
scopes selected at creation, capped by the creator’s current permissions. A parent agency can
also select direct subaccount delegation. Follow the API key quickstart for setup, safe rotation,
and copyable examples.
OAuth 2.1
Use OAuth authorization code with PKCE when your integration connects another SideShift company. The steps below summarize the flow; the OAuth quickstart contains the complete, copyable version.1
Register your application
Send your app name, callback URL, and requested scopes to
POST /api/oauth/v1/register. Save the returned client_id and one-time
registration_access_token.Start with the narrowest scope you need. For a read-only first request, use
campaigns:read.2
Create PKCE values
Generate a random
code_verifier, derive its SHA-256 code_challenge, and
create a random state. Keep the verifier and state in the user’s server-side
session.3
Send the user to SideShift
Redirect the browser to
GET /api/oauth/v1/authorize with the client_id, a registered
callback URL, scopes, state, and PKCE challenge. The callback must match a registered URI
exactly, except a native HTTP loopback callback, which may vary only the port. The user
signs in, selects a company, and approves the scopes.SideShift returns code, state, and iss to your callback. Verify state and verify
that iss is https://app.sideshift.app.4
Exchange the code
From your backend, send the code, callback URL,
client_id, and original
code_verifier to POST /api/oauth/v1/token. You receive a one-hour access
token and, when your client registered the refresh_token grant, a refresh
token.5
Call the Platform API
Send the access token as a bearer token:List endpoints return
{ data, nextCursor, hasMore }. Pass nextCursor back as
cursor to fetch the next page.OAuth endpoint map
Keep the connection active
Access tokens expire after one hour. Refresh tokens rotate on every use: save the new refresh token from each successful refresh response before discarding the previous one. Reusing an old refresh token revokes the token family.Legacy API (Deprecated)
The API-key surface is retained only for existing integrations while they migrate. It is not maintained, receives no new features or fixes, and is not an alternative setup path for new work. Existing integrations send an older key inx-api-key and use /api/v1. See the Legacy API
(Deprecated) reference in the sidebar for its frozen contract. A current sspk_… key is not
compatible with /api/v1; an older sk_live_… key is not compatible with /api/oauth/v1.
The practical difference
The current and deprecated surfaces are not the same API with different credentials. The deprecated surface is read-oriented: of its 24 operations, 19 areGET. Only five write anything -
POST /posts/exportPOST /programs/{id}/invitePOST /invoices,POST /invoices/{invoiceId}/send,POST /invoices/{invoiceId}/void
/api/oauth/v1 surface, authenticated by a scoped Platform API key or OAuth.
They also behave differently on the wire - not just different credentials, but different
pagination, error shapes, and idempotency rules.
On the legacy API only, agency (parent) accounts can pass
scope=agency on
the API key’s analytics and posts endpoints to aggregate across the parent
agency and every subaccount.MCP server
The same OAuth-scoped capabilities are exposed through a remote Model Context Protocol server atPOST /api/mcp, using the Streamable-HTTP transport. An AI agent can operate a
SideShift company through MCP tools instead of raw HTTP calls.
Connecting a client. Point any MCP client at https://app.sideshift.app/api/mcp. It
authenticates with the same OAuth 2.1 flow above - there is no MCP-specific auth scheme.
Tokens minted for MCP are multi-audience, so a single token works for both /api/oauth/v1
and /api/mcp. An unauthorized request gets a 401 with a WWW-Authenticate challenge
pointing at the RFC 9728 protected-resource metadata, so compliant clients can auto-discover
the authorization server.
What you get. Every capability scope maps to tools, mirroring the REST surface plus a
whoami tool. Read scopes expose read-only tools. Write and sensitive tools carry a
confirmation guardrail in their description. The claim-link capability is available as the
create_quickpay_claim_link tool.
Sandbox and sensitive operations
Test and sandbox grants can exercise reads and safe writes, but requests that move money or trigger outbound side-effects - payouts, sending invoices or messages, external re-scrapes - are rejected. Getting a sandbox client. For a human OAuth integration, pass"sandbox": true when you
register, then complete the authorization-code flow:
sandbox claim, and the guarded routes refuse
it with 403 and payouts:write is not available for sandbox (test-mode) grants. There is no
separate sandbox host. The OAuth sandbox flag is set at registration and cannot be changed
afterward. For an internal script, the API key dialog offers a Test mode.
Public registration does not authorize machine access; use the dashboard for
company automations.
Two things worth knowing before you rely on it. Only the literal JSON true enables test mode,
so "true" or 1 leave the client in production mode; this is deliberate, because the damaging
mistake is a real client silently having its payouts refused. And the flag cannot be changed
afterwards - register a separate client rather than promoting one out of test mode, since
integrations may already depend on its writes being inert.
Money-moving endpoints and campaign analytics-history validation/import requests require an
Idempotency-Key.
Sensitive MCP tools are rejected for sandbox and test grants, and can be disabled globally
with the MCP_SAFE_MODE server flag.
Coverage
Campaigns and programs are the same concept; the current spec names them campaigns, the legacy spec names them programs.
The current reference spans the full Platform surface and documents both supported authentication
methods. The legacy reference remains frozen and narrow.