Content staging for API changes
On this page
Nothing written through the content API reaches the live store directly. Writes collect on a draft, called a content change, and the change goes live only when a person approves it in Salesforce. An agent cannot publish without a person’s approval, whatever scopes it has.
Use this process to take a change from draft to the live store, and to check who can act on a draft at each step.
The lifecycle
- Create a change. Over the REST API, send
POST /api/v1/content/changeswith asummary. Reviewers see the summary in the Salesforce approval queue, so describe what the change does, for example"Add the spring range and a new home page hero". Through MCP, the first write opens a draft automatically if you have not created one. - Stage records onto it. Write to paths of the form
/api/v1/content/changes/{change_id}/<resource>, such as/api/v1/content/changes/{change_id}/products. Paths that are not nested under a change return live data. -
Check what you staged. Send
GET /api/v1/content/changes/{change_id}/recordsto list every record staged on the change. Addobject_api_nameto filter by object, for exampleobject_api_name=s_c__page__c.A record you staged as new is not live, so a plain read of it returns
404. To read one back over the REST API, addcontent_change_id={change_id}to a single-record read, such asGET /api/v1/content/pages/{id}?content_change_id={change_id}. This works only for your own draft. List reads, and reads of records that are already live, return live values. Through MCP, reads show the store with your draft applied. - Preview it.
GET /api/v1/content/changes/{change_id}/preview_urlreturns a URL that shows the staged store in a browser. -
Push it. Send
POST /api/v1/content/changes/{change_id}/publish. The change goes to Salesforce for review, and the REST response returns only the new status and a message.When you push through MCP, the response also lists problems found in the staged content, such as products without a price or media without alternative text. Most problems are warnings for the reviewer. One stops the push until it is fixed: a content block that names a theme snippet that does not exist.
- A person approves it in Salesforce. The staged records reach the live store only at this step. Salesforce does not let a person approve a change they created.
A taken identifier is refused when it is staged
An identifier on a media record or a content block must be unique, because Salesforce rejects a duplicate when the change publishes. The media and content block endpoints check for a duplicate when you stage the record, so a clash is refused straight away instead of failing the whole change at publish. The response is a 422 naming the record that already holds the value, for example:
```text
Identifier “hero-banner” is already used by Spring hero (a0B5g00000XyZ12EAB). These must be unique, so choose a different one or update that content block instead. ```
The check ignores case, as Salesforce does, so Hero-Banner clashes with hero-banner. The check covers live records and records staged on the same change, including a staged rename. Keeping a record’s own identifier when you update the record is not a clash.
Who can read and write a draft
Anyone in the store can read any draft through GET /api/v1/content/changes/{change_id} and the records list, so a team can see each other’s work in progress.
Only the draft’s owner can stage records onto it, discard it or push it. A teammate can read your draft but cannot add to it, discard it or push it.
For which scopes allow creating, pushing and discarding a draft, see the scope rules.
Undo or discard
To undo one staged record and keep the rest of the change, send DELETE /api/v1/content/changes/{change_id}/records/{record_id}, where {record_id} is the id returned when you staged the record. This needs content.write, and works only on your own draft.
To discard the whole change and everything staged onto it, send DELETE /api/v1/content/changes/{change_id}.
You can only discard a change while it is still a draft. Once the change is pushed, the decision is made in Salesforce, and the API cannot discard it.
Preview URLs expire
StoreConnect generates a new preview URL for each request, and each URL works for a limited time. Do not store a preview URL to reuse or share later, because you cannot tell when it will stop working. Request a new one each time you need it.
After the push
Whether and when a pushed change is published is decided in Salesforce. The storefront shows the change only after it is published.
To check progress, send GET /api/v1/content/changes/{change_id} and read status in the response:
draft— editable, and not in review.review— pushed and waiting for a person in Salesforce.approved— approved and waiting to be published.published— the staged records are live on the store.
If a change stays at review or approved longer than expected, ask the person approving changes in Salesforce to check it.
Was this article helpful?
Thanks for your feedback! It helps us improve our docs.