Designs API
REST endpoints for designs in SKUFlow: 8 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 designs | GET /organizations/{organizationId}/designs | read |
| Create a design | POST /organizations/{organizationId}/designs | write |
| Get a design | GET /organizations/{organizationId}/designs/{designId} | read |
| Update a design | PATCH /organizations/{organizationId}/designs/{designId} | write |
| Delete a design | DELETE /organizations/{organizationId}/designs/{designId} | sensitive |
| Duplicate a design | POST /organizations/{organizationId}/designs/{designId}/duplicate | write |
| Render the design's mockups | POST /organizations/{organizationId}/designs/{designId}/mockups | write |
| Price a design at quantities | GET /organizations/{organizationId}/designs/{designId}/price | read |
List designs
GET /organizations/{organizationId}/designs
Designs (a product with artwork placed on it), newest first, with the first mockup: filter by product or customer (with includeShared, that customer's and the business's own), search by name. Read-only.
| Permission | decoration.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | designs_list (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
productId | query | string | No | |
customerId | query | string | No | |
includeShared | query | boolean or enum | No | With customerId: also the business's own designs (no customer), e.g. to choose one for that customer's quote. |
query | query | string | No | Free-text search over the list's names, numbers and contact details. 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/designs" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].name | string | |
items[].productId | string | |
items[].product | object | |
items[].product.id | string | |
items[].product.name | string | |
items[].product.kind | string | |
items[].customer | object or null | |
items[].customer.id | string | |
items[].customer.name | string | |
items[].placementCount | integer | |
items[].mockup | object or null | |
items[].mockup.view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
items[].mockup.colorName | string or null | |
items[].mockup.widthPx | integer | |
items[].mockup.heightPx | integer | |
items[].mockup.url | string or null | The flattened PNG (signed, 1 hour). |
items[].mockupsStale | boolean | |
items[].updatedAt | string (date-time) | |
total | integer |
Create a design
POST /organizations/{organizationId}/designs
A product (GET /products) decorated: the colours, and placements (an area key from the product's decoration areas, a method, artwork version layers, print size, ink colours / stitch count / size band). Art can be added later. Then render the mockups (POST /designs/{designId}/mockups) and put it on a quote line (product.designId).
| Permission | designs.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | designs_create (toolset decoration) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string or null | No | Whose design (their library); null = the business's own. |
name | string or null | No | Up to 200 characters. |
colorNames | array of string | No | Product colours it is shown and ordered in (variant colorName). Up to 30 items. |
notes | string or null | No | Up to 5000 characters. |
largeFormat | object or null | No | Large format: size in inches, FIT / FILL / STRETCH, bleed, safe area, background, double-sided, grommets. |
largeFormat.widthIn | number | No | At most 10000. |
largeFormat.heightIn | number | No | At most 10000. |
largeFormat.fit | enum | No | Fit: the whole image inside; FILL: cover the piece (cropped); STRETCH: distorted to fill. One of FIT, FILL, STRETCH. Default FILL. |
largeFormat.bleedIn | number | No | 0–12. Default 0.125. |
largeFormat.safeIn | number | No | 0–24. Default 1. |
largeFormat.background | string | No | Default #ffffff. |
largeFormat.doubleSided | boolean | No | Default false. |
largeFormat.grommetSpacingIn | number or null | No | At most 120. |
largeFormat.grommetEdges | enum | No | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. Default ALL. |
placements | array of object | No | Replaces every placement when given. Up to 20 items. |
placements[].areaKey | string | Yes | One of the product's decoration areas (GET /products/{productId} decorationAreas). Up to 60 characters. |
placements[].areaName | string or null | No | Up to 120 characters. |
placements[].view | enum or null | No | Default: the area's view. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
placements[].methodId | string or null | No | The decoration method (GET /decoration-methods). |
placements[].x | number or null | No | The print area on the view's picture, 0–1. -1–2. |
placements[].y | number or null | No | -1–2. |
placements[].width | number or null | No | At most 3. |
placements[].height | number or null | No | At most 3. |
placements[].inkColors | integer or null | No | Ink colours (COLORS tables). 1–30. |
placements[].stitchCount | integer or null | No | Stitches (STITCHES tables). 0–1000000. |
placements[].sizeBandKey | string or null | No | A size band column key (SIZE_BAND). Up to 40 characters. |
placements[].printWidthIn | number or null | No | At most 10000. |
placements[].printHeightIn | number or null | No | At most 10000. |
placements[].options | object or null | No | |
placements[].options.underbase | boolean or null | No | Force the white underbase on (true) or off (false); default: on dark colours. |
placements[].options.puff | boolean or null | No | Embroidery 3D puff. |
placements[].options.alreadyDigitized | boolean or null | No | The embroidery file exists (a reorder): no digitizing fee. |
placements[].options.artService | boolean or null | No | Ask for the art fee (redraw, clean-up). |
placements[].options.doubleSided | boolean or null | No | Large format: print both sides. |
placements[].options.setupWaived | boolean or null | No | Screens or set-up already paid (a reorder). |
placements[].layers | array of object | No | Artwork on the picture: artwork versions with position, size and rotation as fractions. Up to 12 items. |
placements[].layers[].kind | enum | No | One of ARTWORK, TEXT, CLIPART. Default ARTWORK. |
placements[].layers[].artworkVersionId | string | No | ARTWORK layers: GET /artwork/{artworkId} versions. Up to 64 characters. |
placements[].layers[].text | string | No | TEXT layers: one line. Up to 120 characters. |
placements[].layers[].font | enum | No | TEXT layers (default sans). One of sans, sans-bold, serif, serif-bold, mono. |
placements[].layers[].color | string | No | TEXT and CLIPART layers: the ink colour (#rrggbb). |
placements[].layers[].clipartKey | string | No | CLIPART layers: a key of the clipart library (GET /public/studio/…). Up to 40 characters. |
placements[].layers[].x | number | Yes | Left edge, as a fraction of the picture's width. -1–2. |
placements[].layers[].y | number | Yes | Top edge, as a fraction of the picture's height. -1–2. |
placements[].layers[].width | number | Yes | At most 3. |
placements[].layers[].height | number | Yes | At most 3. |
placements[].layers[].rotation | number | No | -360–360. Default 0. |
productId | string | Yes | The product (GET /products). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"productId":"product_id"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
name | string | |
colorNames | array of string | |
notes | string or null | |
revision | integer | Bumped on every change; proofs show a revision. |
mockups | array of object | |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].colorName | string or null | |
mockups[].widthPx | integer | |
mockups[].heightPx | integer | |
mockups[].url | string or null | The flattened PNG (signed, 1 hour). |
mockupsStale | boolean | The mockups show an older revision: render them again. |
largeFormat | any | Large format: size, fit, bleed, safe area, background, double-sided, grommets; null otherwise. |
product | any | The product: kind, pictures per colour and view (signed links), decoration areas, colours, active variants with prices. |
placements | any | Placements: area, view, method, print area on the picture (0–1), print size, ink colours / stitches / size band, options, and artwork layers (artwork version with links, position, rotation, checks = print warnings). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Get a design
GET /organizations/{organizationId}/designs/{designId}
One design with its product (pictures per colour and view, decoration areas, colours), placements (method, print size, pricing inputs, artwork layers with print checks) and mockups. Read-only.
| Permission | decoration.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | designs_get (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
name | string | |
colorNames | array of string | |
notes | string or null | |
revision | integer | Bumped on every change; proofs show a revision. |
mockups | array of object | |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].colorName | string or null | |
mockups[].widthPx | integer | |
mockups[].heightPx | integer | |
mockups[].url | string or null | The flattened PNG (signed, 1 hour). |
mockupsStale | boolean | The mockups show an older revision: render them again. |
largeFormat | any | Large format: size, fit, bleed, safe area, background, double-sided, grommets; null otherwise. |
product | any | The product: kind, pictures per colour and view (signed links), decoration areas, colours, active variants with prices. |
placements | any | Placements: area, view, method, print area on the picture (0–1), print size, ink colours / stitches / size band, options, and artwork layers (artwork version with links, position, rotation, checks = print warnings). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Update a design
PATCH /organizations/{organizationId}/designs/{designId}
Changes the fields sent; placements replaces every placement. Bumps the revision: mockups go stale and the next quote send makes a new proof. Quote lines already priced keep their price until re-priced.
| Permission | designs.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | designs_update (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string or null | No | Whose design (their library); null = the business's own. |
name | string or null | No | Up to 200 characters. |
colorNames | array of string | No | Product colours it is shown and ordered in (variant colorName). Up to 30 items. |
notes | string or null | No | Up to 5000 characters. |
largeFormat | object or null | No | Large format: size in inches, FIT / FILL / STRETCH, bleed, safe area, background, double-sided, grommets. |
largeFormat.widthIn | number | No | At most 10000. |
largeFormat.heightIn | number | No | At most 10000. |
largeFormat.fit | enum | No | Fit: the whole image inside; FILL: cover the piece (cropped); STRETCH: distorted to fill. One of FIT, FILL, STRETCH. Default FILL. |
largeFormat.bleedIn | number | No | 0–12. Default 0.125. |
largeFormat.safeIn | number | No | 0–24. Default 1. |
largeFormat.background | string | No | Default #ffffff. |
largeFormat.doubleSided | boolean | No | Default false. |
largeFormat.grommetSpacingIn | number or null | No | At most 120. |
largeFormat.grommetEdges | enum | No | One of ALL, TOP_BOTTOM, LEFT_RIGHT, TOP. Default ALL. |
placements | array of object | No | Replaces every placement when given. Up to 20 items. |
placements[].areaKey | string | Yes | One of the product's decoration areas (GET /products/{productId} decorationAreas). Up to 60 characters. |
placements[].areaName | string or null | No | Up to 120 characters. |
placements[].view | enum or null | No | Default: the area's view. One of FRONT, BACK, SIDE, DETAIL, OTHER. |
placements[].methodId | string or null | No | The decoration method (GET /decoration-methods). |
placements[].x | number or null | No | The print area on the view's picture, 0–1. -1–2. |
placements[].y | number or null | No | -1–2. |
placements[].width | number or null | No | At most 3. |
placements[].height | number or null | No | At most 3. |
placements[].inkColors | integer or null | No | Ink colours (COLORS tables). 1–30. |
placements[].stitchCount | integer or null | No | Stitches (STITCHES tables). 0–1000000. |
placements[].sizeBandKey | string or null | No | A size band column key (SIZE_BAND). Up to 40 characters. |
placements[].printWidthIn | number or null | No | At most 10000. |
placements[].printHeightIn | number or null | No | At most 10000. |
placements[].options | object or null | No | |
placements[].options.underbase | boolean or null | No | Force the white underbase on (true) or off (false); default: on dark colours. |
placements[].options.puff | boolean or null | No | Embroidery 3D puff. |
placements[].options.alreadyDigitized | boolean or null | No | The embroidery file exists (a reorder): no digitizing fee. |
placements[].options.artService | boolean or null | No | Ask for the art fee (redraw, clean-up). |
placements[].options.doubleSided | boolean or null | No | Large format: print both sides. |
placements[].options.setupWaived | boolean or null | No | Screens or set-up already paid (a reorder). |
placements[].layers | array of object | No | Artwork on the picture: artwork versions with position, size and rotation as fractions. Up to 12 items. |
placements[].layers[].kind | enum | No | One of ARTWORK, TEXT, CLIPART. Default ARTWORK. |
placements[].layers[].artworkVersionId | string | No | ARTWORK layers: GET /artwork/{artworkId} versions. Up to 64 characters. |
placements[].layers[].text | string | No | TEXT layers: one line. Up to 120 characters. |
placements[].layers[].font | enum | No | TEXT layers (default sans). One of sans, sans-bold, serif, serif-bold, mono. |
placements[].layers[].color | string | No | TEXT and CLIPART layers: the ink colour (#rrggbb). |
placements[].layers[].clipartKey | string | No | CLIPART layers: a key of the clipart library (GET /public/studio/…). Up to 40 characters. |
placements[].layers[].x | number | Yes | Left edge, as a fraction of the picture's width. -1–2. |
placements[].layers[].y | number | Yes | Top edge, as a fraction of the picture's height. -1–2. |
placements[].layers[].width | number | Yes | At most 3. |
placements[].layers[].height | number | Yes | At most 3. |
placements[].layers[].rotation | number | No | -360–360. Default 0. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customerId":"customer_id","name":"Dana Whitfield","colorNames":["string"]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
name | string | |
colorNames | array of string | |
notes | string or null | |
revision | integer | Bumped on every change; proofs show a revision. |
mockups | array of object | |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].colorName | string or null | |
mockups[].widthPx | integer | |
mockups[].heightPx | integer | |
mockups[].url | string or null | The flattened PNG (signed, 1 hour). |
mockupsStale | boolean | The mockups show an older revision: render them again. |
largeFormat | any | Large format: size, fit, bleed, safe area, background, double-sided, grommets; null otherwise. |
product | any | The product: kind, pictures per colour and view (signed links), decoration areas, colours, active variants with prices. |
placements | any | Placements: area, view, method, print area on the picture (0–1), print size, ink colours / stitches / size band, options, and artwork layers (artwork version with links, position, rotation, checks = print warnings). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Delete a design
DELETE /organizations/{organizationId}/designs/{designId}
Destructive: deletes the design and its placements. Refused while an open quote uses it (duplicate it instead).
| Permission | designs.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 | designs_delete (toolset decoration) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | true |
Duplicate a design
POST /organizations/{organizationId}/designs/{designId}/duplicate
A copy with the same product, colours and placements (to change a design an open quote uses, or start a reorder variant).
| Permission | designs.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | designs_duplicate (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}/duplicate" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
name | string | |
colorNames | array of string | |
notes | string or null | |
revision | integer | Bumped on every change; proofs show a revision. |
mockups | array of object | |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].colorName | string or null | |
mockups[].widthPx | integer | |
mockups[].heightPx | integer | |
mockups[].url | string or null | The flattened PNG (signed, 1 hour). |
mockupsStale | boolean | The mockups show an older revision: render them again. |
largeFormat | any | Large format: size, fit, bleed, safe area, background, double-sided, grommets; null otherwise. |
product | any | The product: kind, pictures per colour and view (signed links), decoration areas, colours, active variants with prices. |
placements | any | Placements: area, view, method, print area on the picture (0–1), print size, ink colours / stitches / size band, options, and artwork layers (artwork version with links, position, rotation, checks = print warnings). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Render the design's mockups
POST /organizations/{organizationId}/designs/{designId}/mockups
Flattens the art onto the product's pictures, a PNG per view (and per chosen colour, up to six); large format renders the piece at its size with the image fitted or filled and the grommets. Stored and returned with the design.
| Permission | designs.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | designs_renderMockups (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}/mockups" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
productId | string | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
name | string | |
colorNames | array of string | |
notes | string or null | |
revision | integer | Bumped on every change; proofs show a revision. |
mockups | array of object | |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].colorName | string or null | |
mockups[].widthPx | integer | |
mockups[].heightPx | integer | |
mockups[].url | string or null | The flattened PNG (signed, 1 hour). |
mockupsStale | boolean | The mockups show an older revision: render them again. |
largeFormat | any | Large format: size, fit, bleed, safe area, background, double-sided, grommets; null otherwise. |
product | any | The product: kind, pictures per colour and view (signed links), decoration areas, colours, active variants with prices. |
placements | any | Placements: area, view, method, print area on the picture (0–1), print size, ink colours / stitches / size band, options, and artwork layers (artwork version with links, position, rotation, checks = print warnings). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Price a design at quantities
GET /organizations/{organizationId}/designs/{designId}/price
The design's price at quantities per variant (items; or quantity of its first colour): sizes priced alike grouped (blank + decoration per piece at the total), per-location detail and one-time fees. Read-only.
| Permission | decoration.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | designs_price (toolset decoration) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
designId | path | string | Yes | |
items | query | array of object | No | Up to 200 items. |
quantity | query | integer | No | 1–1000000. |
waivedFees | query | array of string | No | Up to 50 items. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/designs/{designId}/price" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | boolean | |
groups | any | Sizes priced alike: unit price (blank + decoration), quantity, colours, sizes and items. |
placements | any | Per location: method, the column and quantity break used, price per piece (and on dark colours). |
quantity | number | |
totalCents | integer | |
goodsCents | integer | |
feesCents | integer | |
fees | array of object | |
fees[].key | string | {placementKey}:{kind}: name it in waivedFees to leave it off. |
fees[].kind | enum | One of setup, digitizing, art, layout, minimum. |
fees[].label | string | |
fees[].amountCents | integer | |
fees[].costCents | any | Our cost of the fee. Present only for roles with costing.read. |
fees[].costKnown | any | False when the method has no cost table (the fee's cost counts as 0). Present only for roles with costing.read. |
problems | array of string | |
totalCostCents | any | Our cost of the whole line, fees included. Present only for roles with costing.read. |
marginCents | any | Price minus cost. Present only for roles with costing.read. |
costKnown | any | True when every cost behind totalCostCents is known (each blank has a cost, each method a cost table); false means part of it counted as 0. Present only for roles with costing.read. |