ProRankedDashboard ↗

Connect a ProRanked account

Let an operator connect their ProRanked account to your app with a "Connect ProRanked account" button instead of asking them to copy an API key out of the dashboard. Your app runs a standard OAuth 2.1 authorization-code flow with PKCE, the operator approves a consent screen once, and you get back tokens you can use to list their networks and mint your own network-pinned API keys.

This is the recommended integration for a platform that onboards ProRanked operators — an ERP, a CRM, a fleet tool. Day-to-day API traffic still uses the API keys you mint; OAuth is only the front door that replaces the pasted key.

This flow uses a confidential client (your server holds a client secret and performs the token exchange). Confidential clients are provisioned by ProRanked, not self-registered — see Get a client. The self-serve OAuth clients section of the dashboard registers public (browser, PKCE-only) clients for a different use case.

At a glance

GrantAuthorization code + PKCE (S256), confidential client
Authorize URLhttps://id.proranked.com/connect/authorize
Token URLhttps://id.proranked.com/connect/token
Revoke URLhttps://id.proranked.com/connect/revoke
UserInfo URLhttps://id.proranked.com/connect/userinfo
Discoveryhttps://id.proranked.com/.well-known/openid-configuration
Scopesopenid profile email offline_access cpms cpms:read:networks cpms:write:apikeys
Access tokenJWT, 30 minutes, audience https://api.proranked.com/cpms/v1
Refresh token30 days, rotates on every use (the presented token is invalidated)

Get a client

Confidential clients are provisioned per deployment — one client_id + secret per domain your app runs on, so a leaked secret is contained to a single deployment. To register one, send ProRanked:

  • your redirect URIs (multiple are fine — e.g. a production callback and a local dev callback),
  • a display name (shown on the operator's consent screen), and
  • the deployment's domain.

You'll receive a client_id and a client_secret. Store the secret server-side; never ship it in client code.

The flow

1. Redirect to authorize

Generate a PKCE code_verifier + code_challenge (S256) and a state, then send the operator to:

https://id.proranked.com/connect/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://app.example.com/api/v1/ev/oauth/callback
  &scope=openid%20profile%20email%20offline_access%20cpms%20cpms:read:networks%20cpms:write:apikeys
  &code_challenge=CHALLENGE
  &code_challenge_method=S256
  &state=STATE

The operator signs in and sees a consent screen naming your app and the capabilities you asked for ("View the networks on your ProRanked account", "Create and revoke API keys for your networks"). On approval they're redirected back to your redirect_uri with ?code=…&state=…. The grant is remembered, so a returning operator isn't prompted again.

2. Exchange the code

Server-side, exchange the code for tokens. Because the client is confidential, send your secret; because the request used PKCE, send the code_verifier.

POST https://id.proranked.com/connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=THE_CODE
&redirect_uri=https://app.example.com/api/v1/ev/oauth/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&code_verifier=THE_VERIFIER

Response:

{
  "access_token": "eyJ…",
  "token_type": "Bearer",
  "expires_in": 1800,
  "refresh_token": "eyJ…",
  "scope": "openid profile email offline_access cpms cpms:read:networks cpms:write:apikeys"
}

Encrypt the refresh_token at rest — it's what keeps the connection alive.

3. Label the connection

Call GET /cpms/v1/me with the access token to get the connected account's id and email so you can show "Connected as [email protected]":

GET https://api.proranked.com/cpms/v1/me
Authorization: Bearer eyJ…
{ "data": { "operatorId": "1d47…", "email": "[email protected]",
            "accessibleNetworkCount": 3, "scopes": ["cpms:read:networks","cpms:write:apikeys"] },
  "success": true }

Use the token

Four operations accept the operator Bearer token. Everything else keeps using the API keys you mint.

OperationRequest
Who is connectedGET /cpms/v1/me
List their networksGET /cpms/v1/networks
Mint a network-pinned keyPOST /cpms/v1/api-keys?networkUuid={uuid}
Revoke a keyDELETE /cpms/v1/api-keys/{id}
POST https://api.proranked.com/cpms/v1/api-keys?networkUuid=NETWORK_UUID
Authorization: Bearer eyJ…
Content-Type: application/json

{ "name": "Persona — Acme site" }

The minted key is returned once. Use it as an X-API-Key for that network's day-to-day traffic exactly as a pasted key — same behavior, same scopes.

The connecting operator must be an Operator or Admin on the network. ProRanked derives the token's effective permissions from the operator's own role, so a Viewer's token can read networks but cannot mint keys (the mint returns 403). This is intentional — the token can never grant more than the person who approved it already has.

Refresh

Access tokens last 30 minutes. Refresh with the stored refresh token:

POST https://id.proranked.com/connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=THE_REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET

Refresh tokens rotate: each refresh returns a new refresh token and invalidates the one you sent. Always persist the newest one. A refresh token is valid for 30 days from issue.

Disconnect

When the operator disconnects your app, revoke the token (RFC 7009):

POST https://id.proranked.com/connect/revoke
Content-Type: application/x-www-form-urlencoded

token=THE_REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET

Revoking a refresh token invalidates the connection; drop your stored tokens.

Handling expiry — the reconnect path

When a token is expired or revoked, the API answers 401 Unauthorized. On an expired access token the response also carries a Token-Expired: true header — try a refresh first. If the refresh also fails with 401 (the operator disconnected, or the 30-day window lapsed), the connection is gone: clear your stored tokens and show a "Reconnect ProRanked" button that restarts the flow at step 1.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token"