Overview
Advanza is a multitenant SaaS marketing platform that supports OpenID Connect (OIDC) and OAuth 2.0 for secure authentication and single sign-on (SSO). This guide covers supported flows, endpoints, scopes, and best practices for integrating Advanza authentication into your applications.
Protocol: OpenID Connect 1.0 (built on OAuth 2.0 Authorization Code Grant)
Provider: Advanza (via OpenIddict 5.x)
Multi-Tenancy: Full support – each organization is a separate tenant
Security: HTTPS required, PKCE recommended for SPAs, certificates for confidential clients
Supported Authentication Flows
Authorization Code Flow (Recommended)
The OAuth 2.0 Authorization Code Flow is the recommended and most secure flow for most applications, including web apps and single-page applications (SPAs). It uses PKCE (Proof Key for Code Exchange) for public clients to prevent authorization code interception attacks.
Best for: Web applications, SPAs, mobile apps, third-party integrations
Refresh Token Flow
Use refresh tokens to obtain new access tokens without requiring the user to sign in again. Refresh tokens are valid for 14 days and can be rotated to maintain security.
Best for: Long-lived sessions, background services, offline access
Client Credentials Flow (Legacy)
The OAuth 2.0 Resource Owner Password Credentials flow is supported for backward compatibility with legacy integrations. New integrations should use the Authorization Code Flow instead.
Best for: Legacy applications, internal tools (not recommended for new development)
API Endpoints
All endpoints are hosted at https://api.advanza.ai
Authorization Endpoint
GET /connect/authorize
Initiates the OAuth authorization flow. Redirects user to sign in with their identity provider (Microsoft, Google, or email/password).
Query Parameters:
client_id(required): Your application IDredirect_uri(required): URL to redirect after authenticationresponse_type(required): Must be 'code'scope(required): Space-separated list of scopes (openid, email, profile, offline_access, roles)code_challenge(required for SPA): PKCE code challengecode_challenge_method(required with code_challenge): 'S256'state(recommended): Random string to prevent CSRF attackstenant_id(optional): Specific tenant to authenticate into
Token Endpoint
POST /connect/token
Exchanges an authorization code for access tokens, ID token, and optional refresh token.
Request Format: application/x-www-form-urlencoded
Parameters:
grant_type(required): 'authorization_code', 'refresh_token', or 'password'code(required for auth code flow): Authorization code from /authorizeclient_id(required): Your application IDclient_secret(required): Your application secret (keep confidential)redirect_uri(required): Must match the /authorize requestcode_verifier(required for SPA): PKCE code verifierrefresh_token(for refresh flow): The refresh token to exchangeusername & password(for password flow): User credentials
Token Introspection Endpoint
POST /connect/introspect
Validates and inspects the contents of an access token or refresh token.
OpenID Configuration
GET /.well-known/openid-configuration
Standard OIDC metadata endpoint. Returns discovery information including endpoints, public keys, supported scopes, and grant types.
Scopes
Request scopes via the scope parameter on the authorization request:
openid (required)
Requests an ID token containing the user's identity information (subject claim, name, tenant ID, etc.)
Requests user email address and email verification status
profile
Requests user profile information: name, given_name, family_name
offline_access
Requests a refresh token to extend access without requiring re-authentication
roles
Requests the user's roles/permissions (e.g., "Owner", "Editor", "Viewer")
Minimum scope for login: openid email profile
Example: Authorization Code Flow with PKCE
This example demonstrates the recommended flow for single-page applications (SPAs) and mobile apps.
Step 1: Generate PKCE Challenge
Create a code verifier and challenge on the client side:
// 1. Generate random code verifier (43-128 characters)
const codeVerifier = generateRandomString(128);
// 2. Create code challenge via SHA256 hash
const codeChallenge = await crypto.subtle.digest('SHA-256',
new TextEncoder().encode(codeVerifier)
);
// 3. Base64-URL encode the challenge
const codeChallengeB64 = base64UrlEncode(codeChallenge);
// Store codeVerifier in sessionStorage for Step 3
sessionStorage.setItem('pkce_verifier', codeVerifier);Step 2: Redirect to Authorization Endpoint
Direct the user to sign in:
GET /connect/authorize?
client_id={your_app_id}
&redirect_uri=https://your-app.com/callback
&response_type=code
&scope=openid email profile
&code_challenge={pkce_challenge}
&state={random_state}The user will be redirected to their identity provider (Microsoft, Google, or email/password), complete authentication, and be redirected back to your redirect_uri with an authorization code.
Step 3: Exchange Code for Tokens
From your backend, exchange the authorization code:
POST /connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={auth_code}
&client_id={your_app_id}
&client_secret={your_app_secret}
&redirect_uri=https://your-app.com/callback
&code_verifier={pkce_verifier}Step 4: Token Response
On success, you receive:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "DefxA1234567890...",
"id_token": "eyJhbGciOiJSUzI1NiIs..."
}Step 5: Verify ID Token
Validate the ID token signature using the public key from /.well-known/openid-configuration, verify the issuer and audience claims, and extract user information.
Token Claims
ID Token Claims
The ID token (JWT) contains user identity information:
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@company.com",
"email_verified": true,
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"tenant_id": "12345678-1234-1234-1234-123456789012",
"iss": "https://api.advanza.ai",
"aud": "your_app_id",
"iat": 1234567890,
"exp": 1234571490
}Key Claims:
sub: Unique user identifier (Guid)email: User's email addressemail_verified: Whether email is verifiedname, given_name, family_name: User's nametenant_id: User's active tenant/organizationiss: Token issuer (always https://api.advanza.ai)aud: Intended audience (your application ID)iat: Token issued at (Unix timestamp)exp: Token expiration (Unix timestamp)
Access Token Claims
The access token (JWT) contains authorization information:
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@company.com",
"name": "John Doe",
"tenant_id": "12345678-1234-1234-1234-123456789012",
"roles": ["Owner"],
"scope": "openid email profile offline_access roles",
"iss": "https://api.advanza.ai",
"aud": "your_app_id",
"iat": 1234567890,
"exp": 1234571490
}Key Claims:
sub: User IDemail, name: User informationtenant_id: Active tenant (use for multi-tenancy routing)roles: User's roles in the tenantscope: Granted scopesexp: Expiration (typically 1 hour)
Use Access Token For: Include in Authorization header (Authorization: Bearer {access_token}) when calling Advanza APIs or your backend.
Multi-Tenancy
Advanza is a multitenant platform. Each user can be a member of multiple organizations (tenants). The tenant_id claim in both ID and access tokens indicates the user's active tenant context.
Default Tenant
On first sign-in, the user is assigned a default tenant. The tenant_id claim will be populated with this tenant's ID.
Switching Tenants
Users with multiple tenant memberships can switch tenants by passing the desired tenant_id parameter to the authorization endpoint:
GET /connect/authorize?
client_id={your_app_id}
&redirect_uri=https://your-app.com/callback
&response_type=code
&scope=openid email profile
&tenant_id=12345678-1234-1234-1234-123456789012
&code_challenge={pkce_challenge}Routing by Tenant
Use the tenant_id claim to route requests to the correct tenant context in your backend:
// Extract tenant from token claims
const tenantId = tokenClaims.tenant_id;
// Route request to tenant context
const tenantContext = getTenantContext(tenantId);
const result = await performAction(tenantContext, action);Security Best Practices
Use HTTPS in Production
All OAuth requests must use HTTPS to protect credentials and tokens.
PKCE for SPAs and Mobile Apps
Always use PKCE (Proof Key for Code Exchange) for public clients. This prevents authorization code interception attacks.
Keep Client Secret Confidential
Never expose your client secret in client-side code, logs, or version control. Only use it in secure backend-to-backend communication.
Validate State Parameter
Always generate and validate the state parameter to prevent CSRF attacks.
Verify Token Signatures
Always validate ID token and access token signatures using the public key from the OIDC configuration endpoint before trusting their contents.
Refresh Tokens Securely
Store refresh tokens securely (HttpOnly cookies or secure storage, not localStorage). Set appropriate expiration times.
Handle Token Expiration
Access tokens expire after 60 minutes. Implement token refresh logic to maintain uninterrupted access.
Support
For questions, issues, or integration assistance, please contact our support team:
Email: support@advanza.ai
Documentation: https://advanza.ai/docs
Status: https://status.advanza.ai