Products API
REST endpoints for products in SKUFlow: 15 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 products | GET /organizations/{organizationId}/products | read |
| Add a product by hand | POST /organizations/{organizationId}/products | write |
| A product | GET /organizations/{organizationId}/products/{productId} | read |
| Change a product | PATCH /organizations/{organizationId}/products/{productId} | write |
| Delete a product | DELETE /organizations/{organizationId}/products/{productId} | sensitive |
| Refresh from the supplier | POST /organizations/{organizationId}/products/{productId}/refresh | write |
| Add a product picture | POST /organizations/{organizationId}/products/{productId}/images | write |
| Change a product picture | PATCH /organizations/{organizationId}/products/{productId}/images/{imageId} | write |
| Delete a product picture | DELETE /organizations/{organizationId}/products/{productId}/images/{imageId} | sensitive |
| Set large-format finishing | POST /organizations/{organizationId}/products/{productId}/finishing-options | write |
| Price a large-format piece | GET /organizations/{organizationId}/products/{productId}/large-format-price | read |
| Add a variant | POST /organizations/{organizationId}/products/{productId}/variants | write |
| Change a variant | PATCH /organizations/{organizationId}/products/{productId}/variants/{variantId} | write |
| Delete a variant | DELETE /organizations/{organizationId}/products/{productId}/variants/{variantId} | sensitive |
| Change several variants | POST /organizations/{organizationId}/products/{productId}/variants/bulk | write |
List products
GET /organizations/{organizationId}/products
The business's products with their main picture, price range, variant and colour counts and supplier stock. Filter by kind, status (ACTIVE by default), brand, category or supplier connection; query searches names, style numbers, brands, tags and SKUs. Read-only.
| Permission | products.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | products_list (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
query | query | string | No | Search names, style numbers, brands, tags and SKUs. Up to 200 characters. |
kind | query | enum | No | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
status | query | enum | No | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
brand | query | string | No | Up to 200 characters. |
category | query | string | No | Up to 200 characters. |
supplierConnectionId | query | string | No | Only products imported from this connection. |
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/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[].name | string | |
items[].slug | string | URL segment, unique in the business (stores use it). |
items[].brand | string or null | |
items[].styleNumber | string or null | |
items[].description | string or null | |
items[].category | string or null | |
items[].tags | array of string | |
items[].kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
items[].taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
items[].status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
items[].source | enum | One of SUPPLIER, MANUAL. |
items[].supplierConnectionId | string or null | |
items[].supplierStyleId | string or null | |
items[].overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
items[].pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
items[].baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
items[].basePriceCents | integer | The cheapest active variant's price. |
items[].minWidthIn | number or null | |
items[].maxWidthIn | number or null | |
items[].minHeightIn | number or null | |
items[].maxHeightIn | number or null | |
items[].minChargeCents | integer or null | |
items[].lastSupplierSyncAt | string (date-time) or null | |
items[].createdAt | string (date-time) | |
items[].updatedAt | string (date-time) | |
items[].supplierConnection | object or null | |
items[].supplierConnection.id | string | |
items[].supplierConnection.displayName | string | |
items[].supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
items[].image | object or null | |
items[].image.id | string | |
items[].image.colorName | string or null | |
items[].image.view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
items[].image.status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
items[].image.isPrimary | boolean | |
items[].image.sortOrder | integer | |
items[].image.sourceUrl | string or null | |
items[].image.url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
items[].variantCount | integer | |
items[].colorCount | integer | |
items[].priceFromCents | integer or null | |
items[].priceToCents | integer or null | |
items[].supplierStock | integer or null | |
brands | array of string | Every brand in the catalog, for the filter. |
Add a product by hand
POST /organizations/{organizationId}/products
Creates a product that is not from a supplier, with its variants (colour × size; one plain variant when none are given) and, for LARGE_FORMAT, its materials (variants with material and a cost or price per square foot) and finishing options. Prices follow the pricing rule unless priceOverrideCents is set. To add supplier products use POST /suppliers/{supplierConnectionId}/catalog/import instead.
| 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 | products_create (toolset catalog) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 500 characters. |
slug | string or null | No | URL segment (made from the name when blank). Up to 80 characters. |
brand | string or null | No | Up to 200 characters. |
styleNumber | string or null | No | Up to 100 characters. |
description | string or null | No | |
category | string or null | No | Up to 200 characters. |
tags | array of string | No | Up to 50 items. |
kind | enum | No | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | No | How its lines are taxed: CLOTHING (some states tax apparel less), STANDARD or EXEMPT; null = by kind (APPAREL is CLOTHING). One of STANDARD, CLOTHING, EXEMPT. |
status | enum | No | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
pricingRuleId | string or null | No | From GET /pricing-rules; null follows the matching rule. |
decorationAreas | array of object | No | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | Yes | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | Yes | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | Yes | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | No | At most 1000. |
decorationAreas[].maxHeightIn | number or null | No | At most 1000. |
decorationAreas[].x | number or null | No | 0–1. |
decorationAreas[].y | number or null | No | 0–1. |
decorationAreas[].width | number or null | No | 0–1. |
decorationAreas[].height | number or null | No | 0–1. |
decorationAreas[].methods | array of enum | No | The decoration methods that suit this area (empty = any). Up to 10 items. |
minWidthIn | number or null | No | At most 10000. |
maxWidthIn | number or null | No | At most 10000. |
minHeightIn | number or null | No | At most 10000. |
maxHeightIn | number or null | No | At most 10000. |
minChargeCents | integer or null | No | Large format: the least one piece costs. 0–100000000. |
variants | array of object | No | Up to 500 items. |
variants[].colorName | string or null | No | Up to 200 characters. |
variants[].colorHex | string or null | No | |
variants[].size | string or null | No | Up to 50 characters. |
variants[].material | string or null | No | Large format: the material, e.g. 13 oz vinyl banner. Up to 200 characters. |
variants[].sku | string or null | No | Up to 100 characters. |
variants[].gtin | string or null | No | Up to 50 characters. |
variants[].costCents | integer | No | Unit cost in cents (manual products; imported variants take the supplier's). 0–100000000. |
variants[].priceOverrideCents | integer or null | No | Your own price in cents; null follows the pricing rule. 0–100000000. |
variants[].costPerSqFtCents | integer or null | No | Large format: the material's cost per square foot. 0–100000000. |
variants[].pricePerSqFtCents | integer or null | No | Large format: your price per square foot; null follows the rule. 0–100000000. |
variants[].weightGrams | integer or null | No | 0–1000000. |
variants[].active | boolean | No | |
variants[].sortOrder | integer | No | 0–100000. |
finishingOptions | array of object | No | Up to 30 items. |
finishingOptions[].id | string or null | No | An existing option's id to keep it (from the product); omit for a new one. |
finishingOptions[].name | string | Yes | Up to 200 characters. |
finishingOptions[].pricing | enum | Yes | FLAT per piece, PER_LINEAR_FOOT of the edges, or PER_GROMMET every spacingIn inches. One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | No | Which edges: ALL, TOP_BOTTOM, LEFT_RIGHT or TOP. One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | No | At most 240. |
finishingOptions[].priceCents | integer | Yes | 0–100000000. |
finishingOptions[].costCents | integer | No | 0–100000000. |
finishingOptions[].active | boolean | No |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
A product
GET /organizations/{organizationId}/products/{productId}
One product with every variant (price, rule or override, supplier stock per warehouse), its pictures, large-format finishing options, decoration areas and the pricing rule its prices follow. Read-only.
| Permission | products.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | products_get (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
Change a product
PATCH /organizations/{organizationId}/products/{productId}
Changes the fields sent. On a supplier product, a changed name, description, brand, style number, category, tags or kind becomes an owner override that re-imports keep; clearOverrides hands fields back to the supplier (the next refresh fills them). status: ARCHIVED hides it from selling. Prices are recomputed when the rule changes.
| 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 | products_update (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Up to 500 characters. |
slug | string or null | No | URL segment (made from the name when blank). Up to 80 characters. |
brand | string or null | No | Up to 200 characters. |
styleNumber | string or null | No | Up to 100 characters. |
description | string or null | No | |
category | string or null | No | Up to 200 characters. |
tags | array of string | No | Up to 50 items. |
kind | enum | No | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | No | How its lines are taxed: CLOTHING (some states tax apparel less), STANDARD or EXEMPT; null = by kind (APPAREL is CLOTHING). One of STANDARD, CLOTHING, EXEMPT. |
status | enum | No | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
pricingRuleId | string or null | No | From GET /pricing-rules; null follows the matching rule. |
decorationAreas | array of object | No | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | Yes | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | Yes | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | Yes | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | No | At most 1000. |
decorationAreas[].maxHeightIn | number or null | No | At most 1000. |
decorationAreas[].x | number or null | No | 0–1. |
decorationAreas[].y | number or null | No | 0–1. |
decorationAreas[].width | number or null | No | 0–1. |
decorationAreas[].height | number or null | No | 0–1. |
decorationAreas[].methods | array of enum | No | The decoration methods that suit this area (empty = any). Up to 10 items. |
minWidthIn | number or null | No | At most 10000. |
maxWidthIn | number or null | No | At most 10000. |
minHeightIn | number or null | No | At most 10000. |
maxHeightIn | number or null | No | At most 10000. |
minChargeCents | integer or null | No | Large format: the least one piece costs. 0–100000000. |
clearOverrides | array of enum | No | Fields to hand back to the supplier. Up to 7 items. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","slug":"string","brand":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
Delete a product
DELETE /organizations/{organizationId}/products/{productId}
Destructive: deletes the product with its variants, pictures (and our stored copies), finishing options and supplier stock. Consider archiving instead (PATCH status ARCHIVED). Quotes and invoices keep their own line text and prices.
| 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 | products_delete (toolset catalog) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
Refresh from the supplier
POST /organizations/{organizationId}/products/{productId}/refresh
Reads an imported product's style from its supplier now: live cost and stock per warehouse, new pictures, and supplier facts the owner did not override; then reprices. Adds no variants (import again to add colours or sizes). 409 for a product made by hand or when the supplier refuses the connection.
| 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 | products_refresh (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/refresh" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
productId | string | |
variantsUpdated | integer | |
repriced | integer | Variants whose price changed. |
Add a product picture
POST /organizations/{organizationId}/products/{productId}/images
Adds a picture in one call: the bytes as contentBase64 (JPEG, PNG, WebP or GIF, up to 10 MB) or a public sourceUrl SKUFlow downloads through its SSRF guard. Tag it with the colour and the view (FRONT, BACK, SIDE, DETAIL) so mockups can find it; the first picture becomes the main one.
| 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 | products_addImage (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fileName | string | No | The file's name, e.g. receipt.jpg (default: from the URL, else 'file'). Up to 500 characters. |
contentType | string | No | MIME type, e.g. image/jpeg or application/pdf. Optional: taken from a data: URL, the URL's answer or the file's first bytes. Up to 200 characters. |
contentBase64 | string | No | The file's bytes as base64 (a data: URL is accepted too). Up to 10 MB. Give this or sourceUrl. |
sourceUrl | string (uri) | No | A public http(s) URL SKUFlow downloads the file from (up to 10 MB, 20 s, 3 redirects; private and internal addresses are refused). Give this or contentBase64. Up to 2000 characters. |
colorName | string or null | No | The colour it shows (a variant's colorName). Up to 200 characters. |
view | enum | No | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
isPrimary | boolean | No | Make it the product's main picture. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/images" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileName":"string","contentType":"string","contentBase64":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
Change a product picture
PATCH /organizations/{organizationId}/products/{productId}/images/{imageId}
Sets a picture's colour or view, or makes it the main picture (the previous main one stops being main).
| 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 | products_updateImage (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes | |
imageId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
colorName | string or null | No | Up to 200 characters. |
view | enum | No | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
isPrimary | boolean | No |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/images/{imageId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"colorName":"string","view":"FRONT","isPrimary":true}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
Delete a product picture
DELETE /organizations/{organizationId}/products/{productId}/images/{imageId}
Destructive: removes the picture and our stored copy. A supplier picture comes back on the next import or refresh.
| 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 | products_deleteImage (toolset catalog) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes | |
imageId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/images/{imageId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
Set large-format finishing
POST /organizations/{organizationId}/products/{productId}/finishing-options
Replaces a product's finishing options with this list (hems and pole pockets per linear foot of chosen edges, grommets every N inches, flat add-ons). Send existing options with their id to keep them; options left out are removed.
| 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 | products_setFinishingOptions (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
options | array of object | Yes | Up to 30 items. |
options[].id | string or null | No | An existing option's id to keep it (from the product); omit for a new one. |
options[].name | string | Yes | Up to 200 characters. |
options[].pricing | enum | Yes | FLAT per piece, PER_LINEAR_FOOT of the edges, or PER_GROMMET every spacingIn inches. One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
options[].edges | enum | No | Which edges: ALL, TOP_BOTTOM, LEFT_RIGHT or TOP. One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
options[].spacingIn | number or null | No | At most 240. |
options[].priceCents | integer | Yes | 0–100000000. |
options[].costCents | integer | No | 0–100000000. |
options[].active | boolean | No |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/finishing-options" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"options":[{"name":"Dana Whitfield","pricing":"FLAT","priceCents":12500}]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | URL segment, unique in the business (stores use it). |
brand | string or null | |
styleNumber | string or null | |
description | string or null | |
category | string or null | |
tags | array of string | |
kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
source | enum | One of SUPPLIER, MANUAL. |
supplierConnectionId | string or null | |
supplierStyleId | string or null | |
overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
basePriceCents | integer | The cheapest active variant's price. |
minWidthIn | number or null | |
maxWidthIn | number or null | |
minHeightIn | number or null | |
maxHeightIn | number or null | |
minChargeCents | integer or null | |
lastSupplierSyncAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
supplierConnection | object or null | |
supplierConnection.id | string | |
supplierConnection.displayName | string | |
supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
decorationAreas[].maxWidthIn | number or null | At most 1000. |
decorationAreas[].maxHeightIn | number or null | At most 1000. |
decorationAreas[].x | number or null | 0–1. |
decorationAreas[].y | number or null | 0–1. |
decorationAreas[].width | number or null | 0–1. |
decorationAreas[].height | number or null | 0–1. |
decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
pricingRule | object or null | |
pricingRule.id | string | |
pricingRule.name | string | |
appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
appliedPricingRule.id | string | |
appliedPricingRule.name | string | |
images | array of object | |
images[].id | string | |
images[].colorName | string or null | |
images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
images[].isPrimary | boolean | |
images[].sortOrder | integer | |
images[].sourceUrl | string or null | |
images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
variants | array of object | |
variants[].id | string | |
variants[].productId | string | |
variants[].colorName | string or null | |
variants[].colorHex | string or null | |
variants[].size | string or null | |
variants[].material | string or null | Large format: the material. |
variants[].sku | string or null | |
variants[].gtin | string or null | |
variants[].supplierPartId | string or null | |
variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
variants[].followsRule | boolean | |
variants[].costPerSqFtCents | integer or null | |
variants[].pricePerSqFtCents | integer or null | |
variants[].weightGrams | integer or null | |
variants[].active | boolean | |
variants[].sortOrder | integer | |
variants[].overriddenFields | array of string | |
variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
variants[].supplierStockAt | string (date-time) or null | |
variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
variants[].warehouses | array of object | |
variants[].warehouses[].code | string | The supplier's warehouse code. |
variants[].warehouses[].name | string or null | |
variants[].warehouses[].quantity | integer | |
variants[].warehouses[].fetchedAt | string (date-time) | |
finishingOptions | array of object | |
finishingOptions[].id | string | |
finishingOptions[].name | string | |
finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
finishingOptions[].spacingIn | number or null | |
finishingOptions[].priceCents | integer | Integer cents. |
finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
finishingOptions[].active | boolean | |
finishingOptions[].sortOrder | integer |
Price a large-format piece
GET /organizations/{organizationId}/products/{productId}/large-format-price
What one large-format piece (and the quantity) costs the customer at a width × height in inches, a material (variantId) and finishing options (comma-separated ids): square feet × the material's price per square foot, plus finishing (per foot of edge, per grommet or flat), lifted to the minimum charge. problems lists sizes outside the product's limits. Read-only.
| Permission | products.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | products_largeFormatPrice (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes | |
variantId | query | string | Yes | The material: one of the product's variants. |
widthIn | query | number | Yes | At most 10000. |
heightIn | query | number | Yes | At most 10000. |
quantity | query | integer | No | 1–100000. Default 1. |
finishing | query | string | No | Finishing option ids, comma-separated. Up to 2000 characters. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/large-format-price?variantId=variant_id&widthIn=1&heightIn=1" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | boolean | |
problems | array of string | |
material | object | |
material.id | string | |
material.name | string | |
material.pricePerSqFtCents | integer | |
sqFt | number | |
materialCents | integer | |
finishing | array of object | |
finishing[].id | string | |
finishing[].name | string | |
finishing[].units | number | |
finishing[].unit | string | |
finishing[].cents | integer | |
finishingCents | integer | |
unitPriceCents | integer | |
minChargeApplied | boolean | |
totalCents | integer | |
pieceCostCents | integer | Our cost per piece. Present only for roles with costing.read. |
Add a variant
POST /organizations/{organizationId}/products/{productId}/variants
Adds a variant to a product: a colour × size, or a large-format material with its cost or price per square foot. The price follows the pricing rule unless priceOverrideCents is set.
| 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 | productVariants_create (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
colorName | string or null | No | Up to 200 characters. |
colorHex | string or null | No | |
size | string or null | No | Up to 50 characters. |
material | string or null | No | Large format: the material, e.g. 13 oz vinyl banner. Up to 200 characters. |
sku | string or null | No | Up to 100 characters. |
gtin | string or null | No | Up to 50 characters. |
costCents | integer | No | Unit cost in cents (manual products; imported variants take the supplier's). 0–100000000. |
priceOverrideCents | integer or null | No | Your own price in cents; null follows the pricing rule. 0–100000000. |
costPerSqFtCents | integer or null | No | Large format: the material's cost per square foot. 0–100000000. |
pricePerSqFtCents | integer or null | No | Large format: your price per square foot; null follows the rule. 0–100000000. |
weightGrams | integer or null | No | 0–1000000. |
active | boolean | No | |
sortOrder | integer | No | 0–100000. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/variants" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"colorName":"string","colorHex":"string","size":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
colorName | string or null | |
colorHex | string or null | |
size | string or null | |
material | string or null | Large format: the material. |
sku | string or null | |
gtin | string or null | |
supplierPartId | string or null | |
costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
priceCents | integer | The selling price: the rule's, or the owner's override. |
priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
followsRule | boolean | |
costPerSqFtCents | integer or null | |
pricePerSqFtCents | integer or null | |
weightGrams | integer or null | |
active | boolean | |
sortOrder | integer | |
overriddenFields | array of string | |
supplierStock | integer or null | Units at the supplier across its warehouses. |
supplierStockAt | string (date-time) or null | |
discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
warehouses | array of object | |
warehouses[].code | string | The supplier's warehouse code. |
warehouses[].name | string or null | |
warehouses[].quantity | integer | |
warehouses[].fetchedAt | string (date-time) |
Change a variant
PATCH /organizations/{organizationId}/products/{productId}/variants/{variantId}
Changes the fields sent. priceOverrideCents sets your price (null follows the rule again). On an imported variant the cost comes from the supplier (400 if sent), and changing active, sku or gtin is kept through re-imports.
| 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 | productVariants_update (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes | |
variantId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
colorName | string or null | No | Up to 200 characters. |
colorHex | string or null | No | |
size | string or null | No | Up to 50 characters. |
material | string or null | No | Large format: the material, e.g. 13 oz vinyl banner. Up to 200 characters. |
sku | string or null | No | Up to 100 characters. |
gtin | string or null | No | Up to 50 characters. |
costCents | integer | No | Unit cost in cents (manual products; imported variants take the supplier's). 0–100000000. |
priceOverrideCents | integer or null | No | Your own price in cents; null follows the pricing rule. 0–100000000. |
costPerSqFtCents | integer or null | No | Large format: the material's cost per square foot. 0–100000000. |
pricePerSqFtCents | integer or null | No | Large format: your price per square foot; null follows the rule. 0–100000000. |
weightGrams | integer or null | No | 0–1000000. |
active | boolean | No | |
sortOrder | integer | No | 0–100000. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/variants/{variantId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"colorName":"string","colorHex":"string","size":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
colorName | string or null | |
colorHex | string or null | |
size | string or null | |
material | string or null | Large format: the material. |
sku | string or null | |
gtin | string or null | |
supplierPartId | string or null | |
costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
priceCents | integer | The selling price: the rule's, or the owner's override. |
priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
followsRule | boolean | |
costPerSqFtCents | integer or null | |
pricePerSqFtCents | integer or null | |
weightGrams | integer or null | |
active | boolean | |
sortOrder | integer | |
overriddenFields | array of string | |
supplierStock | integer or null | Units at the supplier across its warehouses. |
supplierStockAt | string (date-time) or null | |
discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
warehouses | array of object | |
warehouses[].code | string | The supplier's warehouse code. |
warehouses[].name | string or null | |
warehouses[].quantity | integer | |
warehouses[].fetchedAt | string (date-time) |
Delete a variant
DELETE /organizations/{organizationId}/products/{productId}/variants/{variantId}
Destructive: deletes the variant and its supplier stock. An imported variant comes back on the next import of its colour and size; switching it off (active false) is usually better.
| 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 | productVariants_delete (toolset catalog) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes | |
variantId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/variants/{variantId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
Change several variants
POST /organizations/{organizationId}/products/{productId}/variants/bulk
Switches several of a product's variants on or off and/or sets (or clears, with null) your price on all of them at once, e.g. turn off every 5XL or price every 2XL at $14.
| 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 | productVariants_bulkUpdate (toolset catalog) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
variantIds | array of string | Yes | Up to 1000 items. |
active | boolean | No | |
priceOverrideCents | integer or null | No | 0–100000000. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/products/{productId}/variants/bulk" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"variantIds":["variant_id"]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
updated | integer | |
product | object | |
product.id | string | |
product.name | string | |
product.slug | string | URL segment, unique in the business (stores use it). |
product.brand | string or null | |
product.styleNumber | string or null | |
product.description | string or null | |
product.category | string or null | |
product.tags | array of string | |
product.kind | enum | APPAREL (garments: colour × size), PROMO (promotional items), LARGE_FORMAT (banners and signs priced per square foot from a material) or OTHER. One of APPAREL, PROMO, LARGE_FORMAT, OTHER. |
product.taxClass | enum or null | Tax class of its lines; null = by kind. One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
product.status | enum | ACTIVE (sold) or ARCHIVED (kept, hidden). One of ACTIVE, ARCHIVED. |
product.source | enum | One of SUPPLIER, MANUAL. |
product.supplierConnectionId | string or null | |
product.supplierStyleId | string or null | |
product.overriddenFields | array of string | Fields the owner changed on a supplier product: re-imports keep them. |
product.pricingRuleId | string or null | The rule chosen for this product; null = the matching rule. |
product.baseCostCents | integer | The cheapest active variant's cost. Present only for roles with costing.read. |
product.basePriceCents | integer | The cheapest active variant's price. |
product.minWidthIn | number or null | |
product.maxWidthIn | number or null | |
product.minHeightIn | number or null | |
product.maxHeightIn | number or null | |
product.minChargeCents | integer or null | |
product.lastSupplierSyncAt | string (date-time) or null | |
product.createdAt | string (date-time) | |
product.updatedAt | string (date-time) | |
product.supplierConnection | object or null | |
product.supplierConnection.id | string | |
product.supplierConnection.displayName | string | |
product.supplierConnection.kind | enum | SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS (any other supplier on the standard) or CSV (a catalog file). One of SS_ACTIVEWEAR, SANMAR, ALPHABRODER, JDS, MOMENTEC, PROMOSTANDARDS, CSV. |
product.decorationAreas | array of object | Where art can go on the product, per image view (used by decoration pricing and mockups). Up to 30 items. |
product.decorationAreas[].key | string | A stable key for the location, e.g. "front", "left-chest", "full-back". Up to 60 characters. |
product.decorationAreas[].name | string | What the customer reads: Left chest. Up to 120 characters. |
product.decorationAreas[].view | enum | The product image view the area sits on. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
product.decorationAreas[].maxWidthIn | number or null | At most 1000. |
product.decorationAreas[].maxHeightIn | number or null | At most 1000. |
product.decorationAreas[].x | number or null | 0–1. |
product.decorationAreas[].y | number or null | 0–1. |
product.decorationAreas[].width | number or null | 0–1. |
product.decorationAreas[].height | number or null | 0–1. |
product.decorationAreas[].methods | array of enum | The decoration methods that suit this area (empty = any). Up to 10 items. |
product.pricingRule | object or null | |
product.pricingRule.id | string | |
product.pricingRule.name | string | |
product.appliedPricingRule | object or null | The rule prices follow now (own, matching or default); null = keystone ×2 ending .99. |
product.appliedPricingRule.id | string | |
product.appliedPricingRule.name | string | |
product.images | array of object | |
product.images[].id | string | |
product.images[].colorName | string or null | |
product.images[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
product.images[].status | string | PENDING (being copied from the supplier), STORED (in SKUFlow's storage) or FAILED. |
product.images[].isPrimary | boolean | |
product.images[].sortOrder | integer | |
product.images[].sourceUrl | string or null | |
product.images[].url | string or null | Show this: a signed URL of our copy (1 hour), else the source. |
product.variants | array of object | |
product.variants[].id | string | |
product.variants[].productId | string | |
product.variants[].colorName | string or null | |
product.variants[].colorHex | string or null | |
product.variants[].size | string or null | |
product.variants[].material | string or null | Large format: the material. |
product.variants[].sku | string or null | |
product.variants[].gtin | string or null | |
product.variants[].supplierPartId | string or null | |
product.variants[].costCents | integer | Unit cost (the supplier's for imported variants). Present only for roles with costing.read. |
product.variants[].priceCents | integer | The selling price: the rule's, or the owner's override. |
product.variants[].priceOverrideCents | integer or null | The owner's price; null follows the pricing rule. |
product.variants[].followsRule | boolean | |
product.variants[].costPerSqFtCents | integer or null | |
product.variants[].pricePerSqFtCents | integer or null | |
product.variants[].weightGrams | integer or null | |
product.variants[].active | boolean | |
product.variants[].sortOrder | integer | |
product.variants[].overriddenFields | array of string | |
product.variants[].supplierStock | integer or null | Units at the supplier across its warehouses. |
product.variants[].supplierStockAt | string (date-time) or null | |
product.variants[].discontinuedAt | string (date-time) or null | When the supplier stopped listing this part. |
product.variants[].warehouses | array of object | |
product.finishingOptions | array of object | |
product.finishingOptions[].id | string | |
product.finishingOptions[].name | string | |
product.finishingOptions[].pricing | enum | One of FLAT, PER_LINEAR_FOOT, PER_GROMMET. |
product.finishingOptions[].edges | enum | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. |
product.finishingOptions[].spacingIn | number or null | |
product.finishingOptions[].priceCents | integer | Integer cents. |
product.finishingOptions[].costCents | integer | Our cost per unit of this option. Present only for roles with costing.read. |
product.finishingOptions[].active | boolean | |
product.finishingOptions[].sortOrder | integer |