Skip to main content
All REST endpoints are mounted by the framework adapter (Hono, Express, Next.js, etc.). Paths below are relative to the mount path. The Next.js, Astro, Fastify, and NestJS adapters default to /api/theauth (set with their basePath or prefix option); with Hono and Express you pick the mount path yourself, for example app.route('/api/theauth', theAuthHono(theauth, { authenticate })).
The agent, delegation, audit and dashboard routes (/agents, /delegations, /audit, /dashboard) and POST /authorize require an authenticated caller. Pass authenticate to the adapter, or configure auth.session so the adapter accepts any signed-in user. With neither, the adapter throws when you create it, unless you set allowUnauthenticated: true (local development only). Unauthenticated requests get 401 UNAUTHORIZED. See Framework adapters. POST /authorize/token is checked by the agent’s own kv_ bearer token, and the MCP, password reset and email verification routes carry their own checks.
Successful responses wrap the payload as { "data": ... }. Errors use { "error": { "code": "...", "message": "..." } } with codes such as BAD_REQUEST (400), UNAUTHORIZED (401), NOT_FOUND (404), and INTERNAL_ERROR (500). Examples below show the payload inside data. Dates are ISO 8601 strings and IDs are UUIDs (the agt_... IDs in the examples are illustrative). The MCP OAuth endpoints are the exception: they return bare OAuth JSON.

Agent endpoints

Create agent

Creates a new agent identity. Request body
ownerId, name, type, and at least one permission are required. expiresAt is optional: when omitted, the agent expires after agents.tokenExpiry (default 24h). The owner must already exist as a row in theauth_users. Fields not listed here, such as tenantId, are ignored by the REST endpoint. Response 201 Created
The token (kv_ followed by 43 base64url characters) is returned only here and from the rotate endpoint. Every other endpoint returns "token": "". Validation failures return 400.

List agents

Returns agents, optionally filtered. With no filters it returns every agent. Query parameters Unrecognized status or type values are ignored rather than rejected. Response 200 OK - Array of agent objects.

Get agent

Returns a single agent by ID. Response 200 OK - Agent object. 404 when not found.

Update agent

Updates name, permissions, expiry, or metadata. Request body
All fields are optional. Passing permissions replaces the full permission list. Response 200 OK - Updated agent object, or 404 when not found.

Revoke agent

Permanently revokes an agent. Revoked agents cannot be reactivated. Response 204 No Content, or 404 when not found.

Rotate agent token

Issues a new token and invalidates the previous one. Use this for credential rotation. Only active agents can be rotated. Response 200 OK - Agent object with a new token value. 404 when not found; 500 with the message Cannot rotate token for <status> agent. when the agent is revoked or expired.

Authorization endpoints

Authorize a request

Checks whether an agent has permission to perform an action on a resource. The agent’s own permissions are checked first, then permissions it holds through delegation. Budget policies are not checked here. Request body
agentId, action, and resource are required. The client IP and User-Agent are stored on the audit entry. The IP comes from the adapter’s trustedProxy setting (trustedProxyCount or trustedHeader). With neither set, forwarded headers are ignored and the IP is unknown, so an ipAllowlist constraint denies. Express, Fastify and NestJS fall back to the socket address. A context object in the body is ignored. Response 200 OK when allowed
Response 403 Forbidden when denied. The body is still wrapped in data, and reason is free text, not a code:
For an unknown or inactive agent the response is also 403, with an empty auditId because no audit entry is written.

Authorize by agent token

Same check, but the agent is identified by its bearer token instead of agentId. The body takes action, resource, and optional arguments. A missing or malformed Authorization header returns 401 UNAUTHORIZED. An invalid, revoked, or expired token returns 403 with reason: "Invalid or expired agent token". This path checks only the agent’s own permissions, not delegated ones.

Delegation endpoints

Create delegation

Delegates a subset of permissions from one agent to another. The permissions must be a subset of what fromAgent holds itself. Request body
fromAgent, toAgent, at least one permission, and expiresAt are required. maxDepth defaults to 3; the new link’s depth must be less than or equal to it, otherwise the call fails with 400. An unknown parent agent returns 404. A permission set that is not a subset of the parent’s currently surfaces as 500 INTERNAL_ERROR with the explanatory message. Response 201 Created

List delegations

Returns the delegation chains where :agentId is the source agent (fromAgent). There are no query parameters, and there is no endpoint that lists every delegation. Response 200 OK - Array of delegation objects.

Revoke delegation

Revokes a delegation chain immediately, and cascades to chains the target agent has delegated onward. Response 204 No Content, or 404 when not found.

Audit endpoints

Query audit log

Returns audit log entries matching the specified filters. Query parameters Entries are returned newest first. Invalid dates, non-positive limit, and negative offset values are ignored. The actions filter is applied after limit and offset, so a page can come back shorter than limit. Authorization decisions are recorded only as allowed or denied, so result=rate_limited currently matches nothing. Response 200 OK
Denied entries also carry a free-text reason. tokensCost appears only on entries that recorded one. The IP address and user agent are stored but not returned.

Export audit log

Exports the audit log as JSON or CSV, as evidence for compliance work. The export contains at most the 10,000 most recent matching entries. Query parameters Response 200 OK - File download (audit-export.json or audit-export.csv) with Content-Disposition: attachment. The body is not wrapped in data. CSV columns are id, agentId, userId, action, resource, result, reason, durationMs, tokensCost, timestamp; request parameters appear only in the JSON export.

MCP endpoints

These endpoints implement the MCP OAuth 2.1 specification. They are served only when you pass an MCP module to the adapter (theAuthHono(theauth, { mcp, authenticate }), built with createMcpModule from @glinr/theauth/mcp); otherwise they return 404 with MCP module not configured. Responses are bare OAuth JSON (no data wrapper), errors look like { "error": "invalid_request", "error_description": "..." }, and CORS is open (Access-Control-Allow-Origin: *).

Authorization Server Metadata

Returns OAuth 2.0 Authorization Server Metadata (RFC 8414). Public endpoint, no auth required.

Protected Resource Metadata

Returns Protected Resource Metadata (RFC 9728). Public endpoint, no auth required.

Dynamic Client Registration

Registers a new OAuth client (RFC 7591). Registration is open: the endpoint itself does not authenticate callers. Request body - See RFC 7591 for the full schema. Minimum:
Response 201 Created (with Cache-Control: no-store) - Client metadata including client_id. A client_secret is included for confidential clients, which is the default (token_endpoint_auth_method of client_secret_basic); clients that register with none get no secret. Invalid metadata returns 400 with invalid_client_metadata.

Authorization request

Starts the OAuth authorization code flow. Requires PKCE (code_challenge + code_challenge_method=S256). Responds with a 302 redirect: to the module’s loginPage (with a returnTo parameter) if resolveUserId finds no signed-in user, to consentPage when one is configured, and otherwise to your redirect_uri with the authorization code. Request errors return 400 with an OAuth error code.

Token exchange

Exchanges an authorization code or refresh token for an access token. Confidential clients authenticate with client_secret_basic or client_secret_post. Request body (application/x-www-form-urlencoded) For authorization_code grant:
For refresh_token grant:
Response 200 OK (with Cache-Control: no-store)
refresh_token is present only when the granted scope includes offline_access. expires_in is the module’s accessTokenTtl. Failures return 401 for invalid_client and 400 for everything else.

Dashboard endpoints

Stats overview

Returns aggregate statistics for the admin dashboard. The audit counts cover the last 24 hours and are computed from at most the 1,000 most recent entries. Response 200 OK

Dashboard agents and audit

Aliases for GET /agents and GET /audit, with the same query parameters and responses.

Password reset and email verification

These forward the request to theauth.passwordReset and theauth.emailVerification, which exist only when you pass passwordReset or emailVerification to createTheAuth (and, for password reset, username and auth.session). When the module is not configured the route returns 404. Request and response bodies are defined by those modules, not by the agent endpoints above.

Adapters overview

Framework adapters that mount these endpoints on your server.

Agent identity

Core concepts behind the agent endpoints and token lifecycle.

Audit

Querying and exporting audit logs via the REST API.

Errors

Error codes and HTTP status reference for all endpoints.
Last modified on October 9, 2026