Skip to main content
If you maintain a Payload plugin that adds endpoints, collections, or fields, you can make them show up in the generated spec without depending on this package — and without your users having to wire anything up. Attach a custom.openapi Operation Object to each endpoint you add, and annotate the fields you add the same way.
custom.openapi is a plain convention on Payload’s own custom key — the same one Payload’s agent skills document. Your plugin does not import anything from @seshuk/payload-plugin-openapi, so it adds zero dependencies and zero bundle weight.

A documented plugin

src/index.ts
That is the whole integration. When a user has the OpenAPI plugin installed, your endpoint appears in their spec under its own tag, and your field carries its description and example into the generated schemas. See Custom endpoints for the operation shape and Field metadata for everything fields support.

Why plugin order does not matter

The OpenAPI plugin does not read your config when it runs. It builds the document lazily, on request, from the fully sanitized config. By the time a request hits /api/openapi.json, every plugin in the plugins array has already run — so your endpoints, collections, and fields are visible no matter where either plugin sits in the list. There is no ordering constraint to document and nothing for your users to get wrong.

The key is inert without the plugin

custom.openapi is data on Payload’s custom key, nothing more. If the OpenAPI plugin is not installed, the metadata sits there unused — no runtime cost, no behavior change, no errors. You can ship it unconditionally in your plugin and let each user decide whether they generate a spec.
Users can still drop your endpoints from their spec with filters.includeCustom: false or entity/operation filters — the metadata is an offer, not an obligation.

Beyond single endpoints and fields

Anything not tied to one endpoint or field — shared components, extra tags, a post-build transform — belongs in an extension. Extensions are an opt-in that users wire into their own openapi({ extensions: [...] }) call; there is no implicit cross-plugin channel to maintain. Export an OpenApiExtension object from your package if you want to offer one, and document that users pass it themselves.

Custom endpoints

The full Operation Object convention, path normalization, and collection sources.

Extensions

Shared components, extra tags, and document transforms.