Skip to main content
This guide takes you from no credentials to a working Platform API request using OAuth 2.1 with PKCE. You will request the read-only campaigns:read scope, so the first token cannot change anything.

Only calling the API for your own company?

Create a scoped Platform API key instead. There is no callback URL, browser redirect, consent screen, or token exchange.
Building with Connect or the Scraper API? Those products have separate credentials and setup guides.
The API-key Platform API at /api/v1 is legacy and deprecated. It is not maintained and must not be used for new integrations. Existing integrations should plan to migrate to the OAuth API at /api/oauth/v1.

Before you start

You need:
  • A SideShift account and a company with an active subscription
  • A callback URL in your application
  • curl and openssl for the commands below
For this local example, the callback URL is http://127.0.0.1:3000/oauth/callback. Redirect URIs must use HTTPS in production; HTTP is allowed only for localhost, 127.0.0.1, [::1], and explicitly supported native callbacks. Userinfo, fragments, and wildcard bind addresses are rejected. Authorization matches the registered callback exactly, except a native HTTP loopback callback may vary only the port (RFC 8252 §7.3) — so the value must otherwise be identical in every step. This quickstart uses a public client with no client secret. PKCE protects the authorization code, while your backend must still keep access tokens, refresh tokens, and the registration access token private.
SideShift publishes the two standard discovery documents at the domain root, so a client can resolve every endpoint at runtime rather than pinning the paths below.
This is authorization-server metadata (RFC 8414). code_challenge_methods_supported confirms S256 is the only PKCE method, and authorization_response_iss_parameter_supported means the authorize redirect carries an iss parameter per RFC 9207 that you should check against issuer.The companion document is protected-resource metadata (RFC 9728):
resource is the canonical resource identifier and the audience your access tokens are bound to. Both documents also list every supported scope.

1. Register your application

Register once to get a client_id. This example asks only to read campaigns and includes the refresh_token grant so the integration can stay connected.
The response starts like this:
Copy the returned values:
The registration_access_token is shown only once. Store it like a password; it can update or delete your OAuth client. It is not the token used to call the Platform API.

2. Send the user to SideShift

First, create a one-time PKCE verifier, its SHA-256 challenge, and a random state value:
Build the authorization URL for the callback and scope registered above. The callback and scope are already URL-encoded in this example; if you change either value, URL-encode the replacement too.
Open that URL in a browser. The user signs in to SideShift, chooses the company to connect, reviews the requested scope, and approves access. SideShift then redirects to your callback:
Your callback must verify that:
  • state exactly matches $SIDESHIFT_STATE
  • iss is exactly https://app.sideshift.app
If no local server is running yet, the page may fail to load, but you can still copy code from the browser’s address bar for this manual test.

3. Exchange the code for tokens

Authorization codes are short-lived and single-use. Copy the code from the callback and exchange it from your backend with the same callback URL and PKCE verifier:
You receive a one-hour access token and a refresh token:
Copy both tokens into your server-side environment for the next steps:

4. Make your first API request

Send the access token as a bearer token:
List endpoints return a cursor-paginated response:
An empty data array is a successful result when the connected company has no campaigns.
Connecting an agency parent? If the user granted direct sub-account access during consent, add X-Act-As-Company: CHILD_COMPANY_ID to run one request against that child. Do not use undocumented companyId, client, or similar query parameters as tenant selectors. See Agency sub-account requests for complete examples.

5. Refresh the connection

When the access token expires, exchange the refresh token for a new token pair:
Refresh tokens rotate and are single-use. Atomically replace the old refresh token with the new one from every successful response. Reusing an old refresh token revokes the token family.

Common errors

OAuth protected resource errors include a requestId. OAuth registration, authorization, and token endpoints instead use { error, error_description }. Include requestId when it is present and you contact SideShift support.

Before going live

  • Use an HTTPS callback URL and compare it by exact string; a native loopback HTTP callback is the only exception, and may vary only the port.
  • Store tokens and the registration access token in a secrets manager, never client-side code.
  • Request only the scopes your integration needs.
  • Verify state and iss before exchanging the authorization code.
  • Persist each rotated refresh token before discarding the previous one.

Next

Platform API

Browse capabilities, scopes, and the OAuth reference.

Authentication

Compare credentials, base URLs, and error formats.

MCP server

Use the same OAuth grant with an AI agent.