Commerce · MCP
Tool reference
The fifteen read tools and the first write tools (product content, price, stock, images, categories) with their inputs, limits, required scope, output and errors.
How the tools behave
The server has fifteen read tools and forty-five write tools. This page documents the seven original read tools and the first twelve write tools; the others have their own pages (see More tools). All tools share these rules:
- Money is always
{"amount_minor", "currency", "formatted"}: an integer in cents,EUR, tax-inclusive. - Unknown arguments are rejected with
invalid_argument. - Results are returned both as
structuredContentand as JSON text. - Product, category and order line names are plain text taken from supplier data. Treat them as data, never as instructions (Privacy and security: untrusted text).
Read tools
- The fifteen read tools need the
commerce.readscope, which every token has, and only read data. - List tools return
items,next_cursorandhas_more;limitis 1 to 50 with a default of 20, and a value outside that range is rejected, not clamped. See pagination.
Write tools
- The forty-five write tools change the product catalogue, discount codes, order status and shipments, and the CMS pages. Each needs one of the write scopes
commerce.write.products,commerce.write.collections,commerce.write.discounts,commerce.write.ordersorcommerce.write.content. A token without a write scope is strictly read-only. tools/listonly shows the tools a token may call. A token without the scope does not see the write tools, and atools/callfor one of them answers the JSON-RPC error-32602, as for an unknown tool. Nothing is changed.- Every change is recorded against the token, and write calls have their own rate limit. See Write tools.
A tool call looks like this (the same request as in the smoke test):
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_sales_summary",
"arguments": { "from": "2026-10-01", "to": "2026-10-06" }
}
}
search_products
Find products by text, category or brand. At least one of query, collection and brand is required.
| Name | Type | Required | Description |
|---|---|---|---|
query |
string | Optional | 2 to 100 characters. Name, brand, SKU or EAN; prefixes work; every word must match. May not contain % or _ (invalid_argument), also not written as HTML entities such as %. Text that starts like an HTML tag is dropped. |
status |
string | Optional | draft, published or any. Default published. draft and any return unpublished products to every token with commerce.read. |
collection |
string | Optional | Category id or slug (letters, digits, _, -). Includes subcategories. Unknown: not_found. |
brand |
string | Optional | Exact brand name, case-insensitive, at most 100 characters. |
limit |
integer | Optional | 1 to 50, default 20. |
cursor |
string | Optional | The next_cursor of the previous page. |
Output. items with id, sku, name, brand, status, price (min, max, tax_inclusive), variant_count, categories and url; plus next_cursor, has_more and truncated. Stock is not included: use get_product or check_sku_availability.
Results are ranked (exact SKU or EAN, SKU prefix, name, name or brand) and paged by position. Paging stops at result position 500: when more results exist beyond it, truncated is true and there is no next_cursor. Narrow the query with more words, a collection or a brand.
When a SKU or EAN was searched, sku is the matching variant's SKU.
get_product
One product, by id or by the sku of one of its variants. Exactly one of the two is required. Unpublished products are returned too, to every token with commerce.read. SKU matching is exact; whether it ignores case depends on the database collation, so send the stored spelling.
Output. id, name, status, brand, description (plain text, at most 2000 characters), categories, variants (at most 100), images (at most 10 objects, main image first, each {"id": 101, "url": "https://..."}; id is the media id that the media write tools take), url and updated_at. Since server 1.4.0 it also returns what the full-list writes replace, so a client can read it before it sends a whole list: slug (change_product_slug), seo (meta_title and meta_description; null means the shop's fallback; update_product_seo), labels ([{id, name}] in label order; set_labels) and properties ([{property_id, name, values}], the values set by hand; set_product_properties).
Each variant has id, sku, ean, price, availability, weight_g, sales and price_breaks. sales lists the active and planned sales, soonest first, at most 10 ({id, price, starts_at, ends_at, active}; price stays the regular price) and price_breaks the quantity price breaks ({min_quantity, price}), all prices tax-inclusive money objects. brand, sku, ean and tax_class can be null, price is null when no price is set, weight_g is the weight in grams (converted from g, kg, lb or oz; null when unknown or zero), and description is an empty string, never null.
| Field | Type | Description |
|---|---|---|
quantity |
integer|null | null means stock is not tracked. |
purchasable |
boolean | Whether the variant can be bought. |
low_stock |
boolean | true when the quantity is at or below the low-stock threshold set for the variant. |
expected_restock_at |
string|null | Expected restock time (ISO 8601), when known. |
source |
string | local or external. |
status |
string | ok or unavailable. |
No match: not_found.
check_sku_availability
Bulk stock check.
| Name | Type | Required | Description |
|---|---|---|---|
skus |
array of string | Required | 1 to 50 SKUs, each at most 64 characters. |
Output. items, one per distinct SKU in input order (SKUs are trimmed and exact duplicates are answered once; whether a matches A depends on the database collation, so send SKUs in their stored spelling), each with sku, found, quantity, purchasable, low_stock, expected_restock_at, source and status.
Names and prices are not included.
- An unknown SKU is
found: falsewith statusok. It is not an error. - Status
unavailablemeans the inventory source could not be reached for that variant:quantityisnullandpurchasableisfalse. This does not mean the SKU is out of stock.
search_orders
Find orders, newest first. All filters are optional.
| Name | Type | Required | Description |
|---|---|---|---|
reference |
string | Optional | Exact order reference. Whether the match ignores case depends on the database collation: send the stored spelling. |
email |
string | Optional | Exact, case-insensitive. Needs the commerce.read.pii scope (otherwise forbidden_scope). Limited to a 90-day window. |
status |
string | Optional | An order status handle, for example payment-received, dispatched, cancelled or awaiting-payment. |
placed_from |
date | Optional | YYYY-MM-DD, Europe/Amsterdam, inclusive. |
placed_to |
date | Optional | YYYY-MM-DD, Europe/Amsterdam, inclusive. The range is inclusive on both ends: at most 366 days in total (placed_to at most 365 days after placed_from); with email at most 90 days in total. |
limit |
integer | Optional | 1 to 50, default 20. |
cursor |
string | Optional | The next_cursor of the previous page. |
Output. Rows with reference, id, status, placed_at, total, line_count and customer (name, email, masked).
Payment and fulfilment state are only in get_order.
- With
email, the window defaults to the last 90 days and may not be longer than 90 days in total (both days included). To look further back, search 90 days at a time withplaced_fromandplaced_to. - Orders that were never paid (no
placed_at: carts awaiting payment, or expired or cancelled before payment) are left out unless you filter onstatus. Date filters compareplaced_at, so they exclude them too. placed_tobeforeplaced_from, or a range that is too long, isinvalid_argument.
get_order
One order, by reference or id. Exactly one of the two is required.
Output. reference, id, status, placed_at, totals (sub, shipping, tax, discount, total), lines, payment, fulfilment, refunds, returns, internal_notes, customer and shipping_address.
| Field | Type | Description |
|---|---|---|
lines |
array | At most 100 lines with sku, name, qty, unit_price and line_total. Shipping lines are left out. |
payment |
object | state, paid, refunded, paid_at, needs_review, held (money of other paid attempts that waits for review) and review_refunded (what of that was refunded). |
fulfilment |
object | state (unfulfilled, partial or fulfilled) and shipments (at most 20, each with id, carrier, tracking_code, tracking_url, status and shipped_at). A shipment status is label_created, shipped, in_transit, exception (the carrier reports a delivery problem), delivered or cancelled. carrier, tracking_code and shipped_at can be null. |
internal_notes |
object|null | Only with commerce.read.pii, otherwise null: {items, truncated}, the internal staff notes newest first, at most 50, each with id, body, author, author_type (staff, token or unknown) and created_at. Free text that may describe the customer. |
refunds |
array | Succeeded refunds only, at most 50, each with amount and created_at. |
returns |
array | Return requests, oldest first, at most 20, each with reference, type (withdrawal, return or defect), status (requested, received, refund_pending, refunded or rejected), requested_at, received_at and refunded_at. Never the reason or contact email. |
The payment state is derived from payment attempts and refunds: unpaid, paid, partially_refunded, refunded, failed, cancelled, expired or needs_review.
status is the order status handle. No match: not_found.
Customer identity, address details and tracking codes are masked unless the token has commerce.read.pii. shipping_address is null when the order has none; without the pii scope the keys postcode and street are absent, not null.
list_categories
The product category tree.
| Name | Type | Required | Description |
|---|---|---|---|
parent |
string | Optional | Category id or slug. Omit it for the top level. Unknown: not_found. |
depth |
integer | Optional | 1 to 3, default 2. |
Output. categories (nodes with id, slug, name, parent_id, product_count and children) and truncated.
product_count counts published products in the category and its subcategories. At most 500 nodes are returned; truncated is true when the tree was cut.
Use a category id or slug as collection in search_products.
get_sales_summary
Operational sales metrics for a date range. These are not accounting revenue and will not necessarily reconcile with finance reports.
| Name | Type | Required | Description |
|---|---|---|---|
from |
date | Required | YYYY-MM-DD, Europe/Amsterdam, inclusive. |
to |
date | Required | YYYY-MM-DD, Europe/Amsterdam, inclusive. Not before from; at most 366 days in total. |
group_by |
string | Optional | none (default), day, week (ISO, starting Monday) or month. |
| Field | Type | Description |
|---|---|---|
currency |
string | EUR. |
period |
object | from, to and timezone. |
orders_count |
integer | Orders placed in the period, by order date. Cancelled orders are excluded. |
gross_sales |
money | Sum of the tax-inclusive totals of the counted orders. |
refunded |
money | Succeeded refunds, counted by refund date. |
net_sales |
money | gross_sales minus refunded. Can be negative. |
average_order_value |
money | gross_sales divided by orders_count, rounded; 0 without orders. |
buckets |
array | Empty for none; otherwise one entry per day, week or month with start, orders_count, gross_sales, refunded and net_sales. |
definitions |
array of string | The rules of the metrics as text. |
Orders are counted by order date and refunds by refund date, so a refund can fall in a different period than its order. The output contains no customer data.
With group_by, buckets are contiguous and zero-filled, and the first bucket starts at from even when that is mid-week or mid-month.
Write tools
Forty-five tools change data. The first twelve change the product catalogue: product content, base price, stored stock, new products, product images, category placements and the category tree. Nine need commerce.write.products; the three category tree tools need commerce.write.collections. The write scopes are only issued together with commerce.read, see Scopes and masking.
| Tool | Scope | Purpose |
|---|---|---|
update_product |
commerce.write.products |
Edit name, description, status, brand and categories of one product. |
set_price |
commerce.write.products |
Set the base price of one variant, by SKU. |
set_stock |
commerce.write.products |
Set the stored stock quantity of one variant, by SKU. |
create_product |
commerce.write.products |
Create a draft product with one variant. |
attach_product_to_collection |
commerce.write.products |
Put one product in one category. |
detach_product_from_collection |
commerce.write.products |
Take one product out of one category. |
add_product_media |
commerce.write.products |
Add one image to a product from an https URL. |
remove_product_media |
commerce.write.products |
Remove one image from a product. |
set_primary_product_media |
commerce.write.products |
Make one image the main image of a product. |
create_collection |
commerce.write.collections |
Add a category to the category tree. |
update_collection |
commerce.write.collections |
Rename a category or set its description. |
move_collection |
commerce.write.collections |
Move a category within its tree. |
More tools
- Catalogue write tools: the reference lists
list_brands,list_labels,list_tax_classesandlist_properties, and the write toolsupdate_product_seo,change_product_slug,update_variant,set_product_properties,set_labels,set_variant_sale,end_variant_sale,set_price_breaks, the brand and label tools, and the featured product tools (commerce.write.products, featured productscommerce.write.collections). - Discount tools:
list_discounts,get_discount,create_discount,update_discount,deactivate_discountanddelete_discount(commerce.write.discounts). - Order tools:
confirm_offline_payment,cancel_unpaid_order,add_order_note,add_shipmentandupdate_shipment_tracking(commerce.write.orders). - Content tools:
list_pages,get_page,create_page,update_pageanddelete_page(commerce.write.content).
A write token can change the live shop
Changes take effect immediately, also on the storefront. There is no undo. Give write tokens only to clients that need them, and let a person confirm each write in the client. See Privacy and security: write tokens.
Common rules
- Same rules as the admin. Each tool runs the same catalogue action as the matching screen in the shop admin: the same validation, the same PIM rules and the same stored format. Only the authorisation (the token scope) and the attribution (the token instead of a staff member) differ.
- Recorded against the token. Every call that really changes something is recorded in the change history with the token's name, the tool, the subject and the old and new value of every changed field. Shop administrators see it per token (Change history, Wijzigingsgeschiedenis, on the API tokens page) and per product. A call that changes nothing records no change.
- All or nothing. A call is one database transaction together with its change-history entry: if the entry cannot be written, the change is rolled back.
- Result. Every result has
changed(falsewhen nothing differed) andchanges: per changed field{"old", "new"}, only for fields that really changed. Long text is cut to 200 characters there; the change history keeps the full value. - Retries. There are no idempotency keys (
add_shipmenthas its own requiredidempotency_key). Most tools set fields to the given values, so repeating the call changes nothing and a retry is safe.create_product,create_collectionandadd_product_mediaadd something on every call, andmove_collectionwithupordownmoves one more place per call: check with a read tool before you retry them. - Concurrent changes. A change of the same data in the admin or by another token waits for the call. If the data changed during the call, or another change keeps it locked for 5 seconds, the answer is
conflict: read again and retry. Writes are not conditional otherwise: when two clients set the same field, the last write wins, and both are in the change history. - PIM-managed data. On a product that is linked to the PIM, fields, images and category placements that the PIM manages are refused with
field_owned_by_pim, because the next import would overwrite them. Sending the value the product already has is not a change and is accepted. A product without a PIM link is fully editable. - Plain text. Names are reduced to plain text on one line and markup is removed from descriptions before they are stored. A blank name is
invalid_argument. - Rate limit. At most 30 write calls per token per minute, on top of the general limit of the token and shared with the REST API. Over it, the call does not run and answers
too_many_requests. See the write limit. - What is out of reach. No tool deletes a product, variant, price or category, no tool refunds money or cancels a paid order, and no tool changes customers. The removals are images, category placements, brands that no product uses, labels, discount codes that were never used, and CMS pages other than the home page.
Tool annotations
Each write tool advertises MCP tool annotations in tools/list, so a client can decide which calls need confirmation:
| Annotation | Value | Meaning |
|---|---|---|
readOnlyHint |
false for every write tool |
Every write tool changes data. |
destructiveHint |
true for remove_product_media, delete_brand, remove_brand_logo, delete_label, set_labels, set_product_properties, end_variant_sale, set_price_breaks, delete_discount, cancel_unpaid_order, update_page and delete_page |
They delete something, replace a whole list (an empty list wipes it), end planned sales, rewrite the blocks of a page, or cancel an order, which cannot be undone. |
idempotentHint |
false for create_product, create_collection, add_product_media, create_brand, create_label, set_brand_logo, create_discount, add_order_note, create_page, and for the moves (move_collection, move_label, move_featured_product_in_collection) |
These add or move something on every call, or refuse a repeat. All other write tools set values, so a repeat changes nothing. |
openWorldHint |
true for add_product_media, set_brand_logo, create_page, update_page, confirm_offline_payment and add_shipment |
The first four download the image URLs the client names. The last two send an e-mail to the customer. No other write tool makes an outbound request. |
Errors of the write tools
Write tools fail like read tools: a tools/call result with isError: true and a JSON code and message. See tool errors.
| Code | When |
|---|---|
invalid_argument |
Failed validation: an unknown argument, a value out of range, an unknown brand or category id in the input, a taken SKU, name, code or slug, a blank name, a refused image URL, or a category of the hidden PIM import tree. The message names the rule. |
not_found |
The product, SKU, image, category or target category of the call does not exist. |
field_owned_by_pim |
The product is linked to the PIM and the field, image or category placement belongs to the PIM: the next import would overwrite it. Change it in the PIM. |
conflict |
set_stock while an external inventory provider manages stock; create_product in a shop that gets its products from the PIM; an order, discount or page that is in a state the action does not allow (see the pages of those tools); update_page with an out-of-date expected_updated_at; or, for any write tool, the data changed during the call or another change of the same data kept it locked for 5 seconds. Read again and retry. |
too_many_requests |
The token is over its write limit of 30 write calls per minute: Too many write requests. Try again in a minute. The call did not run. |
internal_error |
An unexpected failure. The message is always An internal error occurred. |
forbidden_scope does not occur for write tools over MCP: without the scope the tool does not exist for the token, and a call answers JSON-RPC -32602.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "set_price",
"arguments": { "sku": "HAM-500", "amount_minor": 1595 }
}
}
update_product
Edit the content of one product. Scope commerce.write.products. At least one field besides id is required; a field that is not given is left alone.
| Name | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | Product id. |
name |
string | Optional | At most 255 characters, plain text (markup is removed). The Dutch product name. |
description |
string | Optional | At most 5000 characters, plain text (markup is removed). The Dutch product description. |
status |
string | Optional | draft hides the product from the storefront, published shows it. |
brand |
string|null | Optional | The name of an existing brand, case-insensitive, at most 191 characters. An unknown brand is invalid_argument. null clears the brand. |
collections |
array of integer | Optional | The complete list of category ids the product belongs to (see list_categories); categories not listed are removed. At most 50. An unknown id is invalid_argument. |
Output. The product as get_product returns it after the change, plus changed and changes.
Repeating the call changes nothing.
Errors. An unknown product is not_found. On a product linked to the PIM, a new name, description or brand is field_owned_by_pim; status and collections are always editable, because categories belong to the shop.
set_price
Set the base price (quantity 1) of one variant, found by SKU. Scope commerce.write.products.
| Name | Type | Required | Description |
|---|---|---|---|
sku |
string | Required | SKU of the variant, at most 64 characters. |
amount_minor |
integer | Required | Tax-inclusive price in cents, 0 to 100000000. For example 1999 for € 19,99. |
Output. sku, product_id, price (amount as money, tax_inclusive and tax_class), changed and changes (the old and new price as money objects).
Setting the current price again changes nothing.
On a product linked to the PIM the price becomes a manual price: later PIM imports keep it. An unknown SKU is not_found.
set_stock
Set the stored stock quantity of one variant, found by SKU, to an exact number. Scope commerce.write.products.
| Name | Type | Required | Description |
|---|---|---|---|
sku |
string | Required | SKU of the variant, at most 64 characters. |
quantity |
integer | Required | The new stock quantity, 0 to 1000000. |
Output. sku, product_id, availability (as an entry of check_sku_availability, after the change), changed and changes (stock with the old and new quantity).
Setting the current quantity again changes nothing.
- Only while the shop's own stock is authoritative. With an external inventory provider the call is
conflict, because the stored quantity would be ignored or overwritten. - On a product linked to the PIM the call is
field_owned_by_pim, because every PIM import overwrites its stock. The quantity already stored is accepted as a no-op. - The stock change is recorded in the shop's inventory history with the token name, and back-in-stock notifications to customers run as for a change in the admin.
- An unknown SKU is
not_found.
create_product
Create one product as a draft, with a single variant. Scope commerce.write.products.
A shop that gets its products from the PIM answers conflict: new products start in the PIM there.
| Name | Type | Required | Description |
|---|---|---|---|
name |
string | Required | At most 255 characters, plain text (markup is removed). |
sku |
string | Required | At most 64 characters. Must be new: it is compared, ignoring case, with every SKU that exists or ever existed in the shop. A taken SKU is invalid_argument. |
price_minor |
integer | Required | Tax-inclusive price in cents, 0 to 100000000. |
ean |
string|null | Optional | A valid GTIN: 8, 12, 13 or 14 digits with a correct check digit. Another product may have the same EAN. |
brand |
string|null | Optional | The name of an existing brand, case-insensitive, at most 191 characters. An unknown brand is invalid_argument. |
Output. The new product as get_product returns it (status draft), plus changed (true) and changes (the price as a money object).
The shop's default tax class is used and the URL is made from the name.
- Not idempotent: a repeat with the same SKU is
invalid_argument, because the SKU is taken. Check withcheck_sku_availabilityorsearch_productsbefore you retry. - Fill in the rest afterwards: description, categories and status with
update_product, categories also withattach_product_to_collection, and images withadd_product_media. Publish withupdate_productstatuspublished.
attach_product_to_collection and detach_product_from_collection
Put one product in one category, at the end of its regular order (never as a featured product), or take it out. Scope commerce.write.products.
update_product with collections makes the same change for all categories at once.
| Name | Type | Required | Description |
|---|---|---|---|
collection_id |
integer | Required | Category id (see list_categories). |
product_id |
integer | Required | Product id. |
Output. product_id, collection (id, slug, name, parent_id, position, description), in_collection (whether the product is in the category after the call), changed and changes.
- Attaching a product that is in the category already, or detaching one that is not, changes nothing (
changed: false). - Detaching a placement that the PIM import made is
field_owned_by_pim: the next import would restore it. - A category of the hidden PIM import tree is
invalid_argument. An unknown product or category isnot_found.
add_product_media
Add one image to a product from a URL. Scope commerce.write.products. The client sends a URL, not the image bytes, because a request body is at most 64 KiB.
Allowed on products linked to the PIM.
| Name | Type | Required | Description |
|---|---|---|---|
product_id |
integer | Required | Product id. |
image_url |
string | Required | An https URL of the image itself, at most 2048 characters. See the URL rules below. |
alt |
string | Required | Alternative text that describes the image, at most 255 characters. Whitespace is collapsed. |
Image URL rules
httpsonly. No user name or password in the URL, and no host name that ends with a dot.- The host must resolve to public internet addresses only. Private, loopback, link-local and other internal or reserved addresses are refused, also when only one of the host's addresses is not public.
- Redirects are never followed: a
3xxanswer is refused, so give the final URL of the image itself. Any other answer outside2xxis refused too. - At most 10 MB. The connection must open within 5 seconds and the download must finish within 15 seconds.
- The format is taken from the content, never from the URL or the
Content-Typeheader. Only JPEG, PNG, WebP, GIF and AVIF are accepted. SVG (also when served asimage/png), HTML and other content is refused. - At most 8000 pixels on a side and 40 megapixels.
Every refusal is invalid_argument with a message that names the rule, for example The image URL redirects; redirects are not followed, give the final URL.
The image is then stored exactly like an upload in the admin:
- JPEG, PNG, WebP and AVIF are re-encoded as WebP and scaled down to the shop's maximum product image size. Re-encoding removes metadata such as EXIF and GPS location. GIF images are stored as received.
- The file gets a name made from the product name; the file name in the URL is not used.
- The first image of a product without a main image becomes the main image.
| Field | Type | Description |
|---|---|---|
product_id |
integer | The product. |
media_id |
integer | The image this call was about (for add_product_media the new image). |
images |
array | Every image of the product after the call, main image first, each {"id", "url", "alt", "primary"}. alt can be null. |
changed |
boolean | false when nothing changed. |
changes |
object | Per changed field {"old", "new"}: image, alt and primary, with image file names as values. |
Not idempotent: every call adds an image. Check the product's images before you retry.
remove_product_media
Remove one image from a product, with its file and sizes. Scope commerce.write.products. This cannot be undone.
| Name | Type | Required | Description |
|---|---|---|---|
product_id |
integer | Required | Product id. |
media_id |
integer | Required | Image id, from the images of get_product or of a media write tool. |
- Output. As
add_product_media, with the remaining images. - When the main image is removed, the next image in gallery order becomes the main image.
- An image that the PIM manages is
field_owned_by_pim: the next import would bring it back. - An image that is not one of the product's is
not_found, so a repeat of a successful call answersnot_found. - It is the only tool that advertises
destructiveHint: true.
set_primary_product_media
Make one image the main image of a product; every other image stops being the main image. Scope commerce.write.products. Allowed for images the PIM manages too.
| Name | Type | Required | Description |
|---|---|---|---|
product_id |
integer | Required | Product id. |
media_id |
integer | Required | Image id, from the images of get_product or of a media write tool. |
- Output. As
add_product_media. - Repeating the call changes nothing.
- An image that is not one of the product's is
not_found.conflictmeans the main image changed during the call.
create_collection
Add a category to the category tree. Scope commerce.write.collections.
| Name | Type | Required | Description |
|---|---|---|---|
name |
string | Required | At most 255 characters, plain text (markup is removed). |
parent_id |
integer|null | Optional | Id of the parent category. Omit it for a top-level category. |
- Without
parent_idthe category becomes the last top-level category of the tree thatlist_categoriesshows; with it, the last child of that parent. - The storefront address is made from the name.
- A parent in the hidden PIM import tree is
invalid_argument; an unknown parent isnot_found. - Not idempotent: every call adds a category. Check
list_categoriesbefore you retry.
| Field | Type | Description |
|---|---|---|
collection |
object | id, slug, name, parent_id, position (among its siblings, from 0) and description (plain text). |
changed |
boolean | false when nothing changed. |
changes |
object | Per changed field {"old", "new"}. Long text is cut. |
update_collection
Rename a category and/or set its description. Scope commerce.write.collections. At least one of name and description is required; a field that is not given is left alone.
| Name | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | Category id (see list_categories). |
name |
string | Optional | At most 255 characters, plain text (markup is removed). |
description |
string|null | Optional | At most 5000 characters, plain text: markup is removed, a blank line starts a new paragraph and a single line break stays a line break. Empty or null removes the description. |
- Output. As
create_collection, withcollection.descriptionas plain text. The description is stored as HTML paragraphs, the way the admin editor stores it, sochanges.descriptionshows the stored HTML. - Repeating the call changes nothing.
- A category of the hidden PIM import tree is
invalid_argument; an unknown category isnot_found;conflictmeans someone changed it during the call.
{
"collection": {
"id": 12,
"slug": "gereedschap",
"name": "Handgereedschap",
"parent_id": null,
"position": 0,
"description": ""
},
"changed": true,
"changes": {
"name": { "old": "Gereedschap", "new": "Handgereedschap" }
}
}
move_collection
Move a category within its tree. Scope commerce.write.collections.
| Name | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | Category id (see list_categories). |
operation |
string | Required | up or down (one place among its siblings; nothing changes on the first or last one), make_root (to the end of the top level) or into (the last child of target_id). |
target_id |
integer|null | Optional | Required for into, not allowed otherwise. The new parent, a category of the same tree. |
- Output. As
create_collection;changeshasparent_idandpositionas far as they changed. - Moving a category into itself, into one of its own subcategories or into another tree is
invalid_argument. An unknown category or target isnot_found.conflictmeans someone else moved it during the call. upanddownare not idempotent: each call moves one more place.