Skip to main content
You configure the plugin with a single openapi(...) call in your Payload config. The docs UI is separate — add scalar() or swaggerUi() alongside it (see Docs UI):
payload.config.ts

Plugin options

Paths are relative to the API route

The plugin registers its endpoints as Payload endpoints, so everything mounts under your Payload API route (routes.api, /api by default). The path you pass to openapi() — and the path you pass to scalar()/swaggerUi() — are relative to that route. The defaults resolve to:
  • GET /api/openapi.json — the generated OpenAPI document
  • GET /api/docs — the interactive API reference

The lazy build model

openapi() does not build anything at config time. It stashes the resolved options, registers the CLI generator, and mounts the endpoints. The document itself is built per request (or per CLI run) from the fully sanitized Payload config. That means plugin order does not matter: collections, globals, fields, and endpoints added by any other plugin are visible in the spec, whether that plugin runs before or after openapi() in your plugins array.
info.title and info.version are required. The plugin throws on boot if either is missing.

Limiting who can read the spec

The spec and the docs page are open to everyone by default, because most API docs are public. The spec lists every documented collection, field and endpoint. If your API is private, add access to openapi() and to the docs UI. It gets the request and returns true to serve it. Any other result answers 403. This recipe shows the docs only to users of your admin collection:
payload.config.ts
The docs page loads the spec from the same site, so the browser sends the admin login cookie with it. To hide the docs only in production, use access: () => process.env.NODE_ENV !== 'production'.

Turning the plugin off

With enabled: false the plugin adds no endpoints, no CLI command, no translations and sends no telemetry. It never adds collections or fields, so your database schema is the same either way. It still checks your options, so a removed option still throws.

Where to go next

  • Info and servers — title, version, description, and where the base URL comes from
  • OpenAPI version — 3.2 by default, downconversion to 3.1/3.0
  • Filters — choose entities and drop operations
  • Security marking — public vs. secured operations
  • Interactive auth — Authorize dialog in the docs UI
  • Caching — when the document is rebuilt
  • Extensions — add paths, components, tags, or transform the document
  • Docs UI — Scalar and Swagger UI options
  • Telemetry — what the anonymous usage report contains and how to turn it off
For copy-ready configurations, see Examples.