> ## Documentation Index
> Fetch the complete documentation index at: https://aiauth.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# AgentSDK Methods

> Complete reference for all AgentSDK methods and their usage

# 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.

<ParamField path="options" type="AuthorizationUrlOptions" required>
  Authorization options including redirect URI and scope
</ParamField>

**Returns:** `Promise<{ url: string; codeVerifier: string; state: string }>`

```typescript theme={null}
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).

<ParamField path="code" type="string" required>
  Authorization code from the OAuth callback
</ParamField>

<ParamField path="state" type="string" required>
  State parameter from the OAuth callback (for CSRF validation)
</ParamField>

<ParamField path="redirectUri" type="string" required>
  The same redirect URI used in getAuthorizationUrl()
</ParamField>

**Returns:** `Promise<TokenResponse>`

```typescript theme={null}
// 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:**

```typescript theme={null}
{
  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.

<ParamField path="refreshToken" type="string" required>
  Valid refresh token from previous authentication
</ParamField>

**Returns:** `Promise<TokenResponse>`

```typescript theme={null}
// 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.

<ParamField path="request" type="AgentRegistrationRequest" required>
  Agent registration details
</ParamField>

**Returns:** `Promise<AgentRegistrationResponse>`

```typescript theme={null}
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

<Warning>
  Store the `agent_secret` securely! You'll need it for certain operations.
</Warning>

***

### authenticateAgent()

Create an authentication session for an agent (legacy challenge-based flow).

<ParamField path="request" type="AgentAuthRequest" required>
  Agent authentication request
</ParamField>

**Returns:** `Promise<AgentAuthResponse>`

```typescript theme={null}
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);
```

<Note>
  For most use cases, use the OAuth flow with `getAuthorizationUrl()` and
  `exchangeCode()` instead of this legacy method.
</Note>

***

### getAgentProfile()

Get the authenticated agent's profile information.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

**Returns:** `Promise<AgentProfile>`

```typescript theme={null}
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:**

```typescript theme={null}
{
  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.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

<ParamField path="updates" type="Partial<AgentProfile>" required>
  Profile fields to update
</ParamField>

**Returns:** `Promise<AgentProfile>`

```typescript theme={null}
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.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

**Returns:** `Promise<UserInfo>`

```typescript theme={null}
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:**

```typescript theme={null}
{
  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.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

<ParamField path="eventData" type="EventData" required>
  Event data to send
</ParamField>

**Returns:** `Promise<any>`

```typescript theme={null}
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).

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

<ParamField path="selector" type="string" required>
  CSS selector or element identifier
</ParamField>

<ParamField path="site" type="string" optional>
  Site or domain name
</ParamField>

<ParamField path="evidence" type="string" optional>
  Evidence of verification (default: 'oauth\_authenticated')
</ParamField>

**Returns:** `Promise<any>`

```typescript theme={null}
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.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

<ParamField path="selector" type="string" required>
  Action or task selector
</ParamField>

<ParamField path="site" type="string" required>
  Site where action was performed
</ParamField>

<ParamField path="result" type="string" required>
  Execution result (truncated to 2000 characters)
</ParamField>

**Returns:** `Promise<any>`

```typescript theme={null}
const accessToken = await storage.getAccessToken();

await sdk.sendPostRun(
  accessToken,
  "automated_task",
  "app.example.com",
  "Task completed successfully. Processed 150 items."
);
```

<Note>
  Results are automatically truncated to 2000 characters to prevent oversized
  payloads.
</Note>

***

## AI Verification / Challenge Flow

### requestChallenge()

Request a verification challenge from the server.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

**Returns:** `Promise<ChallengeResponse>`

```typescript theme={null}
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:**

```typescript theme={null}
{
  ok: boolean;
  challenge?: string;
  expires?: number;
  sig?: string;
  verify_ctx_id?: string;
  message?: string;
}
```

***

### confirmVerification()

Confirm verification with the challenge response.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

<ParamField path="request" type="VerificationConfirmRequest" required>
  Verification confirmation data
</ParamField>

**Returns:** `Promise<any>`

```typescript theme={null}
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.

<ParamField path="accessToken" type="string" required>
  Valid access token from your storage
</ParamField>

**Returns:** `Promise<any>`

```typescript theme={null}
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).

<ParamField path="verifyCtxId" type="string" required>
  Verification context ID
</ParamField>

<ParamField path="options" type="object" optional>
  Polling options (timeout, interval)
</ParamField>

**Returns:** `Promise<boolean>`

```typescript theme={null}
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.

<ParamField path="token" type="string" required>
  Token to revoke (access or refresh token)
</ParamField>

**Returns:** `Promise<void>`

```typescript theme={null}
// 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
```

<Info>
  Revoking either token type will invalidate the session. The `onTokensRevoked`
  callback is automatically triggered.
</Info>

***

### introspectToken()

Introspect a token to check its validity and retrieve metadata.

<ParamField path="token" type="string" required>
  Token to introspect
</ParamField>

**Returns:** `Promise<IntrospectionResponse>`

```typescript theme={null}
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:**

```typescript theme={null}
{
  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:

```typescript theme={null}
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:

```typescript theme={null}
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

<CardGroup cols={2}>
  <Card title="Token Manager" icon="key" href="/sdk/javascript/token-manager">
    Learn about the TokenManager class
  </Card>

  <Card title="Utilities" icon="wrench" href="/sdk/javascript/utilities">
    Utility functions for PKCE, JWT, and more
  </Card>

  <Card title="Types" icon="brackets-curly" href="/sdk/javascript/types">
    Complete TypeScript type definitions
  </Card>

  <Card title="Examples" icon="code" href="/examples/overview">
    See practical examples
  </Card>
</CardGroup>
