Customer products API
REST endpoints for customer products in SKUFlow: 7 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
| Operation | Endpoint | Risk |
|---|---|---|
| List customer products | GET /organizations/{organizationId}/customer-products | read |
| Add a product to a customer's products | POST /organizations/{organizationId}/customer-products | write |
| A customer product | GET /organizations/{organizationId}/customer-products/{customerProductId} | read |
| Rename, note or archive a customer product | PATCH /organizations/{organizationId}/customer-products/{customerProductId} | write |
| Delete a customer product | DELETE /organizations/{organizationId}/customer-products/{customerProductId} | sensitive |
| Change a customer product's prices | POST /organizations/{organizationId}/customer-products/{customerProductId}/prices | sensitive |
| Change many customer products' prices | POST /organizations/{organizationId}/customer-products/prices | sensitive |
List customer products
GET /organizations/{organizationId}/customer-products
A customer's decorated products (or the business's, filtered by product or design) with their customer price, store price, size upcharges, picture and the stores selling each (with where each store's price comes from). Archived ones only with includeArchived. Read-only; call before quoting or making a store for a customer.
| Permission | products.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | customerProducts_list (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerId | query | string | No | Only this customer's products (GET /customers). |
productId | query | string | No | |
designId | query | string | No | |
includeArchived | query | boolean or enum | No | |
query | query | string | No | Search names, styles and designs. Up to 200 characters. |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
total | integer | |
items | array of object | |
items[].id | string | |
items[].customerId | string | |
items[].customer | object | |
items[].customer.id | string | |
items[].customer.name | string | |
items[].productId | string | |
items[].designId | string or null | |
items[].name | string or null | |
items[].displayName | string | The name, else the product and design names. |
items[].customerPrice | object or null | The customer price's rule; null = the normal pricing. |
items[].customerPrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
items[].customerPrice.cents | integer or null | |
items[].customerPrice.markupPercent | number or null | |
items[].customerPrice.roundTo99 | boolean | |
items[].customerPrice.decorationCents | integer | |
items[].storePrice | object or null | The store price's rule; null = each store's own pricing. |
items[].storePrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
items[].storePrice.cents | integer or null | |
items[].storePrice.markupPercent | number or null | |
items[].storePrice.roundTo99 | boolean | |
items[].storePrice.decorationCents | integer | |
items[].customerPriceCents | integer or null | The lowest customer price now. |
items[].storePriceCents | integer or null | The lowest store price now. |
items[].sizeUpchargeCents | object | |
items[].sizePrices | array of object | Each size's customer and store price now and (with costing.read) the cost they are based on. |
items[].sizePrices[].size | string or null | |
items[].sizePrices[].customerPriceCents | integer or null | Integer cents. |
items[].sizePrices[].storePriceCents | integer or null | Integer cents. |
items[].notes | string or null | |
items[].archived | boolean | |
items[].image | string or null | The design's first mockup, else the product's picture (signed, short-lived). |
items[].product | object | |
items[].product.id | string | |
items[].product.name | string | |
items[].product.sizes | array of string | |
items[].design | object or null | |
items[].design.id | string | |
items[].design.name | string | |
items[].catalogPriceCents | integer or null | The product's normal lowest price before decoration, for comparison. |
items[].stores | array of object | The stores selling it and where their price comes from. |
items[].stores[].storeId | string | |
items[].stores[].storeName | string | |
items[].stores[].storeStatus | enum | One of DRAFT, OPEN, CLOSED. |
items[].stores[].storeProductId | string | |
items[].stores[].active | boolean | |
items[].stores[].priceSource | enum | CUSTOMER_PRODUCT: the store item follows this store price; OVERRIDE: it has its own pricing; STORE: it uses the store's pricing (this product has no store price). One of CUSTOMER_PRODUCT, OVERRIDE, STORE. |
items[].stores[].priceFromCents | integer or null | The lowest price shoppers see in that store. |
items[].stores[].priceToCents | integer or null | Integer cents. |
Add a product to a customer's products
POST /organizations/{organizationId}/customer-products
Links a catalog product (GET /products) and optionally its design (GET /designs?productId=&customerId=: the business's own or this customer's) to a customer, with optional prices. One per customer, product and design (409 when it exists: change that one). Nothing is sent to anyone; stores pick it up when it is added to them (POST /stores/{storeId}/products with customerProductIds).
| Permission | products.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | customerProducts_create (toolset stores) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | The customer (GET /customers). |
productId | string | Yes | The catalog product (GET /products). |
designId | string or null | No | Its design (GET /designs?productId=); null = the plain product. |
name | string or null | No | Shown instead of the product and design names. Up to 200 characters. |
notes | string or null | No | Up to 5000 characters. |
customerPrice | object or null | No | What the customer pays per piece when they order directly: new quote lines and hand-typed order lines for this product and design default to it (plus the size's upcharge; a markup is read when the line is made). Null = the normal pricing (decoration matrix). |
customerPrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
customerPrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
customerPrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
customerPrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
storePrice | object or null | No | What shoppers pay per piece in the stores the business runs for this customer: every linked store item follows it (plus the size's upcharge, worked out at each view and checkout) unless that item has its own pricing. Null = each store's own pricing. |
storePrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
storePrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
storePrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
storePrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
customerPriceCents | integer or null | No | Shorthand for a FIXED customer price (ignored when customerPrice is given). 0–10000000. |
storePriceCents | integer or null | No | Shorthand for a FIXED store price (ignored when storePrice is given). 0–10000000. |
sizeUpchargeCents | object | No | Extra per size on top of both prices, in cents, e.g. { "2XL": 200, "3XL": 300 }; sizes not listed add nothing. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customerId":"customer_id","productId":"product_id"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
productId | string | |
designId | string or null | |
name | string or null | |
displayName | string | The name, else the product and design names. |
customerPrice | object or null | The customer price's rule; null = the normal pricing. |
customerPrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | |
customerPrice.markupPercent | number or null | |
customerPrice.roundTo99 | boolean | |
customerPrice.decorationCents | integer | |
storePrice | object or null | The store price's rule; null = each store's own pricing. |
storePrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | |
storePrice.markupPercent | number or null | |
storePrice.roundTo99 | boolean | |
storePrice.decorationCents | integer | |
customerPriceCents | integer or null | The lowest customer price now. |
storePriceCents | integer or null | The lowest store price now. |
sizeUpchargeCents | object | |
sizePrices | array of object | Each size's customer and store price now and (with costing.read) the cost they are based on. |
sizePrices[].size | string or null | |
sizePrices[].customerPriceCents | integer or null | Integer cents. |
sizePrices[].storePriceCents | integer or null | Integer cents. |
notes | string or null | |
archived | boolean | |
image | string or null | The design's first mockup, else the product's picture (signed, short-lived). |
product | object | |
product.id | string | |
product.name | string | |
product.sizes | array of string | |
design | object or null | |
design.id | string | |
design.name | string | |
catalogPriceCents | integer or null | The product's normal lowest price before decoration, for comparison. |
stores | array of object | The stores selling it and where their price comes from. |
stores[].storeId | string | |
stores[].storeName | string | |
stores[].storeStatus | enum | One of DRAFT, OPEN, CLOSED. |
stores[].storeProductId | string | |
stores[].active | boolean | |
stores[].priceSource | enum | CUSTOMER_PRODUCT: the store item follows this store price; OVERRIDE: it has its own pricing; STORE: it uses the store's pricing (this product has no store price). One of CUSTOMER_PRODUCT, OVERRIDE, STORE. |
stores[].priceFromCents | integer or null | The lowest price shoppers see in that store. |
stores[].priceToCents | integer or null | Integer cents. |
A customer product
GET /organizations/{organizationId}/customer-products/{customerProductId}
One customer product with its prices, size upcharges and the stores selling it. Read-only.
| Permission | products.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | customerProducts_get (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerProductId | path | string | Yes | The customer product (GET /customer-products). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products/{customerProductId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
productId | string | |
designId | string or null | |
name | string or null | |
displayName | string | The name, else the product and design names. |
customerPrice | object or null | The customer price's rule; null = the normal pricing. |
customerPrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | |
customerPrice.markupPercent | number or null | |
customerPrice.roundTo99 | boolean | |
customerPrice.decorationCents | integer | |
storePrice | object or null | The store price's rule; null = each store's own pricing. |
storePrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | |
storePrice.markupPercent | number or null | |
storePrice.roundTo99 | boolean | |
storePrice.decorationCents | integer | |
customerPriceCents | integer or null | The lowest customer price now. |
storePriceCents | integer or null | The lowest store price now. |
sizeUpchargeCents | object | |
sizePrices | array of object | Each size's customer and store price now and (with costing.read) the cost they are based on. |
sizePrices[].size | string or null | |
sizePrices[].customerPriceCents | integer or null | Integer cents. |
sizePrices[].storePriceCents | integer or null | Integer cents. |
notes | string or null | |
archived | boolean | |
image | string or null | The design's first mockup, else the product's picture (signed, short-lived). |
product | object | |
product.id | string | |
product.name | string | |
product.sizes | array of string | |
design | object or null | |
design.id | string | |
design.name | string | |
catalogPriceCents | integer or null | The product's normal lowest price before decoration, for comparison. |
stores | array of object | The stores selling it and where their price comes from. |
stores[].storeId | string | |
stores[].storeName | string | |
stores[].storeStatus | enum | One of DRAFT, OPEN, CLOSED. |
stores[].storeProductId | string | |
stores[].active | boolean | |
stores[].priceSource | enum | CUSTOMER_PRODUCT: the store item follows this store price; OVERRIDE: it has its own pricing; STORE: it uses the store's pricing (this product has no store price). One of CUSTOMER_PRODUCT, OVERRIDE, STORE. |
stores[].priceFromCents | integer or null | The lowest price shoppers see in that store. |
stores[].priceToCents | integer or null | Integer cents. |
Rename, note or archive a customer product
PATCH /organizations/{organizationId}/customer-products/{customerProductId}
Changes the name, notes or archived. Archived products leave the customer's list, new stores and quote defaults; stores already selling one keep their prices. Prices change with POST /customer-products/{customerProductId}/prices.
| Permission | products.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | customerProducts_update (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerProductId | path | string | Yes | The customer product (GET /customer-products). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string or null | No | Up to 200 characters. |
notes | string or null | No | Up to 5000 characters. |
archived | boolean | No |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products/{customerProductId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","notes":"string","archived":true}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
productId | string | |
designId | string or null | |
name | string or null | |
displayName | string | The name, else the product and design names. |
customerPrice | object or null | The customer price's rule; null = the normal pricing. |
customerPrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | |
customerPrice.markupPercent | number or null | |
customerPrice.roundTo99 | boolean | |
customerPrice.decorationCents | integer | |
storePrice | object or null | The store price's rule; null = each store's own pricing. |
storePrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | |
storePrice.markupPercent | number or null | |
storePrice.roundTo99 | boolean | |
storePrice.decorationCents | integer | |
customerPriceCents | integer or null | The lowest customer price now. |
storePriceCents | integer or null | The lowest store price now. |
sizeUpchargeCents | object | |
sizePrices | array of object | Each size's customer and store price now and (with costing.read) the cost they are based on. |
sizePrices[].size | string or null | |
sizePrices[].customerPriceCents | integer or null | Integer cents. |
sizePrices[].storePriceCents | integer or null | Integer cents. |
notes | string or null | |
archived | boolean | |
image | string or null | The design's first mockup, else the product's picture (signed, short-lived). |
product | object | |
product.id | string | |
product.name | string | |
product.sizes | array of string | |
design | object or null | |
design.id | string | |
design.name | string | |
catalogPriceCents | integer or null | The product's normal lowest price before decoration, for comparison. |
stores | array of object | The stores selling it and where their price comes from. |
stores[].storeId | string | |
stores[].storeName | string | |
stores[].storeStatus | enum | One of DRAFT, OPEN, CLOSED. |
stores[].storeProductId | string | |
stores[].active | boolean | |
stores[].priceSource | enum | CUSTOMER_PRODUCT: the store item follows this store price; OVERRIDE: it has its own pricing; STORE: it uses the store's pricing (this product has no store price). One of CUSTOMER_PRODUCT, OVERRIDE, STORE. |
stores[].priceFromCents | integer or null | The lowest price shoppers see in that store. |
stores[].priceToCents | integer or null | Integer cents. |
Delete a customer product
DELETE /organizations/{organizationId}/customer-products/{customerProductId}
Destructive: removes it from the customer's products. Store items selling it keep today's price as their own and stay in their stores; quotes and orders keep their lines. To hide it instead, PATCH archived: true.
| Permission | products.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | customerProducts_delete (toolset stores) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerProductId | path | string | Yes | The customer product (GET /customer-products). |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products/{customerProductId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
Change a customer product's prices
POST /organizations/{organizationId}/customer-products/{customerProductId}/prices
Customer-visible: sets the customer price, the store price (each FIXED, COST + markup, MARKUP over the catalog price, or CATALOG) and/or the size upcharges (fields left out stay; null clears a price). Every store item that follows this product's store price shows the new price to shoppers at once (open stores and carts; a shopper mid-checkout is asked to confirm the new total). Saved quotes and orders keep their prices; new quote lines use the new customer price. Answers the product and how many store items were re-priced.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | customerProducts_setPrices (toolset stores) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerProductId | path | string | Yes | The customer product (GET /customer-products). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerPrice | object or null | No | What the customer pays per piece when they order directly: new quote lines and hand-typed order lines for this product and design default to it (plus the size's upcharge; a markup is read when the line is made). Null = the normal pricing (decoration matrix). |
customerPrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
customerPrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
customerPrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
customerPrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
storePrice | object or null | No | What shoppers pay per piece in the stores the business runs for this customer: every linked store item follows it (plus the size's upcharge, worked out at each view and checkout) unless that item has its own pricing. Null = each store's own pricing. |
storePrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
storePrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
storePrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
storePrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
customerPriceCents | integer or null | No | Shorthand for a FIXED customer price (ignored when customerPrice is given). 0–10000000. |
storePriceCents | integer or null | No | Shorthand for a FIXED store price (ignored when storePrice is given). 0–10000000. |
sizeUpchargeCents | object | No | Extra per size on top of both prices, in cents, e.g. { "2XL": 200, "3XL": 300 }; sizes not listed add nothing. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products/{customerProductId}/prices" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customerPrice":{"mode":"FIXED"},"storePrice":{"mode":"FIXED"},"customerPriceCents":12500}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
customerId | string | |
customer | object | |
customer.id | string | |
customer.name | string | |
productId | string | |
designId | string or null | |
name | string or null | |
displayName | string | The name, else the product and design names. |
customerPrice | object or null | The customer price's rule; null = the normal pricing. |
customerPrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
customerPrice.cents | integer or null | |
customerPrice.markupPercent | number or null | |
customerPrice.roundTo99 | boolean | |
customerPrice.decorationCents | integer | |
storePrice | object or null | The store price's rule; null = each store's own pricing. |
storePrice.mode | enum | One of FIXED, CATALOG, MARKUP, COST. |
storePrice.cents | integer or null | |
storePrice.markupPercent | number or null | |
storePrice.roundTo99 | boolean | |
storePrice.decorationCents | integer | |
customerPriceCents | integer or null | The lowest customer price now. |
storePriceCents | integer or null | The lowest store price now. |
sizeUpchargeCents | object | |
sizePrices | array of object | Each size's customer and store price now and (with costing.read) the cost they are based on. |
sizePrices[].size | string or null | |
sizePrices[].customerPriceCents | integer or null | Integer cents. |
sizePrices[].storePriceCents | integer or null | Integer cents. |
notes | string or null | |
archived | boolean | |
image | string or null | The design's first mockup, else the product's picture (signed, short-lived). |
product | object | |
product.id | string | |
product.name | string | |
product.sizes | array of string | |
design | object or null | |
design.id | string | |
design.name | string | |
catalogPriceCents | integer or null | The product's normal lowest price before decoration, for comparison. |
stores | array of object | The stores selling it and where their price comes from. |
stores[].storeId | string | |
stores[].storeName | string | |
stores[].storeStatus | enum | One of DRAFT, OPEN, CLOSED. |
stores[].storeProductId | string | |
stores[].active | boolean | |
stores[].priceSource | enum | CUSTOMER_PRODUCT: the store item follows this store price; OVERRIDE: it has its own pricing; STORE: it uses the store's pricing (this product has no store price). One of CUSTOMER_PRODUCT, OVERRIDE, STORE. |
stores[].priceFromCents | integer or null | The lowest price shoppers see in that store. |
stores[].priceToCents | integer or null | Integer cents. |
repriced | object | Store items (and stores) that now show the new store price. |
repriced.storeItems | integer | |
repriced.stores | integer |
Change many customer products' prices
POST /organizations/{organizationId}/customer-products/prices
Customer-visible: in one step, either sets prices on the listed customer products (items) or moves one customer's prices by a percentage (adjust: CUSTOMER, STORE or BOTH prices, only those already set; a FIXED price moves by the percentage, a markup price gets its markup raised so its price before decoration moves by it and it keeps following costs; optionally rounded up to .99 and limited to some products). Following store items show the new store prices at once. Answers how many products changed and how many store items were re-priced.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | customerProducts_bulkSetPrices (toolset stores) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
items | array of object | No | Up to 300 items. |
items[].customerProductId | string | Yes | |
items[].customerPrice | object or null | No | What the customer pays per piece when they order directly: new quote lines and hand-typed order lines for this product and design default to it (plus the size's upcharge; a markup is read when the line is made). Null = the normal pricing (decoration matrix). |
items[].customerPrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
items[].customerPrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
items[].customerPrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
items[].customerPrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
items[].customerPrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
items[].storePrice | object or null | No | What shoppers pay per piece in the stores the business runs for this customer: every linked store item follows it (plus the size's upcharge, worked out at each view and checkout) unless that item has its own pricing. Null = each store's own pricing. |
items[].storePrice.mode | enum | Yes | FIXED (cents per piece, all in), COST (the variant's current cost + markupPercent, plus decorationCents), MARKUP (the variant's catalog price + markupPercent, plus decorationCents: the store MARKUP rule) or CATALOG (the catalog price plus decorationCents). Worked out when used from current figures, so cost and catalog prices that change with supplier syncs move it. One of FIXED, CATALOG, MARKUP, COST. |
items[].storePrice.cents | integer or null | No | Fixed: the price per piece. 0–10000000. |
items[].storePrice.markupPercent | number or null | No | COST / MARKUP: percent over the cost / the catalog price (e.g. 80). -90–1000. |
items[].storePrice.roundTo99 | boolean | No | COST / MARKUP / CATALOG: round up to .99. |
items[].storePrice.decorationCents | integer | No | COST / MARKUP / CATALOG: the decoration added per piece. 0–10000000. |
items[].customerPriceCents | integer or null | No | Shorthand for a FIXED customer price (ignored when customerPrice is given). 0–10000000. |
items[].storePriceCents | integer or null | No | Shorthand for a FIXED store price (ignored when storePrice is given). 0–10000000. |
items[].sizeUpchargeCents | object | No | Extra per size on top of both prices, in cents, e.g. { "2XL": 200, "3XL": 300 }; sizes not listed add nothing. |
adjust | object | No | |
adjust.customerId | string | Yes | Whose prices to move (GET /customers). |
adjust.percent | number | Yes | e.g. 5 raises by 5%, -10 lowers by 10%. -90–1000. |
adjust.prices | enum | Yes | One of CUSTOMER, STORE, BOTH. |
adjust.roundTo99 | boolean | No | Round each new price up to .99. |
adjust.customerProductIds | array of string | No | Only these of the customer's products (default: all active ones). Up to 300 items. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/customer-products/prices" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"items":[{"customerProductId":"customerProduct_id"}],"adjust":{"customerId":"customer_id","percent":1,"prices":"CUSTOMER"}}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
changed | integer | |
repriced | object | Store items (and stores) that now show the new store price. |
repriced.storeItems | integer | |
repriced.stores | integer |