# Reference

URL: /docs/plugins/payload-revalidate/reference

Every revalidatePlugin option, default, and export in one place — plus the guarantees the finders and hooks make.

The full surface: plugin options, the import-path map for every export, and the behavioural notes worth knowing. For finder signatures see [Writing getters](/docs/plugins/payload-revalidate/getters); for the tag vocabulary see [The atomic model](/docs/plugins/payload-revalidate/atomic-model).

## Plugin options

Every option is optional. Zero-config (`revalidatePlugin()`) gives every collection and global its hooks, and doc tags flow automatically. Declared `lists` are the one thing worth configuring.

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | Master switch. Set `false` to register no hooks or endpoints at all. |
| `collections` | `Record<string, CollectionRevalidateConfig \| false>` | `{}` | Tracking config for YOUR collections, keyed by slug — this plugin registers none of its own, so there's no `slug`/`overrides` here, just the per-collection settings below. Set a slug to `false` to opt the collection out entirely. Omit it and every collection still gets doc tags — just one bare list tag per collection instead of scoped ones. |
| `collections.idField` | `string \| false` | `'slug' when a slug field exists, else false` | The field for the alias doc tag (`posts:my-slug`). Defaults to `'slug'` when the collection has a slug field, otherwise the collection is id-keyed only. |
| `collections.lists` | `Record<string, string[] \| { fields: string[] }>` |  | Declares list scopes — each scope gives a list surface its own tag and names the fields that reorder or filter it (`name: [fields]`, or the longer `name: { fields: [...] }`). |
| `collections.extraTags` | `string[]` |  | Fixed tags added to every doc in the collection. |
| `globals` | `Partial<Record<string, false>>` | `{}` | Opt one of YOUR globals out of revalidation by setting its slug to `false`. Every global is tracked by default. |
| `options` | `RevalidateOptions` |  | The plugin's own knobs. |
| `options.prefix` | `string` | `''` | Namespaces every emitted tag (e.g. `prefix: "app:"` → `app:posts:my-slug`). Use it to isolate tags when two Payload apps share a cache. |
| `options.rules` | `Array<{ on: string; bust: string[]; whenFields?: string[] }>` | `[]` | Manual busts for data the field-walk can't see (e.g. content denormalized by an app-level build step). A rule fires when one of its `whenFields` changed, or on any membership event; deletes fire it unconditionally. |
| `options.observe` | `boolean` | `dev only` | Force the dependency-map observation and dev warnings on in production. By default they run in development only. It also governs the `/api/revalidate-map` endpoints: they serve nothing but observations, so when `observe` is off they are not registered at all. With `observe: true` in production they additionally require an authenticated Payload user. |

> **`idField` is per-collection, not top-level.** Set it under `collections: { posts: { idField: 'uid' } }` (or on the collection's `custom.revalidate`), not as a `revalidatePlugin()` option. Likewise **`walk.maxTags`** (default `64` — caps how many tags the bake-in walk adds to one entry; Next.js allows 128) is a **per-read** option you pass to a finder / `cacheDoc`, not a plugin option. Capped reads are flagged in the dev map.

> Finder defaults, baked in so you never repeat them: `depth: 0` (references stay
> ids), errors resolve to `null`, and id-list reads
> (`findIds`) are forced to `select: {}`. Access is **not** one of them — the finders
> leave `overrideAccess` to Payload's own default (`true`), so a collection with
> restricted `read` access reads the same through a finder as through `payload.find`.
> Pass `overrideAccess: false` to scope a read to what an anonymous visitor may see.
> Override any default per call — except
> `user` / `req`, which the finders refuse (see [Writing
> getters](/docs/plugins/payload-revalidate/getters)).

## Environment variables

None. The plugin reads no environment variables — everything is configured through [plugin options](#plugin-options).

## Endpoints

Two dependency-map routes, governed entirely by [`observe`](#plugin-options) — dev-only by default. They serve nothing but observations, so with `observe: false` (the production posture) they are not registered at all. With `observe: true` forced on in production they additionally require an authenticated Payload user.

| Route                      | Purpose                                              |
| -------------------------- | ---------------------------------------------------- |
| `GET /api/revalidate-map`  | The full dependency map as JSON.                     |
| `POST /api/revalidate-map` | Bust one tag by hand — body `{ "tag": "posts:42" }`. |

These power the `/dev/revalidate` map — see [Troubleshooting](/docs/plugins/payload-revalidate/troubleshooting#the-devrevalidate-map).

## CLI commands

The plugin registers one bin, so it runs through Payload's own CLI.

| Command                  | What                                                                                                                                                                                                                                                                                       |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `payload revalidate-map` | Renders the **static** dependency map from your config alone — no running site, no observations, so it's the build-time / CI view of what busts what. Prints a text report by default; `--json` emits the raw inspection, and `--out <file>` (`-o`) writes it to a file instead of stdout. |

## Exports

Two import entry points, plus the finders and primitives you get back from the factory.

**Package root** — `@pro-laico/payload-revalidate`

| Export                                          | Purpose                                                                                                                                                                                                           |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `revalidatePlugin`                              | The plugin. Add it **last** in `plugins: []`.                                                                                                                                                                     |
| `tagsFor`                                       | `tagsFor(payload)` builds prefix-correct raw tags for the rare hand-spelled `cacheTag` need.                                                                                                                      |
| `readRevalidateMarker`                          | `readRevalidateMarker(config)` returns the typed `config.custom.payloadRevalidate` — the resolved `prefix`, `observe`, `lists`, `extraTags`, `rules`, and the map `endpointPath` (non-null only while observing). |
| `getInspection`                                 | The **live** dependency map for this process (observed reads + graph), or `null` when the plugin isn't active. What `GET /api/revalidate-map` and `/dev/revalidate` serve.                                        |
| `buildStaticInspection` · `renderRevalidateMap` | Build the **static** map from a config (`MapConfigSource`) and render it to the text report — the machinery behind `payload revalidate-map`, for custom CI checks or map UIs.                                     |

**Cache helpers** — `@pro-laico/payload-revalidate/cache`

| Export               | Purpose                                                                                             |
| -------------------- | --------------------------------------------------------------------------------------------------- |
| `createCacheHelpers` | Seed once with your live Payload handle; returns the finders, primitives, and manual busters below. |

**Factory returns** — destructured from `createCacheHelpers(db)`, not imported

| Return                                  | Purpose                                                                         |
| --------------------------------------- | ------------------------------------------------------------------------------- |
| `findDocByID`                           | One doc by id → its id-keyed entry. The atomic unit.                            |
| `findDoc`                               | One doc by query, with alias (`as`) and `draft` tagging.                        |
| `findIds`                               | An id-list plus pagination meta, no second query.                               |
| `findGlobal`                            | A global.                                                                       |
| `cacheDoc` · `cacheIds` · `cacheGlobal` | The low-level primitives a finder wraps, for getters the finders can't express. |
| `revalidateDoc`                         | Bust one doc's tags. Lane-aware (published + `:draft`) and prefix-aware.        |
| `revalidateList`                        | Bust a collection's bare list tag plus every declared scope.                    |
| `revalidateGlobal`                      | Bust a global's tags.                                                           |
| `revalidateAll`                         | Bust the `all` tag — every tagged entry.                                        |

## Notes

- **Add the plugin last** in `plugins: []` — it can only hook collections that exist when
  it runs (a boot-time warning names anything registered after it).
- Failure paths are loud in every environment, once per process: `cacheTag` failing
  (entry materializing untagged), the config being unreachable (bake-in walk skipped),
  and `revalidateTag` no-oping outside a request scope all `console.error`/`warn` — a
  production jobs runner silently not revalidating is the one thing this plugin refuses
  to be quiet about.
- The map endpoints are registered only while `observe` is on, so the production default leaves
  them off the config entirely. With `observe: true` forced on in production, they additionally
  require an authenticated Payload user.
- The cache helpers never resolve Payload or your config themselves — no `globalThis`
  stashes, no `@payload-config` alias tricks, no `transpilePackages` requirement. The
  handle you seed into `createCacheHelpers` is the session that runs and tags every read.
- A draft save **over a published doc** is indistinguishable from an unpublish in the
  hook signature, so both lanes bust — a harmless over-bust that keeps unpublish correct.
- Collections without a slug field get no alias tag — id-keyed reads only.
- The bake-in walk is capped (`walk.maxTags`, default 64; Next allows 128 tags/entry);
  capped reads are flagged in the map.
- Bare `posts` list tags bust on membership only — an unscoped `findIds` read that
  depends on sort/filter fields should declare a scope instead.

## Next

- [Writing getters](/docs/plugins/payload-revalidate/getters) — finder signatures and the `'use cache'` pattern.
- [The atomic model](/docs/plugins/payload-revalidate/atomic-model) — the tag vocabulary and what busts when.
- [Troubleshooting](/docs/plugins/payload-revalidate/troubleshooting) — failure modes and the `/dev/revalidate` map.
