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).
Authorization code from the OAuth callback
State parameter from the OAuth callback (for CSRF validation)
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.
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).
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.
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.
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.
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.
Valid access token from your storage
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).
Valid access token from your storage
CSS selector or element identifier
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.
Valid access token from your storage
Site where action was performed
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.
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.
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.
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).
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 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.
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