MRC and FMG are separate integrations. This guide covers MRC (
mrc.* scopes) with its own Client ID/Secret. For FMG contacts/content, see the FMG APIs → OAuth guide. If you integrate both, you run this flow once per product — two client credentials, two consents, two tokens.The MRC APIs are not yet available. The OAuth integration below is ready to use; API endpoints, scopes, and the API base URL will be published when the MRC APIs are released.
What FMG provides
FMG provisions your MRC application per environment — sandbox first, then production. Build and test against sandbox, then repeat with the production values.What you provide
You give FMG one thing up front:
FMG registers these in its OAuth service (Stytch) against your MRC Client ID. Only registered URIs are accepted at authorization time.
Why the redirect URI matters
The redirect URI is the most security-critical value you register, because it is where the authorizationcode is delivered:
- After the advisor approves consent, the authorization server sends the browser to
redirect_uri?code=.... Whoever controls that URL receives the code and can exchange it for tokens. - So the authorization server treats your registered URIs as a strict allowlist: the
redirect_uriin the authorize request must match a registered URI exactly — scheme, host, port, and path. A mismatch is rejected before any code is issued. - This closes authorization-code interception / open-redirect attacks — an attacker can’t substitute their own callback to capture the code, because an unregistered URI never matches.
- It must be HTTPS and a URL your server controls (no wildcards, no fragments). Register every environment’s callback, since sandbox and production use different values.
Flow at a glance
1
Generate PKCE + state
Server-side, create a
code_verifier, its code_challenge (S256), and a random state.2
Redirect to authorize
Send the advisor’s browser to the Authorize URL with your request parameters.
3
Handle the callback
FMG redirects back with
code and state. Validate state.4
Exchange code for tokens
Server-side
POST to the Token URL with the code, code_verifier, and client_secret.5
Call MRC APIs
Use the
access_token as a Bearer token. Refresh it when it expires.Step 1 — Generate PKCE parameters
Generate these on your server and storecode_verifier + state in the user’s server-side session:
Step 2 — Redirect to authorization
Redirect the advisor’s browser to the Authorize URL:
The advisor authenticates and approves a consent screen listing your requested permissions.
Step 3 — Handle the callback
FMG redirects to yourredirect_uri:
- Compare
stateagainst the session value — abort on mismatch (CSRF). - Retrieve the
code_verifierfrom the session. - Clear both from the session — they are single-use.
Step 4 — Exchange the code for tokens
Server-sidePOST to the Token URL. Authenticate with your client_secret:
refresh_token is only returned when the offline_access scope is granted. Store both tokens securely (server-side session or HttpOnly cookie — never localStorage).
Step 5 — Call MRC APIs
The MRC APIs are not yet available. When released, you will call them with the access token as a Bearer token (
Authorization: Bearer {access_token}); their endpoints and required scopes will be documented under MRC APIs → API Reference.Step 6 — Refresh the access token
When the access token expires (401 response), use the refresh token to get a new one without sending the advisor through the flow again:
Scopes
Request exactly the scopes FMG assigned you — requesting an unprovisioned scope fails.MRC API scopes (for sending SMS, reading delivery status, and similar operations) are not yet available and will be published here when the MRC APIs are released. The flow currently issues identity scopes only (
openid, offline_access).Errors
Security requirements
- PKCE (S256) for every request; keep the
code_verifierserver-side. - Unique
stateper request; validate on callback. - Token exchange and refresh are server-side only — never expose
client_secretorcode_verifierto the browser. - HTTPS for all redirect URIs and API calls.
- Store tokens in HttpOnly cookies or server-side sessions.