Skip to main content

Authorisation code flow

This guide assumes you have registered a connection. Use the endpoint URLs shown in that connection's settings. All token exchange and profile requests happen on your application's server.

1. Start sign-in​

Generate a cryptographically random state value and store it in the application's server-side login session. Generate a PKCE verifier of 43–128 characters from A–Z a–z 0–9 - . _ ~. Calculate code_challenge = BASE64URL(SHA256(code_verifier)), without padding, and keep the verifier in the same session.

Redirect the member's browser to the authorisation endpoint with:

ParameterValue
response_typecode
client_idThe connection's client ID
redirect_uriExact registered callback URL, including any query string
stateRandom session-bound value, at most 512 characters
code_challengeThe PKCE S256 challenge
code_challenge_methodS256
scopeSpace-separated scopes; defaults to profile email membership

The browser is sent to RemyPass's member login and approval screen. Requests expire after ten minutes. After approval the callback receives code and the original state. Cancellation returns error=access_denied and state. Invalid client or callback details produce a local JSON error rather than redirecting to an untrusted destination.

At the callback, verify state against the initiating browser session before exchanging the code. Codes expire after 60 seconds and can be exchanged once. Restart the sign-in flow after an expired or reused code.

2. Exchange the code from the application server​

Send a form-encoded POST to the token endpoint. Authenticate with HTTP Basic using the client ID as username and client secret as password (client_secret_basic). Alternatively include client_id and client_secret in the form body (client_secret_post). Do not combine both methods or put the secret in a URL.

grant_type=authorization_code
code=<received code>
redirect_uri=<the exact redirect_uri used at authorisation>
code_verifier=<the original verifier>

Example response:

{
"access_token": "<opaque token>",
"token_type": "Bearer",
"expires_in": 600,
"scope": "profile email membership"
}

There is no refresh token, password grant, implicit flow or client-credentials grant. Keep the token server-side. Start a new authorisation flow when it expires. The token is bound to the member's RemyPass portal session; logging out or revoking that session invalidates its access.

3. Read the profile and establish your application session​

Call GET /api/v1/oauth/userinfo with Authorization: Bearer <access_token>. Match the returned sub to the linked account in your application, then establish your own session. See the profile response and scopes.

Keep each pending login's state, PKCE verifier and callback URL together in the initiating browser's server-side session. Consume that pending login after a successful callback. A callback with an unexpected state must not log anyone in.

PKCE example​

This Node.js fragment prepares an authorisation URL. session.pendingOAuth represents your framework's server-side session; replace the example configuration with your connection details.

const { randomBytes, createHash } = require('node:crypto');

const state = randomBytes(32).toString('base64url');
const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const redirectUri = 'https://app.example.com/oauth/remypass/callback';

session.pendingOAuth = { state, verifier, redirectUri };
const url = new URL('https://api.remypass.com/api/v1/oauth/authorize');
url.search = new URLSearchParams({
response_type: 'code',
client_id: process.env.REMYPASS_CLIENT_ID,
redirect_uri: redirectUri,
state,
code_challenge: challenge,
code_challenge_method: 'S256',
scope: 'profile email membership',
}).toString();
// Redirect the member's browser to url.toString()

The callback above is an example. Register the exact callback used by your application.

Token exchange example​

After validating callback state, send the saved verifier and callback URL along with the received code. The environment variables below are placeholders populated by your server configuration and callback handler.

curl --request POST 'https://api.remypass.com/api/v1/oauth/token' \
--user "$REMYPASS_CLIENT_ID:$REMYPASS_CLIENT_SECRET" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode "code=$OAUTH_CODE" \
--data-urlencode "redirect_uri=$OAUTH_REDIRECT_URI" \
--data-urlencode "code_verifier=$OAUTH_CODE_VERIFIER"

Do not repeatedly retry a code exchange after it succeeds. Codes are single-use; reuse is rejected and can revoke an access token issued from that code.

For errors and token lifetime rules, see the endpoint reference.