Skip to main content
If your app runs outside the Max AI dashboard (a standalone web app, mobile app, or portal), you need a way to identify which Max AI user is logged in. The OAuth 2.0 Authorization Code flow lets users sign in with their Max AI account and share their identity with your app.
Embedded apps (running inside the Max AI iframe) don’t need OAuth — they receive user context automatically via the App Bridge. OAuth is only for standalone/external apps.

Prerequisites

Before setting up OAuth, you need:
  1. A developer accountGet started if you haven’t already
  2. A marketplace app — Create one in the developer console or via the CLI
  3. An API key — Generate one from the developer console under your app’s API Keys tab (see Authentication)
Your app’s slug (used as client_id in OAuth) is visible in the developer console on your app’s settings page.

How It Works

Redirect to Max AI

Your app sends the user to /oauth/authorize with your client_id, redirect_uri, and a random state nonce for CSRF protection.

User authenticates and consents

Max AI handles login (via Clerk), then shows a consent screen where the user reviews your app’s permissions and selects which organizations to authorize.

Redirect back with code

Max AI redirects the user to your redirect_uri with a short-lived authorization code and the original state parameter.

Exchange code for user info

Your backend calls POST /v3/oauth/token with the authorization code and your API key. This is a server-to-server call — the code is never exposed to the browser.

Receive identity

Max AI returns an OIDC id_token (ES256 JWT), user profile, and the list of authorized organizations with their facilities.

Setup

1. Register Redirect URIs

Add your callback URLs to the [oauth] section of your app manifest (max-ai.app.toml):
Or configure them in the developer console under your app version’s OAuth tab.
Redirect URIs must exactly match — including scheme, host, port, and path. No wildcards. localhost is allowed for development.

2. Redirect to Authorize

When a user wants to sign in with Max AI, redirect them to the authorize endpoint:
The user will see a consent screen showing your app’s name, the permissions it requires, and which organizations to authorize.

3. Handle the Callback

After the user approves (or denies), Max AI redirects to your redirect_uri: On approve:
On deny:
Always verify that the returned state matches the one you sent. This prevents CSRF attacks.
Authorization codes expire after 10 minutes and can only be used once. Exchange them immediately.

4. Exchange the Code

Your backend exchanges the authorization code for user info by calling the token endpoint. Authenticate with your app’s API key:
The token endpoint does not require the X-Organization-Id header. The authorization code already encodes which organizations the user authorized.

5. Receive User Info

The token endpoint returns the user’s identity, authorized organizations, and an OIDC-compliant id_token:

6. Make API Calls

Now that you know the user and their organizations, use the organization IDs as the X-Organization-Id header when calling the Public API:
The X-Organization-Id must be one of the organization IDs returned in authorizedOrganizations. Your API key provides data access; the OAuth flow provides user identity.

Code Example

Token Exchange Errors

The token endpoint returns OAuth 2.0 spec-compliant errors:

Repeat Authorization

When a user authorizes your app, the grant is remembered. On subsequent OAuth flows:
  • Same permissions — the user is redirected back instantly (no consent screen)
  • Permissions changed — the consent screen is shown again
  • Force re-consent — add prompt=consent to the authorize URL to let users change which organizations they share

OpenID Connect

The id_token is a standard OIDC JWT signed with ES256. You can verify it using the public key from the JWKS endpoint: The id_token contains standard OIDC claims:

Embedded vs External Apps

You can support both — use the App Bridge when embedded, and OAuth when accessed standalone.