/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.{ "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
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
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
Unrecognized
status or type values are ignored rather than rejected.
Response 200 OK - Array of agent objects.
Get agent
200 OK - Agent object. 404 when not found.
Update agent
permissions replaces the full permission list. Response 200 OK - Updated agent object, or 404 when not found.
Revoke agent
204 No Content, or 404 when not found.
Rotate agent token
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
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
403 Forbidden when denied. The body is still wrapped in data, and reason is free text, not a code:
403, with an empty auditId because no audit entry is written.
Authorize by agent token
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
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
: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
204 No Content, or 404 when not found.
Audit endpoints
Query audit log
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
reason. tokensCost appears only on entries that recorded one. The IP address and user agent are stored but not returned.
Export audit log
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
Protected Resource Metadata
Dynamic Client Registration
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
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
client_secret_basic or client_secret_post.
Request body (application/x-www-form-urlencoded)
For authorization_code grant:
refresh_token grant:
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
200 OK
Dashboard agents and audit
GET /agents and GET /audit, with the same query parameters and responses.
Password reset and email verification
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.
Related
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.