extensions. Each extension can add paths, components, and tags, and/or transform the finished document before it’s served or written to a file:
payload.config.ts
The extension shape
The transform hook
transform receives one object, the ExtensionContext: the full built document as doc plus the build environment. It must return the document to serve. Mutate and return the same object, or return a new one — either works, but a missing return drops the document. It can be async.
transform fails closed. If it throws or its promise rejects, the spec request fails and the CLI stops with the error. The plugin never serves a document that skipped a transform, so a transform that removes private paths can rely on it.
The ExtensionContext has these properties:
Extension or custom.openapi?
Use the tool that keeps documentation next to what it describes:
custom.openapion an endpoint — documentation for one specific endpoint your config already defines. It lives on the endpoint itself and needs no plugin option. See Custom endpoints.- An extension — documentation that isn’t tied to a single endpoint or field: shared components, extra tags, paths served outside Payload (webhooks handled elsewhere), or a post-build transform over the whole document.
If you’re a plugin author, prefer
custom.openapi on the endpoints you add — it’s picked up automatically without depending on this package. Extensions are an opt-in your users wire into their own openapi({ extensions: [...] }) call. See For plugin authors.