DevelopersAPI reference

Workflows API

REST endpoints for workflows in SKUFlow: 4 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.

OperationEndpointRisk
Draft a quote from a description of the workPOST /organizations/{organizationId}/workflows/quote-from-descriptionwrite
Invoice an approved quote and send it to the customerPOST /organizations/{organizationId}/workflows/invoice-quote-and-sendsensitive
Everything about a customer (360 and open items)GET /organizations/{organizationId}/workflows/customer-overviewread
Create a draft store for a customerPOST /organizations/{organizationId}/workflows/store-for-customerwrite

Draft a quote from a description of the work

POST /organizations/{organizationId}/workflows/quote-from-description

Turns a description of the work ("150 navy tees, 2-colour front print, 1-colour back") into a DRAFT quote (Q-n) for a customer: lines you give are used as they are (a line may be a product line); without them, each phrase of the description (split on commas, 'and', new lines) is matched first to the product catalog (GET /products search: garments, promo items, large format with a size like 72x36) and the decoration phrases after it ("2-colour front print", "embroidered left chest", "DTF back") become a design (POST /designs: method from the decoration matrix, the product's area, ink colours or stitches) priced from the matrix; anything else is matched to the pricebook. What was assumed (sizes, colour, stitch count) is listed in assumptions — set the size breakdown before sending. Phrases with no match are listed in unmatched. Nothing is sent: review it, then quotes.send. Returns the quote, the lines, the designs made, the assumptions, the unmatched phrases and the quote's url.

Permissionquotes.write (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolquote_from_description (toolset sales, in the default set)

Request body

FieldTypeRequiredDescription
customerIdstringYesThe customer (GET /customers).
propertyIdstringNo
requestIdstringNoThe request this answers.
descriptionstringYesThe work, in plain words. Up to 5000 characters.
titlestringNoDefault: the description's first phrase. Up to 200 characters.
linesarray of objectNoUp to 100 items.
lines[].productobjectNoA product line (sizes × colours and a design, or a large-format size), priced by the server; the other fields are ignored.
lines[].product.productIdstringYesThe product (GET /products).
lines[].product.designIdstring or nullNoIts design (GET /designs?productId=): placements and methods priced.
lines[].product.sizesarray of objectNoGarments and promo goods: the quantity per variant (the size × colour grid). Up to 300 items.
lines[].product.largeFormatobject or nullNo
lines[].product.waivedFeesarray of stringNoOne-time fees to leave off, by key ("left-chest:digitizing"). Up to 50 items.
lines[].product.labelstring or nullNoText before the sizes; default: the product's name. Up to 200 characters.
lines[].pricebookItemIdstringNoA pricebook item (GET /pricebook/items).
lines[].descriptionstringNoThe line's text (required without an item). Up to 1000 characters.
lines[].quantitynumberNo0.01–100000. Default 1.
lines[].unitPriceCentsintegerNoOverrides the item's price; required without an item.
validUntilstringNoA calendar date in the business's own calendar, YYYY-MM-DD.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/workflows/quote-from-description" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customerId":"customer_id","description":"string"}'

Response

201: the answer's fields
FieldTypeDescription
quoteobjectThe DRAFT quote (Q-n), as POST /quotes returns it.
quote.idstring
linesarray of object
lines[].descriptionstring
lines[].quantitynumber
lines[].unitPriceCentsinteger
lines[].pricebookItemIdstring or null
lines[].productIdstring or null
lines[].designIdstring or null
lines[].matchedFromstring or nullThe phrase it was matched from.
designsarray of objectDesigns made for decorated products (add artwork to them: PATCH /designs/{designId}).
designs[].idstring
designs[].namestring
assumptionsarray of stringWhat the workflow assumed (sizes, colour, stitches): confirm or fix before sending.
unmatchedarray of stringPhrases with no product or pricebook match: add them or ask.
urlstringThe SKUFlow screen for the result (open it in the web app to see or change it).

Invoice an approved quote and send it to the customer

POST /organizations/{organizationId}/workflows/invoice-quote-and-send

Customer-facing: invoices an approved quote and sends the invoice in one step: reuses the invoice the quote was already converted to, or converts it (quotes.convertToInvoice: the approved lines, deposits applied), then sends it by email (default) or text with the business's invoice message (messages.previewSend → messages.send), which issues it (SENT) and gives the customer the pay link. Consent applies (no text without OK-to-text). If sending is impossible (no address, consent) the invoice is still made and the answer says why. Returns the invoice, the message and the invoice's url.

Permissioninvoices.send (Owner, Admin, Staff)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolinvoice_quote_and_send (toolset invoices, in the default set)
ApprovalOver MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals.

Request body

FieldTypeRequiredDescription
quoteIdstringYesThe APPROVED quote to bill (GET /quotes).
channelenumNoOne of EMAIL, SMS. Default EMAIL.
messagestringNoReplaces the message body (default: the business's invoice template). Up to 5000 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/workflows/invoice-quote-and-send" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"quoteId":"quote_id"}'

Response

200: the answer's fields
FieldTypeDescription
invoiceobjectThe invoice (INV-n).
invoice.idstring
invoiceCreatedboolean
sentboolean
messageobject or nullThe message as sent (status, channel, recipient).
notSentReasonstring or null
urlstringThe SKUFlow screen for the result (open it in the web app to see or change it).

Everything about a customer (360 and open items)

GET /organizations/{organizationId}/workflows/customer-overview

One customer at a glance: the record, the Customer 360 summary (lifetime value, health, behaviours, predictions), and their open items: open quotes, unpaid invoices with the balance and new requests. Give customerId, or query (name, email or phone) when it matches one customer. Parts your role cannot see are left out and named in hidden. Read-only.

Permissioncustomers.read (Owner, Admin, Staff, Member)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolcustomer_overview (toolset customers, in the default set)

Parameters

NameInTypeRequiredDescription
customerIdquerystringNo
queryquerystringNoName, email or phone. Up to 200 characters.

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/workflows/customer-overview" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
customerobject
customer.idstring
insightobject or nullCustomer 360 (GET /customers/{customerId}/insights).
openQuotesarray of object
unpaidInvoicesarray of object
balanceDueCentsintegerSum of the unpaid invoices' balances, in cents.
openRequestsarray of object
hiddenarray of stringSections left out because the role cannot read them.
urlstringThe SKUFlow screen for the result (open it in the web app to see or change it).

Create a draft store for a customer

POST /organizations/{organizationId}/workflows/store-for-customer

A company (or team, fundraiser) store for one customer in one call: drafts the banner and categories (POST /stores/draft: Claude when configured, else a template; invents nothing), creates the DRAFT store for the customer with those categories and the products given (GET /products; each lands in its suggested category) and the pricing, checkout, access and dates given, then answers the store with what still blocks opening (readiness). Nothing is public: review it, then POST /stores/{storeId}/publish.

Permissionstores.manage (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolworkflows_storeForCustomer (toolset stores)

Request body

FieldTypeRequiredDescription
customerIdstringYesThe customer the store is for (GET /customers).
productIdsarray of stringYesCatalog products to sell (GET /products). Up to 300 items.
kindenumNoOne of COMPANY, TEAM, FUNDRAISER, RETAIL. Default COMPANY.
namestringNoDefault: from the customer's name. Up to 200 characters.
checkoutModeenumNoDefault PAY_ONLINE; INVOICE_ACCOUNT and FREE bill the customer. One of PAY_ONLINE, INVOICE_ACCOUNT, FREE.
priceModeenumNoOne of CATALOG, MARKUP, FIXED.
markupPercentnumberNo0–1000.
allowanceCentsintegerNo0–100000000.
opensOnstringNoA calendar date in the business's own calendar, YYYY-MM-DD.
closesOnstringNoThe order deadline.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/workflows/store-for-customer" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customerId":"customer_id","productIds":["product_id"]}'

Response

201: the answer's fields
FieldTypeDescription
storeobject
store.idstring
store.readinessarray of string
draftSourceenumOne of AI, TEMPLATE.
urlstringThe SKUFlow screen for the result (open it in the web app to see or change it).

On this page