Skip to main content
The Ave SDK provides low-level functions for building OAuth authorization URLs and exchanging authorization codes for access tokens.

Basic OAuth Flow

Here’s a complete OAuth flow using PKCE (Proof Key for Code Exchange):
1

Generate PKCE credentials

Create a code verifier and challenge for secure OAuth:
import { generateCodeVerifier, generateCodeChallenge } from "@ave-id/sdk";

const verifier = generateCodeVerifier();
const challenge = await generateCodeChallenge(verifier);

// Store verifier in sessionStorage to use later
sessionStorage.setItem("ave_code_verifier", verifier);
2

Build authorization URL

Create the URL to redirect users to Ave for login:
import { buildAuthorizeUrl } from "@ave-id/sdk";

const url = buildAuthorizeUrl(
  {
    clientId: "YOUR_CLIENT_ID",
    redirectUri: "https://yourapp.com/callback",
  },
  {
    codeChallenge: challenge,
    codeChallengeMethod: "S256",
    scope: ["openid", "profile", "email"],
  }
);

// Redirect to Ave
window.location.href = url;
3

Handle the callback

After the user logs in, Ave redirects back to your app with a code:
import { exchangeCode } from "@ave-id/sdk";

// Extract code from URL
const params = new URLSearchParams(window.location.search);
const code = params.get("code");

// Retrieve stored verifier
const verifier = sessionStorage.getItem("ave_code_verifier");

// Exchange code for tokens
const tokens = await exchangeCode(
  {
    clientId: "YOUR_CLIENT_ID",
    redirectUri: "https://yourapp.com/callback",
  },
  {
    code,
    codeVerifier: verifier,
  }
);

console.log(tokens.access_token);
console.log(tokens.id_token);

API Reference

generateCodeVerifier

Generates a cryptographically random code verifier for PKCE.
function generateCodeVerifier(): string
Returns: A base64url-encoded random string Example:
const verifier = generateCodeVerifier();
// "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

generateCodeChallenge

Generates a code challenge from a verifier using SHA-256.
function generateCodeChallenge(verifier: string): Promise<string>
verifier
string
required
The code verifier from generateCodeVerifier()
Returns: A base64url-encoded SHA-256 hash of the verifier Example:
const challenge = await generateCodeChallenge(verifier);
// "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

buildAuthorizeUrl

Builds the OAuth authorization URL.
function buildAuthorizeUrl(
  config: AveConfig,
  params?: {
    scope?: Scope[];
    state?: string;
    nonce?: string;
    codeChallenge?: string;
    codeChallengeMethod?: "S256" | "plain";
    extraParams?: Record<string, string>;
  }
): string
config
AveConfig
required
Configuration object
params
object
Authorization parameters
Returns: The full authorization URL Example:
const url = buildAuthorizeUrl(
  { clientId: "app_123", redirectUri: "https://app.com/callback" },
  { scope: ["openid", "email"], codeChallenge: challenge }
);
// https://aveid.net/signin?client_id=app_123&redirect_uri=...

exchangeCode

Exchanges an authorization code for access tokens.
function exchangeCode(
  config: AveConfig,
  payload: {
    code: string;
    codeVerifier?: string;
  }
): Promise<TokenResponse>
config
AveConfig
required
Configuration object (same as buildAuthorizeUrl)
payload
object
required
Returns: TokenResponse object
access_token
string
Opaque access token
access_token_jwt
string
JWT version of the access token
id_token
string
OIDC ID token (if openid scope requested)
refresh_token
string
Refresh token (if offline_access scope requested)
expires_in
number
Token lifetime in seconds
scope
string
Granted scopes (space-separated)

refreshToken

Exchanges a refresh token for new access tokens.
function refreshToken(
  config: AveConfig,
  payload: { refreshToken: string }
): Promise<TokenResponse>
config
AveConfig
required
Configuration object
payload.refreshToken
string
required
The refresh token from a previous token response
Returns: TokenResponse with new tokens Example:
const newTokens = await refreshToken(
  { clientId: "app_123", redirectUri: "https://app.com/callback" },
  { refreshToken: tokens.refresh_token }
);

fetchUserInfo

Fetches user information from the OIDC UserInfo endpoint.
function fetchUserInfo(
  config: AveConfig,
  accessToken: string
): Promise<UserInfo>
config
AveConfig
required
Configuration object
accessToken
string
required
Access token from token exchange
Returns: UserInfo object
sub
string
Subject identifier (user ID)
name
string
User’s display name
preferred_username
string
User’s handle (e.g., @alice)
email
string
User’s email address
picture
string
Avatar URL
Example:
const userInfo = await fetchUserInfo(
  { clientId: "app_123", redirectUri: "https://app.com/callback" },
  tokens.access_token
);

console.log(userInfo.preferred_username); // "@alice"

Connector Flow

The connector flow allows users to delegate access to third-party resources.

buildConnectorUrl

Builds a URL for the connector authorization flow.
function buildConnectorUrl(
  config: AveConfig,
  params: {
    state?: string;
    resource: string;
    scope: string;
    mode?: "user_present" | "background";
    extraParams?: Record<string, string>;
  }
): string
params.resource
string
required
Resource identifier (e.g., github.com)
params.scope
string
required
Space-separated scopes for the target resource
params.mode
'user_present' | 'background'
default:"user_present"
Communication mode for the delegation
Example:
const url = buildConnectorUrl(
  { clientId: "app_123", redirectUri: "https://app.com/callback" },
  {
    resource: "github.com",
    scope: "repo user",
    mode: "user_present",
  }
);

window.location.href = url;

exchangeDelegatedToken

Exchanges a user’s access token for a delegated token to a third-party resource.
function exchangeDelegatedToken(
  config: AveConfig,
  payload: {
    subjectToken: string;
    requestedResource: string;
    requestedScope: string;
    actor?: Record<string, unknown>;
    clientSecret?: string;
  }
): Promise<DelegationTokenResponse>
payload.subjectToken
string
required
User’s access token
payload.requestedResource
string
required
Target resource identifier
payload.requestedScope
string
required
Requested scopes for the resource
Example:
const delegatedToken = await exchangeDelegatedToken(
  { clientId: "app_123", redirectUri: "https://app.com/callback" },
  {
    subjectToken: userAccessToken,
    requestedResource: "github.com",
    requestedScope: "repo",
  }
);

// Use delegatedToken.access_token to call GitHub API

Build docs developers (and LLMs) love