Productsup
Developer guides

Publishing changes

Export template changes stay in draft until you commit them. How to commit changes with the ETM API and publish them in the Dev Portal.

7 min read

Writing to an export template does not make the change live. Every write is a draft until you commit it, and only committed changes reach the Productsup platform.

This covers attributes, attribute tags, export template tags, marketing data, custom form fields, and template settings. A successful 2xx from a write endpoint means the change is stored in Export Template Management — not that platform users can see it.

Analyzer tests are the one exception. See What does not need publishing.

The model

An export template has two states of change:

StateWhat it means
DraftThe change is stored in Export Template Management. unpublishedChanges is true. The platform still serves the previously committed state.
CommittedA commit created a new revision. The platform picks that revision up and rebuilds its copy of the template from it.

Nothing moves a draft to committed except an explicit commit. There is no auto-commit, no timeout, and no partial propagation — a draft stays a draft indefinitely.

Commit changes with the API

Call the commit endpoint once you have finished writing:

curl -X POST "https://export-template-api.productsup.com/V1/export-templates/{templateId}/commit" \
  -H "Authorization: Bearer <token>"

A 201 Created response means a new revision exists. Batch your writes and commit once at the end rather than committing after each call — a commit is per template, not per change.

A missing commit produces the symptom "the API returned success, but nothing changed in the platform." Check unpublishedChanges before assuming a write was lost.

Publish changes in the Dev Portal

The Dev Portal calls the same endpoint behind the Publish button on the export template page. Saving a step in the interface stores a draft; it does not publish. When a template has uncommitted changes, the interface shows an unpublished-changes warning.

Both routes are equivalent. If you mix them — writing over the API and working in the interface on the same template — either Publish or a commit call publishes everything currently in draft, regardless of which route created it.

See Publish export template changes for the interface walkthrough.

What does not need publishing

Analyzer tests take effect immediately. These three operations bypass the draft cycle entirely:

OperationEndpoint
Add an analyzer test to an attributePOST /V2/attributes/{attributeId}/analyzer-tests
Update an analyzer testPATCH /V2/attributes/{attributeId}/analyzer-tests/{assignmentId}
Remove an analyzer testDELETE /V2/attributes/{attributeId}/analyzer-tests/{assignmentId}

Adding, changing, or removing an analyzer test is live as soon as the request succeeds, and it does not set unpublishedChanges. There is nothing to commit.

If an analyzer test does not appear to take effect, check whether the attribute you added it to is published. Analyzer tests are stored against the attribute, so a test on an attribute that is still a draft has nothing to run against yet.

The full-replace endpoint mixes both behaviours. PUT /V2/export-templates/{templateId} writes attributes as a draft and analyzer tests immediately, so the analyzer tests in your payload apply before you publish and the rest does not.

Check for uncommitted changes

GET /V2/export-templates/{templateId} returns an unpublishedChanges boolean:

curl "https://export-template-api.productsup.com/V2/export-templates/{templateId}" \
  -H "Authorization: Bearer <token>"
{
  "id": 12345,
  "name": "Example channel",
  "unpublishedChanges": true
}

true means at least one write has not been committed. Commit, and the flag clears.

Worked example

Adding a template tag takes two calls. The first stores the tag; the second publishes it:

# 1. Write the tag — stored as a draft
curl -X POST "https://export-template-api.productsup.com/V1/export-templates/{templateId}/export-template-tags" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"key": "example_tag_key", "value": "example_value"}'

# 2. Commit — the tag becomes live
curl -X POST "https://export-template-api.productsup.com/V1/export-templates/{templateId}/commit" \
  -H "Authorization: Bearer <token>"

Stop after the first call and the tag exists in Export Template Management, is returned by the tag endpoints, and is invisible to the platform.

Propagation is asynchronous

A commit creates the revision; the platform consumes it on its next synchronization run. Allow a short delay between the commit and the change appearing in the platform. A 201 from the commit endpoint confirms the revision was created, not that propagation has finished.

Propagation is one-way, and it rebuilds the platform's copy of the template from Export Template Management on every commit. Anything changed directly on the platform side, outside the ETM API, is overwritten on the next commit. Make the change in Export Template Management so it survives.

A commit always creates a revision, even when the template has no pending draft. Use it to force the platform to re-read a template whose state has drifted.

Next steps

On this page

Still stuck?

Reach out to our support team and we’ll help you get unstuck.

Contact support