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
| Grant | Authorization code + PKCE (S256), confidential client |
| Authorize URL | https://id.proranked.com/connect/authorize |
| Token URL | https://id.proranked.com/connect/token |
| Revoke URL | https://id.proranked.com/connect/revoke |
| UserInfo URL | https://id.proranked.com/connect/userinfo |
| Discovery | https://id.proranked.com/.well-known/openid-configuration |
| Scopes | openid profile email offline_access cpms cpms:read:networks cpms:write:apikeys |
| Access token | JWT, 30 minutes, audience https://api.proranked.com/cpms/v1 |
| Refresh token | 30 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.
| Operation | Request |
|---|---|
| Who is connected | GET /cpms/v1/me |
| List their networks | GET /cpms/v1/networks |
| Mint a network-pinned key | POST /cpms/v1/api-keys?networkUuid={uuid} |
| Revoke a key | DELETE /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"