Store Scope
The store_id field that scopes a product to one client store, the rules it imposes on the product and its prices,
and the item change request object returned when a write to such a product is diverted for client review.
Tip
Looking for hands-on instructions? See Store-Scoped Products and Change Requests for the full flow with examples.
Overview
A product carries an optional store_id. When it is set, the product is store-scoped: it is visible only in that client store, and the store's client reviews every change to it. When it is null the product is global, which is the default and the behaviour every other page in this reference describes.
The store_id field
| Property | Value |
|---|---|
| Type | Integer, the id of a client store |
| Required | No. Omit it, or send null, for a global product. |
| Accepted on | POST /api/suppliers/products only. In the supplier portal it is the Store scope field on the Details step of Add product. |
| Constraints | Must be a store you are connected to. It is prohibited on PUT /api/suppliers/products/{product_identifier}, so a product's scope cannot change after creation. |
| Imports | Not accepted. A store_id in a CSV, JSONL or batch row fails that row. |
| Variants | Variants have no store_id of their own; they inherit the scope of their product. |
Effects on the product
| Area | Rule |
|---|---|
| Prices | Every price on the product or its variants must carry the product's store_id. A price for another store, or with no store_id, is rejected with The prices.N.store_id field must be the store the product is scoped to. This applies to prices embedded in the product payload and to price lists created through POST /api/suppliers/price-lists. |
| Writes | POST (variants), PUT and DELETE on the product and variant endpoints are diverted into an item change request and answer 202 Accepted. See Diverted responses. |
| Sub-resources | Write verbs on the URL, code, property, stock, option, translation and category attach/detach endpoints are refused with 422. |
| Imports and batches | Rows that create or touch a store-scoped product are reported as row errors. |
| Restore | Refused with 422. |
| Mass delete | Store-scoped products are excluded. |
| Duplicate merge | The automatic merge of products sharing an identifier never merges a store-scoped product or merges into one. |
On responses
| Endpoint | Field | Meaning |
|---|---|---|
GET /api/suppliers/products | store_id | The scoping store, or null. |
GET /api/suppliers/products | under_review | true while the product or one of its variants has an open change request. |
GET /api/suppliers/products | query store_scoped | 1 returns only store-scoped products, 0 only global products. Omit for both. |
Diverted responses
A write to a store-scoped item answers 202 Accepted with:
| Field | Description |
|---|---|
change_request_pending | Always true. |
change_request | The item change request that was recorded. |
message | A human-readable explanation. |
The write accepts one extra input, reason: a string of up to 2000 characters shown to the client with the request. It is optional for create and update, and required for delete, which otherwise fails with a validation error on reason.
A write that cannot be recorded, because the item already has an approved request awaiting apply, or because a variant write conflicts with a pending product-level request, fails with 422 and an error on item.
The item change request object
Returned by the diverted responses and by the endpoints below.
| Method | Endpoint | Permission |
|---|---|---|
GET | /api/suppliers/item-change-requests | item-change-requests-list-as-supplier |
GET | /api/suppliers/item-change-requests/{uuid} | item-change-requests-show-as-supplier |
POST | /api/suppliers/item-change-requests/{uuid}/cancel | item-change-requests-cancel-as-supplier |
List parameters
| Parameter | Type | Description |
|---|---|---|
status | string | One of the statuses. |
command | string | create, update or delete. |
item_type | string | product or product_variant. |
store_id | integer | Only requests raised in this store. |
submitted_after, submitted_before | date | Bound the submission date. |
page, per_page | integer | Pagination, 10 per page by default. |
Fields
| Field | Type | Description |
|---|---|---|
uuid | string | The request's reference. |
item_type | string | product or product_variant. |
item_id | integer or null | The live item. null while a create is pending. |
product_id | integer or null | The product, or the parent product of a variant. null while a product create is pending. |
store_id | integer | The store the request was raised in. |
supplier_id | integer | Your supplier id. |
command | string | create, update or delete. |
command_label | string | A display label for command. |
status | string | See Statuses. |
status_label | string | A display label for status. |
item_label | string | The item type and identifier, for example Product KIT-ACME-001. Resolved from the stored payloads, so it is filled in after deletion. |
reason | string or null | The reason you gave. |
resolution_note | string or null | The client's note, recorded when they approved or rejected. |
superseded_by_id | integer or null | The newer request that replaced this one. |
submitted_at | datetime | When you submitted it. |
resolved_at | datetime or null | When it was approved, rejected, superseded or cancelled. |
applied_at | datetime or null | When an approved request was applied. |
proposed_changes | object or null | Your payload as submitted. null for a delete. Single request only. |
before_snapshot | object or null | The item as it was when you submitted, in the same shape as a submission payload. null for a create. Single request only. |
changes | list | The field-level differences, each { "field", "old", "new" }. Nested collections are matched by their natural key, for example a code by type and version, a price by store_id, country and currency, a variant by variant_identifier. Empty for a delete. Single request only. |
store | object | The store, when loaded. |
item | object | The live item, when loaded and still existing. |
Statuses
| Status | Open? | Meaning |
|---|---|---|
pending | Yes | Awaiting the client's decision. Can be cancelled or superseded. |
approved | Yes | Approved, but the apply failed and can be retried by the client. Blocks new submissions for the item until the client retries or rejects it, or you cancel it. |
applied | No | Approved and applied to the live item. |
rejected | No | Rejected by the client. |
superseded | No | Replaced by a newer submission of yours. |
cancelled | No | Withdrawn by you. |
An item has at most one open request at a time. The transitions are pending to approved, rejected, superseded or cancelled, and approved to applied, rejected or cancelled. The closed statuses are final.
Cancel
POST /api/suppliers/item-change-requests/{uuid}/cancel moves a pending or approved request to cancelled and returns it. A closed request fails with 422. The live item is untouched.