Tools
Draft writes
Two write tools patch attribute values as
drafts inside Peak PIM. Nothing reaches Shopify until
something publishes — a person in the app, or a publish-tier connection calling
publish_master_v1. Both require
pim:write.
update_master_attributes_v1
update_master_attributes_v1pim:writePartially update an item's canonical fields.
| Argument | Type | Description |
|---|---|---|
id | string, required | Item id. |
changes | object, required | Field key → new value upserts (string values). An empty value clears the field's value but keeps the field. |
revision | integer | Optimistic concurrency: pass the item's current draft revision. A non-zero value that does not match is rejected with 409; omit or 0 for last-write-wins. |
Behavior to know:
- Empty clears, never deletes. An empty string in
changesclears the field's value but keeps the field itself. - Stale revision → 409. If someone edited the draft since the assistant last read it, a non-zero
revisionthat no longer matches fails with 409 — re-read the item, then retry with the fresh revision. Omittingrevision(or passing 0) skips the check entirely: last write wins. - Option-model keys → 400. A product's option structure can't be edited through this tool; option-model keys in
changesare rejected with 400.
update_projection_attributes_v1
update_projection_attributes_v1pim:writePartially update the fields of an item's per-store version.
| Argument | Type | Description |
|---|---|---|
id | string, required | Per-store version id. |
changes | object, required | Field key → new value upserts, as above. |
- No revision check. Per-store versions have no optimistic concurrency — every write is last-write-wins.
- Duplicate option tuple → 409. A change that would make a variant's option combination collide with another variant's on the same store is rejected with 409.
match_products_v1
match_products_v1pim:writeMatch two products that are the same product on different stores, exactly like the app's product matching: the source product merges into the target, which survives and is returned as merged_into. The source's per-store versions and translations move onto the target, and the source no longer exists.
| Argument | Type | Description |
|---|---|---|
source_product_id | string, required | The product that merges away. |
target_product_id | string, required | The product that survives. |
variant_mappings | array, required | One {source_variant_id, target_variant_id} per real source variant (variant item ids from get_master_related_v1); target_variant_id: null keeps the variant as a new variant of the target. [] when the source has no real variants. |
- Refusals. An incomplete or invalid mapping is rejected with 400; two products (or a mapped variant pair) already on the same store are refused with 409 and
colliding_channel_ids. - PIM-only, no undo. Nothing is sent to Shopify, and there is no unmatch tool.
Read before you write
- Fetch the current state first (
get_master_v1orget_projection_v1) — for the field keys, the current values, and therevisionto pass. - Writing a metafield? Read
list_metafield_definitions_v1first — it tells you the key and the type a value must match. - During a store import/refresh reconciliation, writes fail with 423 until it is finalized in the app — see Security & limits.
These tools carry destructive-write annotations because an upsert overwrites the prior draft value and a match removes the source product — but the blast radius stays inside Peak PIM. Your Shopify stores don't change until an explicit publish.