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:
| Parameter | Value |
|---|---|
response_type | code |
client_id | The connection's client ID |
redirect_uri | Exact registered callback URL, including any query string |
state | Random session-bound value, at most 512 characters |
code_challenge | The PKCE S256 challenge |
code_challenge_method | S256 |
scope | Space-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.