Skip to main content

AgentSDK Methods Reference

The AgentSDK class provides all methods for OAuth 2.1 authentication, agent management, token handling, and event tracking.

OAuth 2.1 / OIDC Authentication

getAuthorizationUrl()

Generate an OAuth 2.1 authorization URL with PKCE for user authentication.
options
AuthorizationUrlOptions
required
Authorization options including redirect URI and scope
Returns: Promise<{ url: string; codeVerifier: string; state: string }>
const { url, codeVerifier, state } = await sdk.getAuthorizationUrl({
  redirectUri: "https://your-app.com/callback",
  scope: "openid profile email agent",
  state: "optional-custom-state", // Optional, auto-generated if not provided
});

// Store codeVerifier and state for later use
await storage.save({ codeVerifier, state });

// Redirect user to authorization URL
console.log("Visit:", url);
Parameters:
  • redirectUri (string, required): The callback URL where the user will be redirected after authorization
  • scope (string, optional): Space-separated list of scopes. Default: 'openid profile email agent'
  • state (string, optional): Custom state parameter for CSRF protection. Auto-generated if not provided
Security Notes:
  • PKCE parameters are automatically generated (S256 method)
  • State parameter is auto-generated if not provided for CSRF protection
  • Store codeVerifier and state securely for the callback step

exchangeCode()

Exchange an authorization code for access tokens (OAuth 2.1 with PKCE).
code
string
required
Authorization code from the OAuth callback
state
string
required
State parameter from the OAuth callback (for CSRF validation)
redirectUri
string
required
The same redirect URI used in getAuthorizationUrl()
Returns: Promise<TokenResponse>
// In your OAuth callback handler
const code = req.query.code;
const state = req.query.state;

try {
  const tokens = await sdk.exchangeCode(
    code,
    state,
    "https://your-app.com/callback"
  );

  console.log("Access token:", tokens.access_token);
  console.log("Refresh token:", tokens.refresh_token);
  console.log("ID token:", tokens.id_token);
  console.log("Expires in:", tokens.expires_in, "seconds");
} catch (error) {
  if (error.code === "state_mismatch") {
    console.error("Possible CSRF attack detected");
  }
}
Token Response:
{
  access_token: string;      // OAuth access token
  token_type: 'Bearer';      // Always 'Bearer'
  expires_in: number;        // Seconds until expiration
  refresh_token?: string;    // Refresh token (if available)
  id_token?: string;         // OpenID Connect ID token
  scope: string;             // Granted scopes
}
Errors:
  • state_mismatch: State parameter doesn’t match (possible CSRF attack)
  • pkce_missing: No code_verifier found (must call getAuthorizationUrl() first)
  • token_exchange_failed: Failed to exchange code for tokens

refreshAccessToken()

Refresh an expired access token using a refresh token.
refreshToken
string
required
Valid refresh token from previous authentication
Returns: Promise<TokenResponse>
// Get refresh token from storage
const refreshToken = await storage.getRefreshToken();

try {
  const newTokens = await sdk.refreshAccessToken(refreshToken);

  // New tokens automatically passed to onTokensRefreshed callback
  console.log("New access token:", newTokens.access_token);
} catch (error) {
  if (error.code === "refresh_failed") {
    // Refresh token invalid/expired - user needs to re-authenticate
    redirectToLogin();
  }
}
Best Practices:
  • Call this method when the access token expires
  • Check token expiration before making API requests
  • If refresh fails, redirect user to re-authenticate

Agent Registration & Management

registerAgent()

Register a new AI agent with the Auth-Agent server.
request
AgentRegistrationRequest
required
Agent registration details
Returns: Promise<AgentRegistrationResponse>
const response = await sdk.registerAgent({
  agent_id: "my-ai-agent",
  agent_secret: "secure-random-secret-key",
  model_name: "gpt-4",
  owner_name: "John Doe",
  owner_email: "john@example.com",
});

console.log(response.success); // true
console.log(response.agent_id); // 'my-ai-agent'
console.log(response.message); // 'Agent registered successfully'
Request Parameters:
  • agent_id (string): Unique identifier for your agent
  • agent_secret (string): Secure secret key (store this securely!)
  • model_name (string): AI model name (e.g., ‘gpt-4’, ‘claude-3’)
  • owner_name (string): Agent owner’s name
  • owner_email (string): Agent owner’s email
Store the agent_secret securely! You’ll need it for certain operations.

authenticateAgent()

Create an authentication session for an agent (legacy challenge-based flow).
request
AgentAuthRequest
required
Agent authentication request
Returns: Promise<AgentAuthResponse>
const authResponse = await sdk.authenticateAgent({
  agent_id: "my-ai-agent",
  agent_secret: "your-agent-secret",
  model_name: "gpt-4",
  client_id: "my-ai-agent",
  redirect_uri: "https://your-app.com/callback",
  state: "random-state",
  scope: "openid profile email agent",
  code_challenge: "challenge-value",
  code_challenge_method: "S256",
});

console.log("Session ID:", authResponse.session_id);
console.log("Challenge URL:", authResponse.challenge_url);
console.log("Expires in:", authResponse.expires_in);
For most use cases, use the OAuth flow with getAuthorizationUrl() and exchangeCode() instead of this legacy method.

getAgentProfile()

Get the authenticated agent’s profile information.
accessToken
string
required
Valid access token from your storage
Returns: Promise<AgentProfile>
const accessToken = await storage.getAccessToken();
const profile = await sdk.getAgentProfile(accessToken);

console.log("Agent ID:", profile.agent_id);
console.log("Model:", profile.model_name);
console.log("Owner:", profile.owner_name);
console.log("Email:", profile.owner_email);
console.log("Permissions:", profile.permissions);
console.log("Disabled:", profile.disabled);
console.log("Created:", profile.created_at);
Profile Response:
{
  agent_id: string;
  model_name: string;
  owner_name: string;
  owner_email: string;
  permissions: string[];
  disabled: boolean;
  created_at: string;
  updated_at: string;
}

updateAgentProfile()

Update the agent’s profile information.
accessToken
string
required
Valid access token from your storage
updates
Partial<AgentProfile>
required
Profile fields to update
Returns: Promise<AgentProfile>
const accessToken = await storage.getAccessToken();

const updatedProfile = await sdk.updateAgentProfile(accessToken, {
  owner_name: "Jane Doe",
  model_name: "gpt-4-turbo",
});

console.log("Updated profile:", updatedProfile);
Updatable Fields:
  • owner_name: Change the owner’s name
  • model_name: Update the AI model name

getUserInfo()

Get user information from the OpenID Connect userinfo endpoint.
accessToken
string
required
Valid access token from your storage
Returns: Promise<UserInfo>
const accessToken = await storage.getAccessToken();
const userInfo = await sdk.getUserInfo(accessToken);

console.log("User ID:", userInfo.sub);
console.log("Agent ID:", userInfo.agent_id);
console.log("Name:", userInfo.name);
console.log("Email:", userInfo.email);
console.log("Model:", userInfo.model_name);
console.log("Permissions:", userInfo.permissions);
UserInfo Response:
{
  sub: string;              // Subject (user ID)
  agent_id: string;         // Agent identifier
  name?: string;            // User's name
  email?: string;           // User's email
  model_name: string;       // AI model name
  permissions?: string[];   // Granted permissions
  [key: string]: any;       // Additional claims
}

Event Sending & Logging

sendEvent()

Send custom event data to the Auth-Agent server for tracking and analytics.
accessToken
string
required
Valid access token from your storage
eventData
EventData
required
Event data to send
Returns: Promise<any>
const accessToken = await storage.getAccessToken();

await sdk.sendEvent(accessToken, {
  event: "custom_event",
  selector: "#my-button",
  site: "example.com",
  evidence: "user_authenticated",
  metadata: {
    userId: "123",
    action: "click",
  },
});
Event Data Fields:
  • event (string, required): Event type/name
  • selector (string, optional): CSS selector or element identifier
  • site (string, optional): Site or domain name
  • evidence (string, optional): Evidence or proof of action
  • result (string, optional): Event result or outcome
  • Additional custom fields are allowed

sendVerifiedClick()

Send a verified click event (convenience method).
accessToken
string
required
Valid access token from your storage
selector
string
required
CSS selector or element identifier
site
string
Site or domain name
evidence
string
Evidence of verification (default: ‘oauth_authenticated’)
Returns: Promise<any>
const accessToken = await storage.getAccessToken();

await sdk.sendVerifiedClick(
  accessToken,
  "#purchase-button",
  "store.example.com",
  "oauth_authenticated"
);

sendPostRun()

Send a post-run event with execution results.
accessToken
string
required
Valid access token from your storage
selector
string
required
Action or task selector
site
string
required
Site where action was performed
result
string
required
Execution result (truncated to 2000 characters)
Returns: Promise<any>
const accessToken = await storage.getAccessToken();

await sdk.sendPostRun(
  accessToken,
  "automated_task",
  "app.example.com",
  "Task completed successfully. Processed 150 items."
);
Results are automatically truncated to 2000 characters to prevent oversized payloads.

AI Verification / Challenge Flow

requestChallenge()

Request a verification challenge from the server.
accessToken
string
required
Valid access token from your storage
Returns: Promise<ChallengeResponse>
const accessToken = await storage.getAccessToken();
const challengeData = await sdk.requestChallenge(accessToken);

console.log("Challenge:", challengeData.challenge);
console.log("Expires:", challengeData.expires);
console.log("Signature:", challengeData.sig);
console.log("Context ID:", challengeData.verify_ctx_id);
Challenge Response:
{
  ok: boolean;
  challenge?: string;
  expires?: number;
  sig?: string;
  verify_ctx_id?: string;
  message?: string;
}

confirmVerification()

Confirm verification with the challenge response.
accessToken
string
required
Valid access token from your storage
request
VerificationConfirmRequest
required
Verification confirmation data
Returns: Promise<any>
const accessToken = await storage.getAccessToken();

await sdk.confirmVerification(accessToken, {
  challenge: challengeData.challenge!,
  expires: challengeData.expires!,
  sig: challengeData.sig!,
  verify_ctx_id: challengeData.verify_ctx_id!,
});

getVerifyStatus()

Get the current verification status.
accessToken
string
required
Valid access token from your storage
Returns: Promise<any>
const accessToken = await storage.getAccessToken();
const status = await sdk.getVerifyStatus(accessToken);

console.log("Verification status:", status);

pollAndAuthenticate()

Poll for a challenge and automatically authenticate (challenge-based flow).
verifyCtxId
string
required
Verification context ID
options
object
Polling options (timeout, interval)
Returns: Promise<boolean>
const success = await sdk.pollAndAuthenticate("verify-ctx-id", {
  timeout: 30000, // 30 seconds
  interval: 2000, // Poll every 2 seconds
});

if (success) {
  console.log("Authentication successful!");
} else {
  console.log("Authentication failed or timed out");
}
Options:
  • timeout (number, default: 30000): Total timeout in milliseconds
  • interval (number, default: 2000): Polling interval in milliseconds

Token & Session Management

revokeToken()

Revoke an access token or refresh token.
token
string
required
Token to revoke (access or refresh token)
Returns: Promise<void>
// Revoke access token
const accessToken = await storage.getAccessToken();
await sdk.revokeToken(accessToken);

// Or revoke refresh token
const refreshToken = await storage.getRefreshToken();
await sdk.revokeToken(refreshToken);

// onTokensRevoked callback is automatically called
Revoking either token type will invalidate the session. The onTokensRevoked callback is automatically triggered.

introspectToken()

Introspect a token to check its validity and retrieve metadata.
token
string
required
Token to introspect
Returns: Promise<IntrospectionResponse>
const accessToken = await storage.getAccessToken();
const introspection = await sdk.introspectToken(accessToken);

console.log("Active:", introspection.active);
console.log("Scope:", introspection.scope);
console.log("Client ID:", introspection.client_id);
console.log("Expires at:", introspection.exp);
console.log("Issued at:", introspection.iat);
console.log("Subject:", introspection.sub);

if (!introspection.active) {
  console.log("Token is expired or invalid");
}
Introspection Response:
{
  active: boolean;           // Whether token is active
  scope?: string;            // Granted scopes
  client_id?: string;        // Client identifier
  username?: string;         // Username (if available)
  token_type?: string;       // Token type
  exp?: number;              // Expiration timestamp
  iat?: number;              // Issued at timestamp
  sub?: string;              // Subject (user ID)
  [key: string]: any;        // Additional claims
}

Error Handling

All methods throw AuthError objects with detailed information:
try {
  const tokens = await sdk.exchangeCode(code, state, redirectUri);
} catch (error) {
  const authError = error as AuthError;

  console.error("Error code:", authError.code);
  console.error("Description:", authError.description);
  console.error("HTTP status:", authError.statusCode);

  // Handle specific errors
  switch (authError.code) {
    case "token_expired":
      // Refresh the token
      break;
    case "state_mismatch":
      // Possible CSRF attack
      break;
    case "forbidden":
      // Insufficient permissions
      break;
    default:
      // Generic error handling
      break;
  }
}
Common Error Codes:
  • state_mismatch: State parameter mismatch (CSRF protection)
  • pkce_missing: Code verifier not found
  • token_expired: Access token expired
  • forbidden: Insufficient permissions
  • no_refresh_token: Refresh token not provided
  • refresh_failed: Token refresh failed
  • revoke_failed: Token revocation failed
  • introspection_failed: Token introspection failed

Complete Example

Here’s a complete example using multiple SDK methods:
import { AgentSDK, TokenManager } from "ai-auth";

// Initialize SDK
const tokenManager = new TokenManager();
const sdk = new AgentSDK({
  agentId: process.env.AGENT_ID!,
  agentSecret: process.env.AGENT_SECRET,
  onTokensReceived: (tokens) => tokenManager.setTokens(tokens),
  onTokensRefreshed: (tokens) => tokenManager.setTokens(tokens),
  onTokensRevoked: () => tokenManager.clear(),
});

// 1. Start OAuth flow
async function startAuth() {
  const { url, codeVerifier, state } = await sdk.getAuthorizationUrl({
    redirectUri: "http://localhost:3000/callback",
    scope: "openid profile email agent",
  });

  console.log("Visit:", url);
  return { codeVerifier, state };
}

// 2. Handle callback
async function handleCallback(code: string, state: string) {
  const tokens = await sdk.exchangeCode(
    code,
    state,
    "http://localhost:3000/callback"
  );
  return tokens;
}

// 3. Make authenticated requests
async function getUserData() {
  if (tokenManager.isExpired() && tokenManager.refreshToken) {
    await sdk.refreshAccessToken(tokenManager.refreshToken);
  }

  const accessToken = tokenManager.getAccessToken();

  // Get user info
  const userInfo = await sdk.getUserInfo(accessToken);
  console.log("User:", userInfo);

  // Get agent profile
  const profile = await sdk.getAgentProfile(accessToken);
  console.log("Profile:", profile);

  // Send event
  await sdk.sendVerifiedClick(accessToken, "#button", "example.com");
}

// 4. Logout
async function logout() {
  if (tokenManager.accessToken) {
    await sdk.revokeToken(tokenManager.accessToken);
  }
}

Next Steps