Catalog resources
Organize products with categories, brands, tax classes, discounts, and vehicle fitment.
These resources complement the product API. Administrative writes require an authorized admin session or an explicitly supported token scope.
Categories
| Method | Path | Result |
|---|---|---|
GET | /api/admin/categories | categories, including productCount |
POST | /api/admin/categories | Created category |
PATCH | /api/admin/categories/:id | Updated category |
DELETE | /api/admin/categories/:id | id and deleted |
Creation requires name; optional fields are slug, parent_id, position, is_visible, and icon. Slugs are normalized and must be unique within the relevant shop scope. The list is not paginated.
{
"name": "Workshop clothing",
"slug": "workshop-clothing",
"is_visible": true
}
Token reads use catalog:read. Creation and updates use catalog:write; token deletion goes through the write-approval flow.
Brands
Use GET and POST /api/admin/brands, and PATCH or DELETE /api/admin/brands/:id. The public read route is /api/brands. Token access follows the catalog read/write scopes and deletion rules.
Suppliers
Use GET /api/admin/suppliers to list suppliers and GET /api/admin/suppliers/:id to inspect one. Create with POST /api/admin/suppliers and update with PUT /api/admin/suppliers/:id, not PATCH. Supplier IDs can be assigned to products and purchase orders.
Tax classes
GET /api/tax-classes requires an admin or partner session and returns tax_classes. Creation, updates, and deletion use /api/admin/tax-classes and /api/admin/tax-classes/:id with POST, PATCH, and DELETE respectively.
The create body requires name and rate; is_default is optional. A tax rate is a fraction: 0.20 means 20%.
{
"name": "Standard VAT",
"rate": 0.20,
"is_default": true
}
The current token allowlist mentions /api/admin/tax-classes for reads, but the implemented GET route is /api/tax-classes. Use a session for this route; catalog:read does not currently match the implemented path.
Discounts
Use an admin session for these endpoints:
| Method | Path | Purpose |
|---|---|---|
GET | /api/admin/discounts | Search codes with q, limit, and offset |
POST | /api/admin/discounts | Create a code |
PATCH | /api/admin/discounts/:id | Update a code |
DELETE | /api/admin/discounts/:id | Delete a code |
POST | /api/store/discounts/validate | Validate a code in the storefront flow |
The create body requires a code of 2–40 characters and a type. For percent, value is 1–100: 10 means 10%. For fixed, value is integer cents. For free_shipping, use 0.
{
"code": "WELCOME10",
"type": "percent",
"value": 10,
"active": true,
"max_uses_per_user": 1
}
Optional controls include min_order_cents, usage limits, starts_at, expires_at, channel_ids, and account/newsletter requirements. An empty channel list applies to all channels. Final eligibility and totals are evaluated by the checkout pricing flow.
Vehicle fitment
Vehicle data forms a make → model → year-group hierarchy:
| Method | Path | Purpose |
|---|---|---|
GET | /api/vehicle-makes | List makes |
GET | /api/vehicle-makes/:makeId/models | List models |
GET | /api/vehicle-models/:modelId/year-groups | List year groups |
GET | /api/admin/products/:id/fitment | Read a product's assignments |
POST | /api/admin/products/:id/fitment | Add an assignment |
PUT | /api/admin/products/:id/fitment | Replace assignments |
The lookup routes are allowed for catalog:read tokens; the write policy separately permits selected hierarchy and assignment operations. Product attributes use GET /api/products/:id/attributes, POST /api/admin/products/:id/attributes, and DELETE /api/admin/attributes/:attrId.
The backend path allowlist matters: the split public shop backend does not expose /api/vehicle*. Use a backend that serves these routes for your integration.
Found something unclear? Let us know