Drafts
Payload's Draft functionality builds on top of the Versions functionality to allow you to make changes to your collection documents and globals, but publish only when you're ready. This functionality allows you to build powerful Preview environments for your data, where you can make sure your changes look good before publishing documents.
By enabling Versions with Drafts, your collections and globals can maintain newer, and unpublished versions of your documents. It's perfect for cases where you might want to work on a document, update it and save your progress, but not necessarily make it publicly published right away. Drafts are extremely helpful when building preview implementations.

If Drafts are enabled, the typical Save button is replaced with new actions which allow you to either save a draft, or publish your changes.
Options
Collections and Globals both support the same options for configuring drafts. You can either set versions.drafts to true, or pass an object to configure draft properties.
Draft Option | Description |
|---|---|
| Enable |
| Beta. Localizes the |
| Allow for editors to schedule publish / unpublish events in the future. More |
| Set |
Database changes
By enabling drafts on a collection or a global, Payload will automatically inject a new field into your schema called _status. The _status field is used internally by Payload to store if a document is set to draft or published.
Admin UI status indication
Within the Admin UI, if drafts are enabled, a document can be shown with one of three "statuses":
- Draft - if a document has never been published, and only draft versions of the document are present
- Published - if a document is published and there are no newer drafts available
- Changed - if a document has been published, but there are newer drafts available and not yet published
Draft API
Using the draft parameter
When drafts are enabled, the create, update, find, and findByID operations for REST, GraphQL, and Local APIs expose a draft parameter. For write operations, it controls validation and where data is written. For read operations, it determines whether to return draft versions.
Understanding draft parameter and _status field
The draft parameter and _status field work together but serve different purposes:
draft parameter - Controls two things:
- Validation: When
draft: true, required fields are not enforced, allowing you to save incomplete documents - Write location: Determines whether the main collection document is updated
draft: true- Saves ONLY to versions table (main collection unchanged)draft: falseor omitted - Saves to BOTH main collection AND versions table
_status field - Indicates whether a document is published or in draft state
- Defaults to
'draft'when not explicitly provided - Can be explicitly set in your data to
'published'or'draft'
First document creation
When you first create a document, it's always written to the main collection (since no document exists yet):
- If you don't specify
_status, it defaults to_status: 'draft' - A version is also created in the versions table
- The
draftparameter controls validation but doesn't change where the initial document is written
Subsequent updates
After initial creation, the draft parameter controls where your updates are written:
draft: true- Only the versions table is updated; the main collection document remains unchangeddraft: falseor omitted - Both the main collection and versions table are updated
Important: The draft parameter does NOT control whether a document is published or not. A document remains with _status: 'draft' by default unless you explicitly set _status: 'published' in your data.
Publishing a document
To publish a document, you must explicitly set _status: 'published' in your data. When you do this:
- If you use
draft: falseor omit it, the main collection will be updated with the published status - If you use
draft: true, the_status: 'published'takes precedence and will still update the main collection as published (overriding thedraft: truebehavior)
Quick reference
Operation | | | Result |
|---|---|---|---|
Create | | omitted | Main collection updated with |
Create | | | Main collection updated with |
Update | | omitted or | Only versions table updated, main collection unchanged |
Update | | | Main collection updated with |
Update | | omitted | Main collection updated with |
Update | | | Main collection updated with |
Required fields
Setting _status: "draft" will not bypass required field validation. You need to set draft: true to save incomplete documents as shown in the previous examples.
Reading drafts vs. published documents
In addition to the draft argument within create and update operations, a draft argument is also exposed for find and findByID operations.
When draft is set to true while reading a document, Payload will return the most recent version from the versions table, regardless of whether it's a draft or published document.
Example scenario:
- You create a document with
_status: 'published'(published in main collection) - You update with
draft: trueto make changes without affecting the published version - You update again with
draft: trueto make more draft changes
At this point, your published document remains unchanged in the main collection, and you have two newer draft versions in the _[collectionSlug]_versions table.
When you fetch the document with a standard find or findByID operation, the published document from the main collection is returned and draft versions are ignored.
However, if you pass draft: true to the read operation, Payload will return the most recent version from the versions table. In the scenario above with two draft versions, you'll get the latest (second) draft.
Note: If there are no newer drafts (e.g., you published a document and haven't made draft changes since), querying with draft: true will still return the latest version from the versions table, which would be the same published content as in the main collection.
Controlling who can see Collection drafts
Restricting draft access
You can use the read Access Control method to restrict who is able to view drafts of your documents by simply returning a query constraint which restricts the documents that any given user is able to retrieve.
Here is an example that utilizes the _status field to require a user to be logged in to retrieve drafts:
Here is an example for how to write an Access Control function that grants access to both documents where _status is equal to "published" and where _status does not exist:
Controlling who can publish
You can use update Access Control to restrict who can publish documents by returning a query constraint on the _status field. When this constraint prevents publishing, the Admin UI automatically hides the Publish and Unpublish buttons.
Here is an example where admins can publish, but editors can only save drafts:
The update function returns a query constraint instead of a boolean. Payload appends this constraint to the update query, so only documents where _status is not published can be updated by editors. This also blocks scheduled publish jobs from executing for those users.
The create function uses a data check instead since there is no existing document to query against.
Scheduled publish
Payload provides for an ability to schedule publishing / unpublishing events in the future, which can be helpful if you need to set certain documents to "go live" at a given date in the future, or, vice versa, revert to a draft state after a certain time has passed.
You can enable this functionality on both collections and globals via the versions.drafts.schedulePublish: true property.
Unpublishing drafts
If a document is published, the Payload Admin UI will be updated to show an "unpublish" button at the top of the sidebar, which will "unpublish" the currently published document. Consider this as a way to "revert" a document back to a draft state. On the API side, this is done by simply setting _status: 'draft' on any document.
Reverting to published
If a document is published, and you have made further changes which are saved as a draft, Payload will show a "revert to published" button at the top of the sidebar which will allow you to reject your draft changes and "revert" back to the published state of the document. Your drafts will still be saved, but a new version will be created that will reflect the last published state of the document.
Was this page helpful?