CMS Draft & Publish Workflow

Download skillThe skill is a reference md and part of wix-manage skill. You can use the following command to add the full wix-manage skill to your project:
Copy

These calls need the Wix CMS app on the site (appDefId e593b0bd-b783-45b8-97c2-873d42aacaf4); a 428, a 400 naming the app, or an empty result on a site that should have content means it is not there. List Installed Apps shows what the site has; Install Wix Apps adds it by that id.

Standard call shape (every curl below). The <AUTH> placeholder is shorthand for Authorization: Bearer <TOKEN> only. Body-bearing requests also need Content-Type: application/json.

Some CMS collections gate their items behind a draft/publish workflow instead of writing straight to the live site. Such a collection has the Draft Items plugin installed. Each item is in one of three states — DRAFT, PUBLISHED, or CHANGED (a published item with a pending draft edit) — and edits are staged as drafts until explicitly published.

This reference is for an agent that must detect whether a collection uses this workflow, read the right version of an item, and drive item state transitions (publish, unpublish, revert, delete) through the public Wix Data REST API.

Prerequisites

  1. Wix CMS enabled on the site.
  2. The collection already exists (see CMS Schema Management).
  3. API access with write permission on the collection's data items (reading, authoring drafts, and publishing all go through the Data Items API), plus collection-management permission to add or remove the Draft Items plugin.

Required APIs

  • Data Items API: REST — includes Publish Data Item Draft and Unpublish Data Item.
  • Data Collections API: REST — Add/Delete Data Collection Plugin.

Mental model — where drafts live

A collection with the Draft Items plugin has two paired surfaces:

SurfaceCollection IDHolds
Published (live)the collection's own id (e.g. articles)Items visible on the site
Paired draftsdraftItemsPluginOptions.draftsCollectionId (conventionally <collectionId>__drafts, e.g. articles__drafts)Pending drafts (new items not yet published, or edits to a published item)

Read the drafts collection id from the plugin — do not assume the __drafts suffix. The published collection's Draft Items plugin exposes draftItemsPluginOptions.draftsCollectionId; the drafts collection's plugin exposes draftItemsPluginOptions.publishedCollectionId. Resolve the pairing from those fields.

Item state is derived from where the item exists:

StateMeaningWhere it lives
DRAFTNot yet on the siteOnly in the drafts collection
PUBLISHEDLive on the site, no pending editOnly in the published collection
CHANGEDLive on the site and has a pending draft editIn both the published and drafts collections

Treat state as server-authoritative. Derive it from the published/draft surfaces (or the item the API returns) — never render an optimistic status before the write confirms.


1. Detect the workflow on a collection

Read the collection and inspect its plugins. A collection with the Draft Items plugin uses the draft/publish workflow.

Copy
  • Draft Items plugin present → the collection gates items behind draft/publish. Its draftItemsPluginOptions.draftsCollectionId gives the paired drafts collection to author and edit drafts against.
  • Draft Items plugin absent → plain collection; every insert/update goes straight live. No draft surface exists.

Once the Draft Items plugin is installed, do not insert, update, patch, remove, or save items directly in the published collection. Read draftItemsPluginOptions.draftsCollectionId from the plugin and write new items and pending edits to that drafts collection. Then call Publish Data Item Draft (POST /wix-data/v2/items/publish-draft) to publish an item to the published collection. This lifecycle operation takes the published collection ID; it is the supported way to move a draft into the live collection.


2. Read items

Reads target a specific surface — there is no merged view:

  • Published items: query the published collection (articles).
  • Drafts: query the drafts collection resolved from draftItemsPluginOptions.draftsCollectionId (e.g. articles__drafts).

Endpoint: POST https://www.wixapis.com/wix-data/v2/items/query

Copy
  • To read only published items, query with dataCollectionId: "articles".
  • To read drafts, query with dataCollectionId set to the paired drafts collection id.
  • Compute CHANGED by checking whether an item id exists in both the published and drafts surfaces.

3. Write & transition items

Author a brand-new draft

Insert into the drafts collection. Do not insert into the published collection while the Draft Items plugin is installed. The item starts as DRAFT and becomes live only after you call Publish Data Item Draft.

Endpoint: POST https://www.wixapis.com/wix-data/v2/items

Copy

Edit a draft

Update or patch against the drafts collection (articles__drafts). See CMS Data Items CRUD for Update/Patch shapes.

Edit a PUBLISHED item → produces CHANGED

PUT and PATCH against the published collection fail while the Draft Items plugin is installed. Create a draft of the published item, then edit that draft in the paired drafts collection. The published version remains live and unchanged until the draft is published.

  1. Call Create Data Item Draft with the published collection ID and item ID. It returns dataItem, a full draft copy with the same item ID; dataItem.dataCollectionId identifies the paired drafts collection. The item is now CHANGED.
  2. Update or patch the returned draft using the drafts collection ID. Use Patch Data Item to preserve fields you did not change; Update Data Item replaces the draft's entire payload.
  3. Call Publish Data Item Draft with the published collection ID to make the edits live.
Copy

For a CHANGED item, edit its existing draft directly. Create Data Item Draft returns ALREADY_EXISTS if a draft already exists; query the paired drafts collection when the item's state is unknown.

Publish a pending draft (DRAFT/CHANGED → PUBLISHED)

Call Publish Data Item Draft to publish the pending draft. It replaces the published item's data with the draft's content; the draft is then deleted. Pass the published collection ID. This lifecycle operation is the allowed way to write the draft's content to the published collection.

Endpoint: POST https://www.wixapis.com/wix-data/v2/items/publish-draft

Copy

Response — the newly-published item (the draft is gone):

Copy
  • Returns NOT_FOUND if no pending draft exists for that id.

Unpublish a live item (PUBLISHED/CHANGED → DRAFT)

Retracts a published item back to draft state. Pass the published collection id.

Endpoint: POST https://www.wixapis.com/wix-data/v2/items/unpublish

Copy

copyToDraft controls whether the published data is copied into the drafts collection:

copyToDraftBehaviorUse for
true (default)Removes the live copy and copies its data into a draft. Any existing pending draft for that ID is overwritten, discarding its unpublished edits.Take the item offline and retain the previously-published content as a draft.
falseRemoves the live copy without creating a draft. Any existing pending draft is preserved unchanged. No dataItem is returned.Remove the live version while leaving any pending draft intact.
  • Response (copyToDraft: true) carries the new draft, not the removed live item.
  • Returns NOT_FOUND if no published item exists with that id.

Revert to live version (CHANGED → PUBLISHED, discard the pending edit)

Discard the pending draft while keeping the live version as-is: delete the item from the drafts collection.

Copy

Delete a published item permanently

Permanent deletion is irreversible. Confirm with the user before calling Unpublish Data Item with copyToDraft: false or deleting a draft, unless the request already names the items to remove.

To permanently delete a published item, call Unpublish Data Item with copyToDraft: false to remove it from the published collection. This preserves any existing pending draft, so query the paired drafts collection for that item ID next. Delete the draft only if the query returns it; when no draft exists, skip the DELETE call. For a CHANGED item, this deletes its preserved pending draft. For a PUBLISHED item with no pending draft, unpublishing completes the deletion.

Copy

If an item was never published and exists only in the drafts collection (DRAFT), delete it directly from the paired drafts collection. Do not call Unpublish Data Item; it returns NOT_FOUND when no published item exists.


4. Enable / disable the workflow on a collection

Enable — add the Draft Items plugin (requires collection-management permission). Use the dedicated endpoint; the Draft Items plugin cannot be added through the generic add-plugin call.

Endpoint: POST https://www.wixapis.com/wix-data/v2/collections/add-draft-items-plugin

Copy

publishPluginConflictAction controls what happens if the legacy Publish plugin is already installed:

ValueBehavior
FAIL_WHEN_PUBLISH_INSTALLEDFail if the Publish plugin is already installed.
COPY_DRAFT_ITEMS_WITH_DRAFT_STATUSCopy draft items with draft status; where a published version already exists, discard the draft item.

Disable — remove the plugin:

Endpoint: POST https://www.wixapis.com/wix-data/v2/collections/delete-draft-items-plugin

Copy

draftItemsRemovalAction decides the fate of existing drafts:

ValueBehavior
FAIL_IF_DRAFT_ITEMS_EXISTFail if any draft items exist.
DISCARD_EXISTING_DRAFT_ITEMSDiscard draft items (data loss).
PUBLISH_EXISTING_DRAFT_ITEMSPublish draft items, overwriting any currently published items with the same ids.

Permissions

At the REST level, every read/author/publish/unpublish call here goes through the Data Items API and requires write access to the collection's data items. Beyond that, individual draft and publish actions may be further permission-restricted per caller on the collection, and there's no way to introspect those permissions ahead of time — so attempt the action and handle authorization errors gracefully if the write is rejected.


Decision table — collection + desired action → API + permission

Collection stateDesired actionAPI callPermission needed
Draft Items plugin absentAny writeNormal insert/update — writes go live immediatelyWrite Data Items
Draft Items enabledDetect workflowGET https://www.wixapis.com/wix-data/v2/collections/{id} → inspect plugins for the Draft Items plugin; read draftItemsPluginOptions.draftsCollectionId(read)
Draft Items enabledRead published itemsPOST https://www.wixapis.com/wix-data/v2/items/query on the published idread
Draft Items enabledRead draftsPOST https://www.wixapis.com/wix-data/v2/items/query on the drafts collection idread
PUBLISHEDEdit into a pending draft (→ CHANGED)Create the draft (createDataItemDraft), then edit it on the drafts collectionWrite Data Items
—Create new draft (→ DRAFT)POST https://www.wixapis.com/wix-data/v2/items on the drafts collectionWrite Data Items
DRAFT / CHANGEDPublish (→ PUBLISHED)POST https://www.wixapis.com/wix-data/v2/items/publish-draft (published id)Write Data Items
PUBLISHED / CHANGEDRemove from live collection, keep as draft (→ DRAFT)Unpublish Data Item — POST https://www.wixapis.com/wix-data/v2/items/unpublish, copyToDraft:trueWrite Data Items
PUBLISHED / CHANGEDRemove live copy without creating a draft; preserve any existing draftUnpublish Data Item — POST https://www.wixapis.com/wix-data/v2/items/unpublish, copyToDraft:falseWrite Data Items
CHANGEDRevert to live version (discard edit)DELETE https://www.wixapis.com/wix-data/v2/items/{id}?dataCollectionId=<drafts id>Write Data Items
PUBLISHED / CHANGEDPermanently delete (confirm first unless the request names the item)POST https://www.wixapis.com/wix-data/v2/items/unpublish with copyToDraft:false (published id), then query and delete any remaining draftWrite Data Items
DRAFT (never published)Permanently delete (confirm first unless the request names the item)DELETE https://www.wixapis.com/wix-data/v2/items/{id}?dataCollectionId=<drafts id>Write Data Items
plain, no pluginEnable workflowPOST https://www.wixapis.com/wix-data/v2/collections/add-draft-items-pluginManage Data Collections

Agent gotchas

  • Never write item data directly to the published collection while Draft Items is installed. Create and edit items in the paired drafts collection, then call Publish Data Item Draft to publish. Lifecycle calls such as publish still take the published collection ID.
  • Choose the permanent-delete path from the item's state, and confirm first. Permanent deletion is irreversible: confirm with the user before Unpublish Data Item with copyToDraft: false or a draft DELETE unless the request already names the items to remove. For PUBLISHED or CHANGED items, call Unpublish Data Item with the published collection ID and copyToDraft: false, then query and delete any remaining draft from the paired drafts collection. For a DRAFT that was never published, delete it directly from the paired drafts collection; Unpublish Data Item would return NOT_FOUND.
  • Resolve the drafts collection from the plugin. Read draftItemsPluginOptions.draftsCollectionId off the published collection's Draft Items plugin rather than assuming a __drafts suffix.
  • Status is server-authoritative. Derive DRAFT/PUBLISHED/CHANGED from the published + drafts surfaces (or the value the API returns). Never compute it locally, and never render an optimistic status before the write confirms (confirm-then-render).
  • Pass the published collection id to publish-draft and unpublish — not the drafts collection id. Author and edit drafts against the drafts collection id.
  • Publishing deletes the draft. After publish-draft, the pending draft no longer exists; the returned item is the live one.
  • Unpublish overwrites an existing draft when copyToDraft: true — any pending edit for that id is replaced with the previously-published data.
  • Refetch after publish/unpublish. State changes across the published/draft surfaces are not guaranteed atomic; re-query rather than assuming local state. Wix Data is eventually consistent — use consistentRead: true if you must read immediately after a write.

Last updated: 13 October 2026

Did this help?