← All docs

OpenAPI

The HTTP API is described in one OpenAPI 3.1 document. Point a client generator, an API gateway or a test tool at it.

On a deployment /openapi.json, e.g. https://api.antibot.dev/openapi.json
In the repository web/public/openapi.json

What it covers

Every route handler under web/app/api, one operation per method:

Tag
Server API Events, visitors and related visitors, with a secret key
Assess /assess, its outcomes, trap reports, the edge's refusal counts, receipt usage and revocations
Agent and mobile SDKs Identification, integrity keys, pulses, challenges, waiting rooms, the credential lookup, App Attest — and their CORS preflights
Management API Everything under /api/management/v1
Operations /api/health, /api/ready, /api/metrics

And what the service sends you: every webhook delivery, under the document's webhooks — the identification and each type the others carry (alert.started, session.escalated, script.changed, …), with the body's schema and the three headers every delivery has. Generate your receiver's types from it.

The agent and the SDKs call their endpoints for you. They are described so a proxy, a firewall rule or a custom client can be written against them, not because you need to call them.

Each operation says how it authenticates:

  • Secret key — Authorization: Bearer sk_… or Auth-API-Key. The role on the requirement is the use the key needs: identification for the Server API, assess for the assess family. A key that lists no uses may do both.
  • Management key — Authorization: Bearer mk_…. The role is the scope the operation needs. Discovery (GET /api/management/v1) needs none.
  • Public key — in the request body, as apiKey. OpenAPI cannot describe a credential in a body, so these operations list no security scheme and their body requires apiKey.
  • Metrics token — ANTIBOT_METRICS_TOKEN, as a bearer.

Errors are the shared Error shape, { "error": { "code", "message" } }. Each error response lists the codes it can carry. See Errors.

What it leaves out

  • GET /api/auth/sso/callback. It is where an identity provider sends the browser back after single sign-on — a step in signing in to the dashboard, not an API.
  • The agent script itself (/agent/v1/antibot.js), which is not under /api.
  • The dashboard's pages and form actions.

One rule a request body follows is not in its schema: /assess/outcome needs at least one of account, card, phone, code, content and hold. JSON Schema generated from the code cannot carry it, so the operation's description says it instead.

How it is made

It is generated from the code, not written by hand:

cd web
pnpm openapi
  • Paths and methods come from the route handlers: every route.ts under web/app/api, read for the methods it exports.
  • Request bodies the API validates with zod come from those schemas, the ones the routes import, through z.toJSONSchema. They live in web/lib/api/schemas/.
  • Everything else — summaries, the Management API's bodies, query parameters, responses and errors — is one table beside the generator, web/scripts/openapi.operations.ts. Its enums are the code's own constants, so a new scope or rule action reaches the document by itself.

Changing a route, a request schema or that table means running pnpm openapi and committing the new openapi.json with the change.

CI keeps it honest

pnpm test:openapi fails when:

  • openapi.json is not what pnpm openapi writes now — it went stale;
  • a route handler has no operation, or an operation no route handler, other than the exclusions listed in the table;
  • an operationId repeats, a $ref does not resolve, or an operation has no responses;
  • a request body backed by zod is not the schema its route imports and parses with, or a route parses with a schema the document does not know;
  • the documented success status is not one the handler returns;
  • the code sends a webhook the document does not have, or the document has one the code does not send; a body the code builds, or one the webhooks guide shows, does not fit its schema.

It also sends real requests through the handlers in-process: bodies the document accepts must be accepted and bodies it refuses refused, and every answer must fit the documented response.