bin script under the openapi:generate key. It builds the same document the runtime endpoint serves and writes it to disk — no HTTP request, no running server needed.
- Commit the spec to the repo, so API changes show up in code review.
- Diff schemas in CI and fail the build on unintended API changes.
- Feed a client-code generator (openapi-typescript, Orval, and friends).
- Host a static spec with no runtime endpoint at all — see Serve a pre-generated spec.
The script reads the plugin’s resolved options from your Payload config, so
openapi() must be in your plugins
array — even with serve: false.Flags
Flags accept both
--flag value and --flag=value.
--lang
Picks the locale used for translated titles and descriptions. Defaults to your project’s i18n.fallbackLanguage.
all to write one file per language in your i18n.supportedLanguages, named openapi.<lang>.json:
When
--lang all writes multiple files, the openapi.<lang>.json naming applies and --out is ignored.--out
Output path for a single-language run:
--server
Base URL written to the spec’s servers array:
servers field is filled in per request from the incoming Host header, so there is nothing to configure. A file on disk has no request to read the host from — so you set the base URL yourself with --server, or leave it out and ship a spec with empty servers. metadata carries the API’s title, version, and description only, never its URL; keeping the base URL out of the spec is what lets the same document work behind any host, proxy, or environment.
The generated spec reflects public-access marking only — it never runs per-user access checks. This matches the HTTP
endpoint exactly. See Security marking.
CI example
Commit the spec, regenerate it in CI, and fail the job when the committed file drifts from the config:.github/workflows/openapi.yml
See also
- Serve a pre-generated spec —
serve: false, static hosting, and pointing the docs UI at a file - Internationalization — locales,
?lang=, and multi-language generation - Programmatic use — build the document in your own code instead