Guides
Monitor publishes
A PIM edit is a draft until someone publishes it, and a publish can fail. Two
fields — pending_publish and last_publish_status — plus
the status list filter give you everything an alerting job needs to
catch failed and forgotten publishes.
The publish-state fields
Every entity, every store version, and every entity's per-store
stores[] entry carries:
| Field | Meaning |
|---|---|
pending_publish | Draft changes exist that have not been pushed to the store(s) yet |
last_publish_status | Where the draft stands: never_published · pending · published · failed |
The status filter and last_publish_status field describe where the entity stands with Peak PIM's stores. Shopify's own product status (active/draft/archived) is a per-store attribute value, not this field.
Find problems with the status filter
Every list endpoint accepts status, with values identical to
last_publish_status — a value read from a response can be fed straight
back into the filter. The alerting sweep is one filtered list per resource:
# Everything whose last publish failed
curl -s "https://api.peak-pim.com/api/v1/products?status=failed&limit=250" \
-H "Authorization: Bearer pk_live_..."
{"data": [
{"id": "0e8f...", "type": "product", "title": "Trail Runner 2",
"draft_revision": 7, "pending_publish": true,
"last_publish_status": "failed", "store_ids": ["a1b2...", "c3d4..."]}
], "next_cursor": null}
# Everything that has never gone live at all
curl -s "https://api.peak-pim.com/api/v1/products?status=never_published&limit=250" \
-H "Authorization: Bearer pk_live_..."
Repeat for /api/v1/variants, /api/v1/collections, and
/api/v1/media. Page with cursor if the filtered list
exceeds a page.
Localize the failure per store
An account-level failed tells you something went wrong; the detail
read tells you where. The entity's stores[] array carries publish
state per store it lives on:
curl -s https://api.peak-pim.com/api/v1/products/0e8f... \
-H "Authorization: Bearer pk_live_..."
{"id": "0e8f...", "title": "Trail Runner 2", ...,
"stores": [
{"store_id": "a1b2...", "store_domain": "acme-us.myshopify.com",
"pending_publish": false, "last_publish_status": "published"},
{"store_id": "c3d4...", "store_domain": "acme-de.myshopify.com",
"pending_publish": true, "last_publish_status": "failed"}
]}
Here the US store is live and the German store failed — the alert should name
acme-de.myshopify.com, not just the product.
Alerting patterns
-
Failed-publish alert. Poll
status=failedper resource on a schedule. Any row is alert-worthy; includetitleand the failing stores from the detail read. -
Forgotten-draft alert.
pending_publish: truewithlast_publish_status: publishedmeans someone edited after the last successful publish and never pushed. List rows carry both fields, so a catalog poll can flag rows that stay pending across consecutive runs. -
Launch checklist. Before a campaign, sweep
status=never_publishedandstatus=pendingto catch items that were meant to be live. -
Keep it cheap. These are ordinary list reads: ETags,
limit=250, and the rate-limit headers all apply. A monitor that mostly sees 304s is nearly free.
The MCP alternative
The same fields come back from the connector's list and get tools, so a read-tier assistant can run the sweep on demand:
"List my products and show me which ones have unpublished changes."
On the publish tier, publish_master_v1 closes the loop: after a
publish, its result reports per-store success and failure (and on timeout the
publish may still complete — re-read the item and check its publish state). See
Build an AI catalog operator.
Related
- Pagination & filtering — the
statusparameter in context. - Data health — the sync dimension counts unpublished and failed entities account-wide.
- Core concepts — publish state in the data model.