Sync Config
Configure write, publish, archive, draft, and hard-delete behavior.
Sync Config
Sync behavior is server-owned.
The manifest can request mode: "sync" or publish: true, but the plugin applies writes or publishing only when server config allows it.
Write Gate
1sync: {2 allowWrites: true,3}
Without allowWrites: true, mode: "sync" is rejected.
Auth Is Separate
sync controls whether accepted requests may write or publish. auth controls whether a request is accepted.
Supported auth modes:
ed25519for signed requests with public keys stored in Access records. A key can sync every docs set unless its Access record listsAllowed docs sets; unscoped keys log a warning on use.github-oidcfor GitHub Actions workflows trusted through Access owner or repository records, with per-docs-set branch, repository, tag-ref, workflow ref, and pull-request rules.
See GitHub OIDC and signed push.
Publish Gate
1target: {2 type: 'docsCollection',3 enableDrafts: true,4},5sync: {6 allowPublish: true,7}
Publishing requires both a draft-enabled dedicated docs collection and allowPublish: true.
When --publish is not requested, synced generated docs are written as drafts.
Cache Revalidation
After a successful sync, the endpoint attempts to revalidate generated docs
paths, synced asset routes, and common docs sitemap tags through next/cache.
This keeps production App Router pages from serving stale generated docs or raw
AI assets after push --publish.
Disable path revalidation or provide app-specific tags when needed.
1sync: {2 allowWrites: true,3 allowPublish: true,4 revalidate: {5 paths: true,6 tags: ['payload-markdown-docs', 'sitemap', 'sitemap:docs'],7 },8}
Use revalidate: false only when the app handles docs cache invalidation
elsewhere.
Assets
Manifest assets (skills, stored llms.txt files, static text files) are
served from the site origin, so the server accepts only the content types
pmdocs emits: text/markdown, text/plain, application/json, and
application/yaml, optionally with charset=utf-8.
Other types (for example text/html or image/svg+xml) reject the sync with
invalid_manifest. Every asset, llms, and skill response is sent with
X-Content-Type-Options: nosniff and
Content-Security-Policy: default-src 'none'; sandbox; JSON, YAML, and CSV are
sent as attachments. Rows stored before this policy with another type are
served as text/plain.
Assets have no draft state. When the docs collection has drafts, a sync
without --publish reports asset creates and updates but does not apply them
(warning assets_deferred_until_publish); the next --publish sync applies
them. Asset removals always apply. Set sync.applyAssetsOnDraftSync: true to
apply asset changes in non-publish syncs as earlier versions did.
Dry-Run Audit Records
Every dry run records a sync run by default. Set sync.auditDryRuns: false to
record applied syncs only. Dry runs still consume their nonce.
Delete Behavior
deleteBehavior can be:
archiveignoredraftdelete
Hard delete requires allowHardDelete: true.
Removals take effect on the public site in every sync, including syncs without
--publish: archive and draft write the published record so a doc removed
from Git stops being served immediately. draft additionally unpublishes it.
An archived doc releases its route. Its stored route becomes
archived:<id>:<route>, so another file can take over the URL (for example
guide.md becoming guide/index.md, or two docs swapping slug: values).
When the file comes back, the archived record is reactivated on its real route.
A sync is applied in a single database transaction when the Payload database
adapter supports transactions (Postgres, SQLite, MongoDB replica sets). If any
write fails, no docs, assets, or docs-set changes from that sync are kept, and
the sync run is recorded as failed.
A sync is rejected with 409 route_collision before any write when a route it
needs is still held by a doc it cannot release: a doc owned by another docs
set, or a published doc of the same set whose published version this sync does
not update (for example a non---publish sync that moves guide.md away from
/guide while a new file claims /guide). Run the change as a --publish
sync instead.
Recommended default
Use deleteBehavior: 'archive' and allowHardDelete: false. Archive keeps records available for review and avoids accidental destructive syncs.