Building an app

Create an OAuth application, choose its scopes, and handle its credentials.

Create it

Publishing an app lives under Settings → API access → Publish an app, not in the settings sidebar: almost every customer wants an API key to read their own data, and only partners building a product on Superposition need an app. You will need to be an organization admin.

Then choose New app.

You provide:

  • Name — shown to anyone deciding whether to authorize it, so make it the name they would recognise.
  • Redirect URIs — one per line. These must match exactly at authorize time, so add your staging callback now rather than debugging a mismatch later.
  • Requested scopes — what the app will ask for. See Scopes.
  • Public client — turn this on for mobile, desktop, and single-page apps that cannot keep a secret. No client secret is issued and PKCE is required instead.

The client secret is shown once, immediately after creation. There is no way to retrieve it afterwards. The client id stays visible on the app list — it is public by design and travels in every authorize URL.

Requested scopes are what your app will ask for, not what it is granted. Each organization decides at the consent screen. Ask for the least you need: a consent screen full of permissions is one people decline.

The authorization flow

Standard OAuth 2.1 authorization code with PKCE.

GET https://app.superposition.ai/api/auth/oauth2/authorize
  ?client_id=<your client id>
  &redirect_uri=<one of your registered URIs>
  &response_type=code
  &scope=jobs:read%20candidates:read%20offline_access
  &resource=https://app.superposition.ai/api/v1
  &code_challenge=<PKCE challenge>
  &code_challenge_method=S256
  &state=<your CSRF value>

The resource parameter matters. It binds the token to the REST API, and a token minted for a different audience is rejected — so a token you obtained for one surface cannot be replayed against another. Ask for https://app.superposition.ai/api/v1.

Exchange the code at the token endpoint, then call the API with the access token exactly as you would with an API key:

curl https://app.superposition.ai/api/v1/jobs \
  -H "Authorization: Bearer <access token>"

Access tokens are short-lived — ten minutes. Ask for offline_access alongside your scopes to be issued a refresh token, then renew with it rather than re-sending the user through consent:

curl -X POST https://app.superposition.ai/api/auth/oauth2/token \
  -d grant_type=refresh_token \
  -d refresh_token=<your refresh token> \
  -d client_id=<your client id> \
  -d client_secret=<your client secret> \
  -d resource=https://app.superposition.ai/api/v1

Each refresh returns a new refresh token; store it and discard the old one. Without offline_access you get an access token and nothing to renew it with, and the connection stops working after ten minutes.

offline_access is not a permission over anyone's data, so it does not appear in your app's scope picker — every published app may request it.

Editing an app

Name, redirect URIs, and requested scopes can all be changed later.

Widening the requested scopes does not widen any authorization that already exists. An organization that already connected keeps exactly what it agreed to until someone authorizes again. This is deliberate: a publisher must not be able to grant themselves more access by editing their own registration.

Rotating the secret

Settings → API access → Publish an app → Rotate secret.

Unlike API keys, apps do rotate. A client id is a published identity that other organizations have already authorized, so replacing the app would revoke every existing connection. Rotating the secret in place is the only way to answer a leak without breaking your customers.

The old secret stops working immediately, so update every deployment before you rotate — or straight after, with the new value already staged.

Deleting an app

Deleting revokes every organization's authorization of it. There is no undo, and re-creating the app produces a different client id, so every customer would have to reconnect.

Last updated on

On this page