Console and admin API

Every endpoint of the customer console API (/v1/account, /v1/console) and the private operator admin API (/v1/admin), with their OpenAPI contracts.

Everything the console at /app does goes through a JSON API you can call yourself. The contracts are OpenAPI 3.1 documents, checked by the test suite against the registered routes and real responses:

Errors are {"error": "<code>", "message": "…"}; the codes are on Error codes.

Authentication

  • Console. POST /v1/account/login sets the ag_account session cookie (HttpOnly, SameSite=Lax, Secure over TLS; 12 hours, or 2 hours without use). GET /v1/account/session returns the signed-in user, the customer and a CSRF token; send it as X-CSRF-Token on every request that changes something. Requests from other sites are refused (cross_origin).
  • Two-factor authentication. With 2FA on, login answers {"mfaRequired": true} and a 5-minute pre-session; POST /v1/account/login/mfa with the code from the authenticator app (or a recovery code) completes the sign-in. An account can require 2FA of all its members; members without it get 403 mfa_setup_required on the console until they turn it on.
  • API tokens. For scripts and CI, create a token under API tokens and send Authorization: Bearer agt_… to /v1/console/* (no CSRF token). A token is limited to its scopes (sites:read, sites:write, analytics:read, members:read) and never works on /v1/account or /v1/admin.
  • Admin. The admin API is private: the public host answers 404 for /v1/admin/. Operators reach it on a private network or through an SSH tunnel, sign in with the operator key (POST /v1/admin/login, cookie ag_admin) and send X-CSRF-Token on changes.
  • Operator and customer sessions never unlock each other's APIs. A customer sees only its own sites; another customer's site key answers 404.
  • Accounts and roles. A user can belong to several accounts; the session works in one at a time (the active account, changed with POST /v1/account/switch). In each account the user has a role: owner, admin, member or readonly. Every console route needs a permission of that role: sites:read, sites:write, analytics:read, members:read, members:write, tokens:write, account:write, account:delete or audit:read. A missing one answers 403 forbidden and names it. A suspended account answers 403 account_suspended (its sites keep protecting), a suspended user 403 user_suspended.
RolePermissions
ownerall, including account:delete (delete the account, transfer ownership)
admineverything else: sites, analytics, members, tokens, account settings, audit log
membersites:read, sites:write, analytics:read, members:read
readonlysites:read, analytics:read, members:read

Account

MethodPathSummary
POST/v1/account/request-accessAsk for an account; the same answer whether or not the address is known
POST/v1/account/loginSign in; sets ag_account
POST/v1/account/logoutEnd the session
GET/v1/account/sessionThe signed-in user, their accounts, the active account with role, limits and permissions, and the CSRF token
POST/v1/account/switchMake another of the user's accounts the active one
POST/v1/account/accountsCreate another account, owned by the caller (at most 3 owned)
GET/v1/account/invite/{token}Who an invite link is for, without using it
POST/v1/account/invite/acceptSet the first password with an invite link (single use, 7 days) and sign in
POST/v1/account/password/forgotEmail a reset link (1 hour) if an account uses the address; always 202
POST/v1/account/password/resetSet a new password with a reset link; ends the user's other sessions and signs in
POST/v1/account/login/mfaComplete a sign-in with a 2FA code or a recovery code
GET/v1/account/mfaYour 2FA state and whether the account requires it
POST/v1/account/mfa/setupStart 2FA setup: a TOTP secret and an otpauth:// URL for a QR code
POST/v1/account/mfa/enableTurn 2FA on with a code; returns 10 single-use recovery codes once
POST/v1/account/mfa/disableTurn 2FA off (password and a code or recovery code)
POST/v1/account/passwordChange your password; ends your other sessions
GET/v1/account/sessionsYour signed-in sessions (browser, pseudonymous address)
DELETE/v1/account/sessions/{id}End one session
POST/v1/account/sessions/revoke-othersEnd every session but this one

Console

MethodPathSummary
GET/v1/console/accountThe active account: name, status, limits and usage
PATCH/v1/console/accountRename the account (account:write)
DELETE/v1/console/accountDelete the account (owner; type its name to confirm; no site may enforce); data is purged after 30 days
POST/v1/console/account/transfer-ownershipMake another member the owner; the caller becomes an admin
GET/v1/console/membersThe account's members with role, status and last sign-in
POST/v1/console/membersInvite someone by email with a role (members:write)
PATCH/v1/console/members/{userId}Change a member's role (only owners change owners; never the last owner)
DELETE/v1/console/members/{userId}Remove a member (never the last owner)
POST/v1/console/members/{userId}/resend-inviteEmail a fresh invite link to a member who has not set a password
GET/v1/console/auditThe account's audit log: members, roles, sites, credentials, limits, status, sign-ins
GET/v1/console/sitesThe customer's sites
POST/v1/console/sitesAdd a site (monitor mode, widget mode invisible unless given); siteKey, customerId and customerName are refused; default action submit; at most 10 allowed origins (400 origin_limit)
GET/v1/console/sites/{siteKey}A site with credentials, changes and rules summary
PATCH/v1/console/sites/{siteKey}Change name, origins (at most 10), actions, routes, mode or widget mode
GET/v1/console/sites/{siteKey}/changesThe site's audit trail
POST/v1/console/sites/{siteKey}/credentialsA backend credential, shown once (at most 3 live per site)
POST/v1/console/sites/{siteKey}/credentials/{credId}/rotateReplace a credential; the old one works for overlapSeconds
POST/v1/console/sites/{siteKey}/credentials/{credId}/revokeRevoke a credential now
GET/v1/console/sites/{siteKey}/rulesThe site's rule set and overrides
PUT/v1/console/sites/{siteKey}/rulesReplace the site's rules or overrides
POST/v1/console/sites/{siteKey}/rules/validateCheck rules without saving
GET/v1/console/sites/{siteKey}/installwaiting until AgentGate sees a decision for the site, then live
GET/v1/console/sites/{siteKey}/healthIntegration health over the last 24 hours: is the server verifying tokens, is traffic arriving, are pages on unlisted origins, are siteverify calls failing
GET/v1/console/sites/{siteKey}/analyticsChallenge outcomes, solve rate, solve types, token validation and top lists (default: last 24 hours)
GET/v1/console/sites/{siteKey}/agent-promptA setup prompt for a coding agent (text/markdown): site key, endpoint contract, AGENTGATE_SECRET from the environment (never the secret), checklist
GET/v1/console/managed-groupsThe managed rule-group catalog (read-only, the same for every account): what each group reference in a rule set expands to
GET/v1/console/metricsDaily counts, challenges, latency (errors.eventWriteFailures is always 0 here: it is process-wide)
GET/v1/console/decisionsDecisions, newest first (same filters as the admin API)
GET/v1/console/decisions/{decisionId}One decision with its labels and rule (no trace link)
GET/v1/console/visitorsPseudonymous request sources
GET/v1/console/visitors/{visitorId}One source and its recent decisions
GET/v1/console/tokensThe account's API tokens (never the secrets)
POST/v1/console/tokensCreate an API token with scopes and an optional expiry; the secret is shown once
DELETE/v1/console/tokens/{id}Revoke an API token now

Limits are per account: by default 5 sites, 3 live backend secrets per site, 10 members and 25 live API tokens (GET /v1/console/account shows them and the usage). New sites start in monitor mode with one browser-checked action, submit.

Admin (private)

MethodPathSummary
POST/v1/admin/loginExchange the operator credential (ADMIN_KEY) for a session cookie
POST/v1/admin/logoutEnd the session
GET/v1/admin/sessionThe current operator and the CSRF token for mutations
GET/v1/admin/sitesEvery site with today's traffic and integration health
POST/v1/admin/sitesCreate a site (monitor mode unless mode is given)
GET/v1/admin/sites/{siteKey}Site detail with credentials, recent changes and rules summary
PATCH/v1/admin/sites/{siteKey}Change name, origins, actions, routes or mode
GET/v1/admin/sites/{siteKey}/changesThe site's configuration audit trail, newest first
POST/v1/admin/sites/{siteKey}/credentialsCreate a backend credential; the secret is returned once
POST/v1/admin/sites/{siteKey}/credentials/{credId}/rotateCreate a replacement; the old credential works for overlapSeconds (default 86400, at most 7 days)
POST/v1/admin/sites/{siteKey}/credentials/{credId}/revokeRevoke immediately
GET/v1/admin/sites/{siteKey}/rulesThe site's base rule set, per-rule overrides and effective rule set
PUT/v1/admin/sites/{siteKey}/rulesReplace the site's rule configuration
POST/v1/admin/sites/{siteKey}/rules/validateValidate without storing; errors carry line and column for ruleSetText
GET/v1/admin/managed-groupsEvery registered managed rule group version and its member rules
GET/v1/admin/metricsOverview counts and a bucketed series for a time range
GET/v1/admin/visitorsPseudonymous request sources, most recently seen first
GET/v1/admin/visitors/{visitorId}One source's summary and its 50 newest decisions (default range: 31 days)
GET/v1/admin/decisionsDecisions, newest first, with filters
GET/v1/admin/decisions/{decisionId}Why: labels grouped by source, matched rule, scores, versions, would-decision, trace
PUT/v1/admin/decisions/{decisionId}/labelLabel a decision human, bot, agent or unsure for the model loop
GET/v1/admin/labelsExport operator labels in update order (oldest first) for training
POST/v1/admin/labelsLabel a decision (by decision or request ID) with a source, for probes and scripts
GET/v1/admin/sites/{site}/feature-captureWhether the site stores model feature vectors (never content) and for how long
PUT/v1/admin/sites/{site}/feature-captureOpt in or out of feature capture; opting out deletes the site's vectors
GET/v1/admin/modelsActive, candidate and previous model per kind (agent, bot, content)
GET/v1/admin/models/{kind}/{role}A model file (weights and metadata)
PUT/v1/admin/models/{kind}/{role}Load a candidate model; it scores traffic in shadow without affecting decisions
DELETE/v1/admin/models/{kind}/{role}Stop shadow scoring
GET/v1/admin/models/{kind}/compareCandidate vs active on recent traffic: agreement, would-change counts, per-label rates
POST/v1/admin/models/{kind}/promoteMake the candidate active (recorded in config_changes; survives restarts)
POST/v1/admin/models/{kind}/rollbackRestore the previous active model
GET/v1/admin/sites/{siteKey}/installWhether AgentGate has seen traffic for the site (the add-site wizard's install check)
GET/v1/admin/sites/{siteKey}/healthIntegration health: typed checks over the last 24 hours
GET/v1/admin/sites/{siteKey}/analyticsChallenge outcomes, solve types, token validation and top lists for a range
GET/v1/admin/sites/{siteKey}/agent-promptA self-contained setup prompt for a coding agent (Markdown)
GET/v1/admin/access-requestsAccess requests from /signup, newest first
POST/v1/admin/access-requests/{id}/approveCreate the customer (named by company, else name), the user and a 7-day invite link; email the link
POST/v1/admin/access-requests/{id}/declineDecline a pending request (no email is sent)
GET/v1/admin/customersAccounts with owner, member and site counts, status, limits and last activity (status, q filters)
GET/v1/admin/customers/{id}One account: members, sites with health, API tokens, limits, usage, recent audit events
PATCH/v1/admin/customers/{id}Rename an account or change its limits
DELETE/v1/admin/customers/{id}Delete an account (same rules as the owner's)
POST/v1/admin/customers/{id}/suspendSuspend: console and API closed, sites keep protecting
POST/v1/admin/customers/{id}/reactivateLift a suspension, or restore a deleted account within 30 days
POST/v1/admin/customers/{id}/sitesCreate a site in the account
POST/v1/admin/customers/{id}/membersAdd someone to the account with a role; returns an invite link for a new user
PATCH/v1/admin/customers/{id}/members/{userId}Change a member's role
DELETE/v1/admin/customers/{id}/members/{userId}Remove a member
POST/v1/admin/customers/{id}/members/{userId}/resend-inviteA fresh invite link for a member without a password
GET/v1/admin/customers/{id}/auditThe account's audit log
DELETE/v1/admin/customers/{id}/tokens/{tokenId}Revoke one of the account's API tokens
POST/v1/admin/sites/{siteKey}/moveMove a site to another account
POST/v1/admin/users/{userId}/suspendSuspend a user everywhere; their sessions end
POST/v1/admin/users/{userId}/reactivateLift a user's suspension
POST/v1/admin/users/{userId}/reset-linkA one-hour password reset link, also emailed
POST/v1/admin/users/{userId}/mfa/resetTurn a user's 2FA off (lost authenticator)
GET/v1/admin/accountsCustomer users with their accounts and roles
POST/v1/admin/accountsInvite a user directly (a new customer, or customerId to add a teammate)
GET/v1/admin/outboxMessages the service sent or will send, newest first; bodies hold one-time links
GET/v1/admin/docs-feedback"Was this helpful?" answers on the public docs, counted per page (most answered first)

Public endpoints

These need no session; they are documented on their own pages.

MethodPathPage
GET/sdk/v1/agentgate.js, /sdk/v1/worker.jsWidget configuration
POST/v1/browser/challenge, /v1/browser/verify; GET /v1/browser/instrumentHow the check works
POST/v1/siteverifyValidate tokens
GET/v1/gateway/checkGateway overview
POST/agent/submitSign requests
GET/.well-known/agentgate-tools.json, /v1/agent-tools/{siteKey}Declared tools
GET/v1/handoff/{id}Human handoff
GET/.well-known/agentgate-keys.json; POST /v1/receipts/verifySigned receipts
POST/v1/docs/feedbackthe "Was this helpful?" buttons on these pages
GET/healthz, /readyzliveness and readiness: /readyz answers 200 while AgentGate can decide (ready, or degraded when only optional data such as threat intelligence is missing) and 503 with Retry-After: 5 when it cannot

View as Markdown