The module is
products. It is required in 3PL mode and optional elsewhere (chapter 12).
1. The product object
2. CRUD
- Optimistic concurrency. Send
If-Match: 7(theversion) on update. A stale version returns409 state_error/version_conflict, with the current object inerror.details. This prevents two sync sources from silently overwriting each other. statusisactive,archived, ordraft(incomplete trade data: allowed in drafts, and rejected at purchase when required).- The search query
-hs_codes.import.GB:*finds products missing a UK import code, which is useful before opening a new corridor.
3. Sync
matchisexternal_id,sku, orid. A match updates, and no match creates. The response is the product, withsystem_metadata.upsert: "created" | "updated" | "unchanged".- Field ownership.
fields_ownedsays which fields this source is authoritative for. Fields it does not own are never overwritten by it. That lets an e-commerce platform own titles and prices, while the trade team owns HS codes and origin, with no last-writer-wins damage. - Bulk.
POST /v1/batcheswithoperation: "products.upsert"(up to 1000), orPOST /v1/products/importwith a CSVfileand a column mapping. - Incremental pull.
GET /v1/products?updated[gte]=…with cursor pagination, orproduct.*webhooks, keep downstream systems in sync. - Export.
POST /v1/exportswithresource: "products"(chapter 10 §8).
4. Items that reference products
AnyItem may set product:
- The product’s fields, merged over its parent’s (for variants), fill every item field that the item leaves unset.
import_hs_codeis taken fromhs_codes.import[ship_to.address.country], then"*".export_hs_codeis taken fromhs_codes.export[ship_from.address.country].- Fields set on the item always win. Per-shipment overrides are normal, such as a discounted
unit_value. - The resolved values are written onto the item. At purchase they are snapshotted, so later product edits never change a purchased shipment or its customs record.
- A
draftorarchivedproduct used in a purchase returns400 parameter_invalid(product_not_active).
POST /v1/classifications/{id}/apply accepts { "product": "prod_..." } as well as a shipment, writing into hs_codes and classification. Compliance screening caches its item results in restrictions[].
5. Events
product.created, product.updated (with previous_attributes), product.archived, product.unarchived, product.deleted, product.classification_needed (emitted when a shipment needs a destination code the product lacks).