Stores API
REST endpoints for stores in SKUFlow: 31 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 online stores | GET /organizations/{organizationId}/stores | read |
| Create an online store | POST /organizations/{organizationId}/stores | write |
| An online store | GET /organizations/{organizationId}/stores/{storeId} | read |
| Change an online store | PATCH /organizations/{organizationId}/stores/{storeId} | write |
| Delete an online store | DELETE /organizations/{organizationId}/stores/{storeId} | sensitive |
| Open a store for orders | POST /organizations/{organizationId}/stores/{storeId}/publish | sensitive |
| Close a store | POST /organizations/{organizationId}/stores/{storeId}/close | write |
| Set a store's categories | POST /organizations/{organizationId}/stores/{storeId}/categories | write |
| A store's sales | GET /organizations/{organizationId}/stores/{storeId}/dashboard | read |
| A store's production batch | GET /organizations/{organizationId}/stores/{storeId}/batch | read |
| Export a store's orders (CSV) | GET /organizations/{organizationId}/stores/{storeId}/orders/export | read |
| Draft a store's banner and categories | POST /organizations/{organizationId}/stores/draft | write |
| Upload a store picture | POST /organizations/{organizationId}/stores/images | write |
| A store's invites | GET /organizations/{organizationId}/stores/{storeId}/invites | read |
| Invite people to a store | POST /organizations/{organizationId}/stores/{storeId}/invites | sensitive |
| A store's custom domains | GET /organizations/{organizationId}/stores/{storeId}/domains | read |
| Connect a custom domain to a store | POST /organizations/{organizationId}/stores/{storeId}/domains | write |
| Check a store domain's DNS now | POST /organizations/{organizationId}/stores/{storeId}/domains/{domainId}/verify | write |
| Make a domain the store's main address | POST /organizations/{organizationId}/stores/{storeId}/domains/{domainId}/primary | write |
| Disconnect a store domain | DELETE /organizations/{organizationId}/stores/{storeId}/domains/{domainId} | sensitive |
| Remove an invite | DELETE /organizations/{organizationId}/stores/{storeId}/invites/{inviteId} | sensitive |
| A store's products | GET /organizations/{organizationId}/stores/{storeId}/products | read |
| Add products to a store | POST /organizations/{organizationId}/stores/{storeId}/products | write |
| Change a store product | PATCH /organizations/{organizationId}/stores/{storeId}/products/{storeProductId} | write |
| Remove a product from a store | DELETE /organizations/{organizationId}/stores/{storeId}/products/{storeProductId} | sensitive |
| List store orders | GET /organizations/{organizationId}/store-orders | read |
| A store order | GET /organizations/{organizationId}/store-orders/{storeOrderId} | read |
| Approve a company-paid order | POST /organizations/{organizationId}/store-orders/{storeOrderId}/approve | sensitive |
| Reject a company-paid order | POST /organizations/{organizationId}/store-orders/{storeOrderId}/reject | sensitive |
| Cancel a store order | POST /organizations/{organizationId}/store-orders/{storeOrderId}/cancel | sensitive |
| Mark store orders fulfilled | POST /organizations/{organizationId}/store-orders/fulfil | write |
List online stores
GET /organizations/{organizationId}/stores
The business's online stores with their status, whether they take orders today, the deadline, address, products, paid/approved order count, sales and fundraiser progress. Filter by status, kind, customer or a search of names and addresses. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_list (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | enum | No | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
kind | query | enum | No | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
customerId | query | string | No | Only stores for this customer. |
query | query | string | No | 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/stores" \
-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 | |
items[].subdomain | string | Its address on the sites domain (unique across stores and websites). |
items[].kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
items[].status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
items[].availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
items[].opensOn | string or null | |
items[].closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
items[].daysLeft | integer or null | |
items[].customerId | string or null | |
items[].customer | object or null | |
items[].customer.id | string | |
items[].customer.name | string | |
items[].customer.taxExempt | boolean | |
items[].theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
items[].theme.primaryColor | string | |
items[].theme.accentColor | string | |
items[].theme.font | string | |
items[].theme.radius | string | |
items[].theme.headerStyle | string | |
items[].logoUrl | string or null | |
items[].heroImageUrl | string or null | |
items[].heroTitle | string or null | |
items[].heroText | string or null | |
items[].access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
items[].hasPassword | boolean | A password is set (it is never returned). |
items[].allowedEmailDomains | array of string | |
items[].checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
items[].requireApproval | boolean | |
items[].allowanceCents | integer or null | |
items[].fundraiserGoalCents | integer or null | |
items[].fundraiserPercent | number or null | |
items[].shippingOptions | array of object | Up to 10 items. |
items[].shippingOptions[].id | string | |
items[].shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
items[].shippingOptions[].label | string | Up to 80 characters. |
items[].shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
items[].shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
items[].shippingOptions[].table | array of object | Up to 10 items. Default []. |
items[].shippingOptions[].note | string | Up to 500 characters. Default ``. |
items[].taxRate | number | |
items[].taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
items[].priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
items[].markupPercent | number or null | |
items[].roundTo99 | boolean | |
items[].policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
items[].policies.returns | string | |
items[].policies.guarantee | string | |
items[].policies.privacy | string | |
items[].returnsPolicy | string or null | |
items[].guaranteePolicy | string or null | |
items[].privacyPolicy | string or null | |
items[].contactEmail | string or null | |
items[].contactPhone | string or null | |
items[].fulfilledBy | string or null | |
items[].categories | array of object | |
items[].categories[].id | string | |
items[].categories[].name | string | |
items[].categories[].slug | string | |
items[].categories[].imageUrl | string or null | |
items[].categories[].sortOrder | integer | |
items[].productCount | integer | |
items[].inviteCount | integer | |
items[].orderCount | integer | Paid or approved orders. |
items[].salesCents | integer | Totals of paid or approved orders. |
items[].fundraiser | object or null | |
items[].fundraiser.raisedCents | integer | Integer cents. |
items[].fundraiser.goalCents | integer or null | |
items[].fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
items[].readiness | array of string | What must be fixed before the store can open (empty = ready). |
items[].urls | object | |
items[].urls.path | string | On the app: /store/{subdomain} (always works). |
items[].urls.appUrl | string | |
items[].urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
items[].urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items[].publishedAt | string (date-time) or null | |
items[].closedAt | string (date-time) or null | |
items[].createdAt | string (date-time) | |
items[].updatedAt | string (date-time) |
Create an online store
POST /organizations/{organizationId}/stores
Creates a DRAFT store (nothing is public until POST /stores/{storeId}/publish). Its address comes from the business and store names unless subdomain is given; shipping starts with the kind's defaults. categories adds category tiles; productIds (GET /products) adds catalog products, each in the category its kind and name suggest. To start from an AI draft of the banner and categories, call POST /stores/draft first. For a whole store in one call for a customer, see POST /workflows/store-for-customer.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_create (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
slug | string or null | No | URL segment in the business (made from the name when blank). Up to 80 characters. |
subdomain | string | No | Its address on the sites domain: 3–40 lower-case letters, numbers and hyphens. Up to 40 characters. |
kind | enum | No | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
customerId | string or null | No | The customer the store is for (GET /customers); required for INVOICE_ACCOUNT and FREE (they are billed). |
opensOn | string or null | No | A calendar date in the business's own calendar, YYYY-MM-DD. |
closesOn | string or null | No | The order deadline (orders taken through the end of this day). |
theme | object or null | No | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | No | |
theme.accentColor | string | No | |
theme.font | string | No | |
theme.radius | string | No | |
theme.headerStyle | string | No | |
logoUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
heroImageUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
heroTitle | string or null | No | Up to 120 characters. |
heroText | string or null | No | Up to 400 characters. |
access | enum | No | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
password | string or null | No | Sets the store password (PASSWORD access); null removes it. Never returned. Up to 100 characters. |
allowedEmailDomains | array of string | No | Up to 20 items. |
checkoutMode | enum | No | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | No | |
allowanceCents | integer or null | No | Free: what each person may spend, in cents. 0–100000000. |
fundraiserGoalCents | integer or null | No | 0–100000000. |
fundraiserPercent | number or null | No | Fundraiser: the share of each order's goods subtotal raised, percent. 0–100. |
shippingOptions | array of object | No | Choices at checkout: kind SHIP (to each person; rate FREE, FLAT flatCents or TABLE by goods subtotal), BULK (one delivery to the organization) or PICKUP; note shows under the choice. Up to 10 items. |
shippingOptions[].id | string | Yes | |
shippingOptions[].kind | enum | Yes | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Yes | Up to 80 characters. |
shippingOptions[].rate | enum | Yes | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | No | 0–1000000. Default 0. |
shippingOptions[].table | array of object | No | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | Yes | 0–100000000. |
shippingOptions[].table[].cents | integer | Yes | 0–1000000. |
shippingOptions[].note | string | No | Up to 500 characters. Default ``. |
taxRate | number | No | Sales tax percent on goods and shipping (as invoices); tax-exempt customers pay none. With taxByAddress, the rate where no tax rule covers the address (and of pickup and bulk orders). 0–30. |
taxByAddress | boolean | No | Tax shipped orders by the business's tax rules for the ship-to address (Settings → Taxes) instead of one rate. |
priceMode | enum | No | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | No | 0–1000. |
roundTo99 | boolean | No | |
returnsPolicy | string or null | No | Your returns policy; null = the default wording. |
guaranteePolicy | string or null | No | |
privacyPolicy | string or null | No | |
contactEmail | empty string or string (email) or null | No | |
contactPhone | string or null | No | Up to 40 characters. |
fulfilledBy | string or null | No | "Fulfilled by …" in the footer; null = the business's name. Up to 200 characters. |
categories | array of object | No | Up to 30 items. |
categories[].name | string | Yes | Up to 60 characters. |
categories[].imageUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
productIds | array of string | No | Catalog products to sell. Up to 300 items. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | |
subdomain | string | Its address on the sites domain (unique across stores and websites). |
kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
opensOn | string or null | |
closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
daysLeft | integer or null | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
customer.taxExempt | boolean | |
theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | |
theme.accentColor | string | |
theme.font | string | |
theme.radius | string | |
theme.headerStyle | string | |
logoUrl | string or null | |
heroImageUrl | string or null | |
heroTitle | string or null | |
heroText | string or null | |
access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
hasPassword | boolean | A password is set (it is never returned). |
allowedEmailDomains | array of string | |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | |
allowanceCents | integer or null | |
fundraiserGoalCents | integer or null | |
fundraiserPercent | number or null | |
shippingOptions | array of object | Up to 10 items. |
shippingOptions[].id | string | |
shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Up to 80 characters. |
shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
shippingOptions[].table | array of object | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | 0–100000000. |
shippingOptions[].table[].cents | integer | 0–1000000. |
shippingOptions[].note | string | Up to 500 characters. Default ``. |
taxRate | number | |
taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
roundTo99 | boolean | |
policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
policies.returns | string | |
policies.guarantee | string | |
policies.privacy | string | |
returnsPolicy | string or null | |
guaranteePolicy | string or null | |
privacyPolicy | string or null | |
contactEmail | string or null | |
contactPhone | string or null | |
fulfilledBy | string or null | |
categories | array of object | |
categories[].id | string | |
categories[].name | string | |
categories[].slug | string | |
categories[].imageUrl | string or null | |
categories[].sortOrder | integer | |
productCount | integer | |
inviteCount | integer | |
orderCount | integer | Paid or approved orders. |
salesCents | integer | Totals of paid or approved orders. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
readiness | array of string | What must be fixed before the store can open (empty = ready). |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
publishedAt | string (date-time) or null | |
closedAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
An online store
GET /organizations/{organizationId}/stores/{storeId}
One store with its branding, categories, access, checkout, shipping, tax, pricing, policies (as shown), addresses, sales, fundraiser progress and readiness (what must be fixed before it can open). Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_get (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | |
subdomain | string | Its address on the sites domain (unique across stores and websites). |
kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
opensOn | string or null | |
closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
daysLeft | integer or null | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
customer.taxExempt | boolean | |
theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | |
theme.accentColor | string | |
theme.font | string | |
theme.radius | string | |
theme.headerStyle | string | |
logoUrl | string or null | |
heroImageUrl | string or null | |
heroTitle | string or null | |
heroText | string or null | |
access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
hasPassword | boolean | A password is set (it is never returned). |
allowedEmailDomains | array of string | |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | |
allowanceCents | integer or null | |
fundraiserGoalCents | integer or null | |
fundraiserPercent | number or null | |
shippingOptions | array of object | Up to 10 items. |
shippingOptions[].id | string | |
shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Up to 80 characters. |
shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
shippingOptions[].table | array of object | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | 0–100000000. |
shippingOptions[].table[].cents | integer | 0–1000000. |
shippingOptions[].note | string | Up to 500 characters. Default ``. |
taxRate | number | |
taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
roundTo99 | boolean | |
policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
policies.returns | string | |
policies.guarantee | string | |
policies.privacy | string | |
returnsPolicy | string or null | |
guaranteePolicy | string or null | |
privacyPolicy | string or null | |
contactEmail | string or null | |
contactPhone | string or null | |
fulfilledBy | string or null | |
categories | array of object | |
categories[].id | string | |
categories[].name | string | |
categories[].slug | string | |
categories[].imageUrl | string or null | |
categories[].sortOrder | integer | |
productCount | integer | |
inviteCount | integer | |
orderCount | integer | Paid or approved orders. |
salesCents | integer | Totals of paid or approved orders. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
readiness | array of string | What must be fixed before the store can open (empty = ready). |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
publishedAt | string (date-time) or null | |
closedAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Change an online store
PATCH /organizations/{organizationId}/stores/{storeId}
Changes the fields sent. Changing the password, the access kind or the email domains sends every shopper back through the gate. An OPEN store changes for shoppers at once.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_update (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Up to 200 characters. |
slug | string or null | No | URL segment in the business (made from the name when blank). Up to 80 characters. |
subdomain | string | No | Its address on the sites domain: 3–40 lower-case letters, numbers and hyphens. Up to 40 characters. |
kind | enum | No | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
customerId | string or null | No | The customer the store is for (GET /customers); required for INVOICE_ACCOUNT and FREE (they are billed). |
opensOn | string or null | No | A calendar date in the business's own calendar, YYYY-MM-DD. |
closesOn | string or null | No | The order deadline (orders taken through the end of this day). |
theme | object or null | No | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | No | |
theme.accentColor | string | No | |
theme.font | string | No | |
theme.radius | string | No | |
theme.headerStyle | string | No | |
logoUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
heroImageUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
heroTitle | string or null | No | Up to 120 characters. |
heroText | string or null | No | Up to 400 characters. |
access | enum | No | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
password | string or null | No | Sets the store password (PASSWORD access); null removes it. Never returned. Up to 100 characters. |
allowedEmailDomains | array of string | No | Up to 20 items. |
checkoutMode | enum | No | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | No | |
allowanceCents | integer or null | No | Free: what each person may spend, in cents. 0–100000000. |
fundraiserGoalCents | integer or null | No | 0–100000000. |
fundraiserPercent | number or null | No | Fundraiser: the share of each order's goods subtotal raised, percent. 0–100. |
shippingOptions | array of object | No | Choices at checkout: kind SHIP (to each person; rate FREE, FLAT flatCents or TABLE by goods subtotal), BULK (one delivery to the organization) or PICKUP; note shows under the choice. Up to 10 items. |
shippingOptions[].id | string | Yes | |
shippingOptions[].kind | enum | Yes | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Yes | Up to 80 characters. |
shippingOptions[].rate | enum | Yes | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | No | 0–1000000. Default 0. |
shippingOptions[].table | array of object | No | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | Yes | 0–100000000. |
shippingOptions[].table[].cents | integer | Yes | 0–1000000. |
shippingOptions[].note | string | No | Up to 500 characters. Default ``. |
taxRate | number | No | Sales tax percent on goods and shipping (as invoices); tax-exempt customers pay none. With taxByAddress, the rate where no tax rule covers the address (and of pickup and bulk orders). 0–30. |
taxByAddress | boolean | No | Tax shipped orders by the business's tax rules for the ship-to address (Settings → Taxes) instead of one rate. |
priceMode | enum | No | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | No | 0–1000. |
roundTo99 | boolean | No | |
returnsPolicy | string or null | No | Your returns policy; null = the default wording. |
guaranteePolicy | string or null | No | |
privacyPolicy | string or null | No | |
contactEmail | empty string or string (email) or null | No | |
contactPhone | string or null | No | Up to 40 characters. |
fulfilledBy | string or null | No | "Fulfilled by …" in the footer; null = the business's name. Up to 200 characters. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","slug":"string","subdomain":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | |
subdomain | string | Its address on the sites domain (unique across stores and websites). |
kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
opensOn | string or null | |
closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
daysLeft | integer or null | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
customer.taxExempt | boolean | |
theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | |
theme.accentColor | string | |
theme.font | string | |
theme.radius | string | |
theme.headerStyle | string | |
logoUrl | string or null | |
heroImageUrl | string or null | |
heroTitle | string or null | |
heroText | string or null | |
access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
hasPassword | boolean | A password is set (it is never returned). |
allowedEmailDomains | array of string | |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | |
allowanceCents | integer or null | |
fundraiserGoalCents | integer or null | |
fundraiserPercent | number or null | |
shippingOptions | array of object | Up to 10 items. |
shippingOptions[].id | string | |
shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Up to 80 characters. |
shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
shippingOptions[].table | array of object | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | 0–100000000. |
shippingOptions[].table[].cents | integer | 0–1000000. |
shippingOptions[].note | string | Up to 500 characters. Default ``. |
taxRate | number | |
taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
roundTo99 | boolean | |
policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
policies.returns | string | |
policies.guarantee | string | |
policies.privacy | string | |
returnsPolicy | string or null | |
guaranteePolicy | string or null | |
privacyPolicy | string or null | |
contactEmail | string or null | |
contactPhone | string or null | |
fulfilledBy | string or null | |
categories | array of object | |
categories[].id | string | |
categories[].name | string | |
categories[].slug | string | |
categories[].imageUrl | string or null | |
categories[].sortOrder | integer | |
productCount | integer | |
inviteCount | integer | |
orderCount | integer | Paid or approved orders. |
salesCents | integer | Totals of paid or approved orders. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
readiness | array of string | What must be fixed before the store can open (empty = ready). |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
publishedAt | string (date-time) or null | |
closedAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Delete an online store
DELETE /organizations/{organizationId}/stores/{storeId}
Destructive: deletes a store that never took an order, with its products, categories, invites and shopper carts; its address stops working. A store with orders is 409: close it instead.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | stores_delete (toolset stores) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
Open a store for orders
POST /organizations/{organizationId}/stores/{storeId}/publish
Customer-visible: makes the store public at its address and takes orders between its dates (a CLOSED store reopens). 409 with the list when something is missing (readiness: products, shipping, the paying customer, the allowance, the password, email domains, the fundraiser share).
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | stores_publish (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/publish" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | |
subdomain | string | Its address on the sites domain (unique across stores and websites). |
kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
opensOn | string or null | |
closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
daysLeft | integer or null | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
customer.taxExempt | boolean | |
theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | |
theme.accentColor | string | |
theme.font | string | |
theme.radius | string | |
theme.headerStyle | string | |
logoUrl | string or null | |
heroImageUrl | string or null | |
heroTitle | string or null | |
heroText | string or null | |
access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
hasPassword | boolean | A password is set (it is never returned). |
allowedEmailDomains | array of string | |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | |
allowanceCents | integer or null | |
fundraiserGoalCents | integer or null | |
fundraiserPercent | number or null | |
shippingOptions | array of object | Up to 10 items. |
shippingOptions[].id | string | |
shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Up to 80 characters. |
shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
shippingOptions[].table | array of object | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | 0–100000000. |
shippingOptions[].table[].cents | integer | 0–1000000. |
shippingOptions[].note | string | Up to 500 characters. Default ``. |
taxRate | number | |
taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
roundTo99 | boolean | |
policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
policies.returns | string | |
policies.guarantee | string | |
policies.privacy | string | |
returnsPolicy | string or null | |
guaranteePolicy | string or null | |
privacyPolicy | string or null | |
contactEmail | string or null | |
contactPhone | string or null | |
fulfilledBy | string or null | |
categories | array of object | |
categories[].id | string | |
categories[].name | string | |
categories[].slug | string | |
categories[].imageUrl | string or null | |
categories[].sortOrder | integer | |
productCount | integer | |
inviteCount | integer | |
orderCount | integer | Paid or approved orders. |
salesCents | integer | Totals of paid or approved orders. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
readiness | array of string | What must be fixed before the store can open (empty = ready). |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
publishedAt | string (date-time) or null | |
closedAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Close a store
POST /organizations/{organizationId}/stores/{storeId}/close
Stops orders and makes its production batch final: answers the store and the batch (units per product, colour and size over paid and approved orders, the personalised lines to print and how orders are delivered) — the production and blank purchase list. The storefront stays up saying it is closed. POST /publish reopens it.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_close (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/close" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
store | object | |
store.id | string | |
store.name | string | |
store.slug | string | |
store.subdomain | string | Its address on the sites domain (unique across stores and websites). |
store.kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
store.status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
store.availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
store.opensOn | string or null | |
store.closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
store.daysLeft | integer or null | |
store.customerId | string or null | |
store.customer | object or null | |
store.customer.id | string | |
store.customer.name | string | |
store.customer.taxExempt | boolean | |
store.theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
store.theme.primaryColor | string | |
store.theme.accentColor | string | |
store.theme.font | string | |
store.theme.radius | string | |
store.theme.headerStyle | string | |
store.logoUrl | string or null | |
store.heroImageUrl | string or null | |
store.heroTitle | string or null | |
store.heroText | string or null | |
store.access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
store.hasPassword | boolean | A password is set (it is never returned). |
store.allowedEmailDomains | array of string | |
store.checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
store.requireApproval | boolean | |
store.allowanceCents | integer or null | |
store.fundraiserGoalCents | integer or null | |
store.fundraiserPercent | number or null | |
store.shippingOptions | array of object | Up to 10 items. |
store.shippingOptions[].id | string | |
store.shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
store.shippingOptions[].label | string | Up to 80 characters. |
store.shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
store.shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
store.shippingOptions[].table | array of object | Up to 10 items. Default []. |
store.shippingOptions[].note | string | Up to 500 characters. Default ``. |
store.taxRate | number | |
store.taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
store.priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
store.markupPercent | number or null | |
store.roundTo99 | boolean | |
store.policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
store.policies.returns | string | |
store.policies.guarantee | string | |
store.policies.privacy | string | |
store.returnsPolicy | string or null | |
store.guaranteePolicy | string or null | |
store.privacyPolicy | string or null | |
store.contactEmail | string or null | |
store.contactPhone | string or null | |
store.fulfilledBy | string or null | |
store.categories | array of object | |
store.categories[].id | string | |
store.categories[].name | string | |
store.categories[].slug | string | |
store.categories[].imageUrl | string or null | |
store.categories[].sortOrder | integer | |
store.productCount | integer | |
store.inviteCount | integer | |
store.orderCount | integer | Paid or approved orders. |
store.salesCents | integer | Totals of paid or approved orders. |
store.fundraiser | object or null | |
store.fundraiser.raisedCents | integer | Integer cents. |
store.fundraiser.goalCents | integer or null | |
store.fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
store.readiness | array of string | What must be fixed before the store can open (empty = ready). |
store.urls | object | |
store.urls.path | string | On the app: /store/{subdomain} (always works). |
store.urls.appUrl | string | |
store.urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
store.urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
store.publishedAt | string (date-time) or null | |
store.closedAt | string (date-time) or null | |
store.createdAt | string (date-time) | |
store.updatedAt | string (date-time) | |
batch | object |
Set a store's categories
POST /organizations/{organizationId}/stores/{storeId}/categories
Replaces the store's category tiles with this ordered list (keep an existing one by its id; a missing one is removed and its products lose their category). Up to 30.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_setCategories (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
categories | array of object | Yes | Up to 30 items. |
categories[].id | string or null | No | An existing category (from the store) to keep. |
categories[].name | string | Yes | Up to 60 characters. |
categories[].imageUrl | string or null | No | An image from POST /stores/images (/image-proxy/avatars/store-…) or an https URL. Up to 2000 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/categories" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"categories":[{"name":"Dana Whitfield"}]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
name | string | |
slug | string | |
subdomain | string | Its address on the sites domain (unique across stores and websites). |
kind | enum | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
status | enum | DRAFT (being built), OPEN (taking orders between its dates) or CLOSED. One of DRAFT, OPEN, CLOSED. |
availability | enum | Whether it takes orders today (status and dates). One of DRAFT, NOT_OPEN_YET, OPEN, CLOSED. |
opensOn | string or null | |
closesOn | string or null | The order deadline (inclusive), YYYY-MM-DD. |
daysLeft | integer or null | |
customerId | string or null | |
customer | object or null | |
customer.id | string | |
customer.name | string | |
customer.taxExempt | boolean | |
theme | object | The website theme: primaryColor and accentColor (#rrggbb), font (modern, classic, friendly, bold, elegant, geometric), radius (square, soft, round), headerStyle (light, dark, brand). |
theme.primaryColor | string | |
theme.accentColor | string | |
theme.font | string | |
theme.radius | string | |
theme.headerStyle | string | |
logoUrl | string or null | |
heroImageUrl | string or null | |
heroTitle | string or null | |
heroText | string or null | |
access | enum | Who may enter: PUBLIC, PASSWORD (a shared password), EMAIL_DOMAIN (an email at one of allowedEmailDomains, not verified) or INVITE (each person's own invite link). One of PUBLIC, PASSWORD, EMAIL_DOMAIN, INVITE. |
hasPassword | boolean | A password is set (it is never returned). |
allowedEmailDomains | array of string | |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
requireApproval | boolean | |
allowanceCents | integer or null | |
fundraiserGoalCents | integer or null | |
fundraiserPercent | number or null | |
shippingOptions | array of object | Up to 10 items. |
shippingOptions[].id | string | |
shippingOptions[].kind | enum | One of SHIP, BULK, PICKUP. |
shippingOptions[].label | string | Up to 80 characters. |
shippingOptions[].rate | enum | One of FREE, FLAT, TABLE. |
shippingOptions[].flatCents | integer | 0–1000000. Default 0. |
shippingOptions[].table | array of object | Up to 10 items. Default []. |
shippingOptions[].table[].minSubtotalCents | integer | 0–100000000. |
shippingOptions[].table[].cents | integer | 0–1000000. |
shippingOptions[].note | string | Up to 500 characters. Default ``. |
taxRate | number | |
taxByAddress | boolean | Shipped orders are taxed by the business's tax rules for the address. |
priceMode | enum | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
roundTo99 | boolean | |
policies | object | The policy pages as shoppers see them (the store's own words, else the default). |
policies.returns | string | |
policies.guarantee | string | |
policies.privacy | string | |
returnsPolicy | string or null | |
guaranteePolicy | string or null | |
privacyPolicy | string or null | |
contactEmail | string or null | |
contactPhone | string or null | |
fulfilledBy | string or null | |
categories | array of object | |
categories[].id | string | |
categories[].name | string | |
categories[].slug | string | |
categories[].imageUrl | string or null | |
categories[].sortOrder | integer | |
productCount | integer | |
inviteCount | integer | |
orderCount | integer | Paid or approved orders. |
salesCents | integer | Totals of paid or approved orders. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
readiness | array of string | What must be fixed before the store can open (empty = ready). |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
publishedAt | string (date-time) or null | |
closedAt | string (date-time) or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
A store's sales
GET /organizations/{organizationId}/stores/{storeId}/dashboard
Orders by status, paid/approved orders, sales, units sold, average order, fundraiser progress, the top five products and the latest orders. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_dashboard (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/dashboard" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
ordersByStatus | object | |
orderCount | integer | |
salesCents | integer | Integer cents. |
unitsSold | integer | |
averageOrderCents | integer | Integer cents. |
fundraiser | object or null | |
fundraiser.raisedCents | integer | Integer cents. |
fundraiser.goalCents | integer or null | |
fundraiser.percent | number or null | Share of the goal raised (may pass 100). |
topProducts | array of object | |
topProducts[].productName | string | |
topProducts[].units | integer | |
topProducts[].salesCents | integer | Integer cents. |
recentOrders | array of object | |
recentOrders[].id | string | |
recentOrders[].identifier | string | |
recentOrders[].status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
recentOrders[].buyerName | string | |
recentOrders[].totalCents | integer | Integer cents. |
recentOrders[].createdAt | string (date-time) |
A store's production batch
GET /organizations/{organizationId}/stores/{storeId}/batch
The group order so far (final once the store is closed): units per product (with its decoration and design), colour and size over paid and approved orders — what to produce and which blanks to buy — plus the personalised lines (names, numbers) to print and the delivery methods. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_batch (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/batch" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
orderCount | integer | |
totalUnits | integer | |
products | array of object | |
products[].productId | string or null | |
products[].productName | string | |
products[].styleNumber | string or null | |
products[].decorationName | string or null | |
products[].designId | string or null | |
products[].totalUnits | integer | |
products[].sizes | array of string | |
products[].colors | array of object | |
products[].colors[].colorName | string or null | |
products[].colors[].totalUnits | integer | |
products[].colors[].sizes | array of object | |
personalized | array of object | |
personalized[].orderIdentifier | string | |
personalized[].buyerName | string | |
personalized[].productName | string | |
personalized[].colorName | string or null | |
personalized[].size | string or null | |
personalized[].quantity | integer | |
personalized[].values | string | |
shipping | array of object | |
shipping[].label | string | |
shipping[].kind | string | |
shipping[].orders | integer |
Export a store's orders (CSV)
GET /organizations/{organizationId}/stores/{storeId}/orders/export
Every order line of the store as CSV text (order, date, status, name, email, delivery, address, cost centre, product, SKU, colour, size, personalisation, quantity, prices), optionally one status only. Spreadsheet formulas are neutralised. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_exportOrders (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
status | query | enum | No | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/orders/export" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
filename | string | |
contentType | string | |
orderCount | integer | |
csv | string |
Draft a store's banner and categories
POST /organizations/{organizationId}/stores/draft
Suggests a store name, banner title and text, category tiles and an address from the business's name, the customer's (optional) and the products chosen. Written by Claude when configured (uses AI credits), else a template; never invents facts (no prices, deadlines or promises). Creates nothing: pass the result to POST /stores.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_draft (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
kind | enum | Yes | COMPANY (a company's branded store), TEAM (players and parents order by a deadline), FUNDRAISER (part of each sale goes to a cause, with a goal) or RETAIL (the business's own shop). One of COMPANY, TEAM, FUNDRAISER, RETAIL. |
name | string or null | No | Up to 200 characters. |
customerId | string or null | No | The customer the store is for. |
productIds | array of string | No | Up to 300 items. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/draft" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"COMPANY"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
name | string | |
heroTitle | string | |
heroText | string | |
categories | array of string | |
source | enum | One of AI, TEMPLATE. |
suggestedSubdomain | string |
Upload a store picture
POST /organizations/{organizationId}/stores/images
Stores a picture in one call — contentBase64 (JPEG, PNG, WebP or GIF, up to 8 MB) or a public sourceUrl SKUFlow downloads through its SSRF guard — and answers its url for a store's logo, banner, category tile or a product's decorated mockup (PATCH /stores/{storeId}/products/{storeProductId} mockups).
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_uploadImage (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
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. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/images" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileName":"string","contentType":"string","contentBase64":"string"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
url | string | |
contentType | string |
A store's invites
GET /organizations/{organizationId}/stores/{storeId}/invites
The people invited to an INVITE store, each with their own link (their key to the store) and when it was last used. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_invites (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/invites" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].email | string | |
items[].name | string or null | |
items[].url | string | |
items[].lastUsedAt | string (date-time) or null | |
items[].createdAt | string (date-time) |
Invite people to a store
POST /organizations/{organizationId}/stores/{storeId}/invites
Grants access: gives each email its own invite link to the store (people already invited keep theirs). SKUFlow does not email the links: share them (the answer lists every invite with its url).
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | stores_addInvites (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
people | array of object | Yes | Up to 500 items. |
people[].email | string (email) | Yes | Up to 254 characters. |
people[].name | string or null | No | Up to 200 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/invites" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"people":[{"email":"dana@example.com"}]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].email | string | |
items[].name | string or null | |
items[].url | string | |
items[].lastUsedAt | string (date-time) or null | |
items[].createdAt | string (date-time) |
A store's custom domains
GET /organizations/{organizationId}/stores/{storeId}/domains
The store's own domains (e.g. shop.example.com) with their status and every DNS record to add. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | stores_domains (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/domains" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items | array of object | |
items[].id | string | |
items[].hostname | string | |
items[].status | enum | ACTIVE domains serve the store; PENDING waits for DNS; FAILED after three days. One of PENDING, ACTIVE, FAILED. |
items[].isPrimary | boolean | The address shopper links use once it is ACTIVE. |
items[].lastError | string or null | What the last DNS check found missing. |
items[].apex | boolean | A bare domain (example.com): A records instead of a CNAME. |
items[].cnameTarget | string | Where a CNAME points (SKUFlow's sites host). |
items[].records | array of object | Every DNS record to add at the domain's DNS host. |
items[].records[].type | string | |
items[].records[].name | string | Relative to the domain, as most DNS providers ask. |
items[].records[].fullName | string | |
items[].records[].value | string |
Connect a custom domain to a store
POST /organizations/{organizationId}/stores/{storeId}/domains
Adds a domain (e.g. shop.example.com) as PENDING. The business adds every record in records (the ownership TXT and a CNAME, or A records for a bare domain); the domain becomes ACTIVE once the checks pass (every ten minutes, or POST …/verify), then serves the storefront and becomes the address in shopper links and emails. Up to three per store; a domain can't belong to a website and a store at once.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_addDomain (toolset stores) |
| Plan | Custom domain: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
hostname | string | Yes | Up to 260 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/domains" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"hostname":"string"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items | array of object | |
items[].id | string | |
items[].hostname | string | |
items[].status | enum | ACTIVE domains serve the store; PENDING waits for DNS; FAILED after three days. One of PENDING, ACTIVE, FAILED. |
items[].isPrimary | boolean | The address shopper links use once it is ACTIVE. |
items[].lastError | string or null | What the last DNS check found missing. |
items[].apex | boolean | A bare domain (example.com): A records instead of a CNAME. |
items[].cnameTarget | string | Where a CNAME points (SKUFlow's sites host). |
items[].records | array of object | Every DNS record to add at the domain's DNS host. |
items[].records[].type | string | |
items[].records[].name | string | Relative to the domain, as most DNS providers ask. |
items[].records[].fullName | string | |
items[].records[].value | string |
Check a store domain's DNS now
POST /organizations/{organizationId}/stores/{storeId}/domains/{domainId}/verify
Runs the DNS checks for one store domain now; lastError says what is missing. ACTIVE domains serve the store.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_verifyDomain (toolset stores) |
| Plan | Custom domain: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
domainId | path | string | Yes | The custom domain (GET /stores/{storeId}/domains). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/domains/{domainId}/verify" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items | array of object | |
items[].id | string | |
items[].hostname | string | |
items[].status | enum | ACTIVE domains serve the store; PENDING waits for DNS; FAILED after three days. One of PENDING, ACTIVE, FAILED. |
items[].isPrimary | boolean | The address shopper links use once it is ACTIVE. |
items[].lastError | string or null | What the last DNS check found missing. |
items[].apex | boolean | A bare domain (example.com): A records instead of a CNAME. |
items[].cnameTarget | string | Where a CNAME points (SKUFlow's sites host). |
items[].records | array of object | Every DNS record to add at the domain's DNS host. |
items[].records[].type | string | |
items[].records[].name | string | Relative to the domain, as most DNS providers ask. |
items[].records[].fullName | string | |
items[].records[].value | string |
Make a domain the store's main address
POST /organizations/{organizationId}/stores/{storeId}/domains/{domainId}/primary
Shopper links (invites, order confirmations, checkout returns) use this domain once it is ACTIVE.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | stores_setPrimaryDomain (toolset stores) |
| Plan | Custom domain: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
domainId | path | string | Yes | The custom domain (GET /stores/{storeId}/domains). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/domains/{domainId}/primary" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items | array of object | |
items[].id | string | |
items[].hostname | string | |
items[].status | enum | ACTIVE domains serve the store; PENDING waits for DNS; FAILED after three days. One of PENDING, ACTIVE, FAILED. |
items[].isPrimary | boolean | The address shopper links use once it is ACTIVE. |
items[].lastError | string or null | What the last DNS check found missing. |
items[].apex | boolean | A bare domain (example.com): A records instead of a CNAME. |
items[].cnameTarget | string | Where a CNAME points (SKUFlow's sites host). |
items[].records | array of object | Every DNS record to add at the domain's DNS host. |
items[].records[].type | string | |
items[].records[].name | string | Relative to the domain, as most DNS providers ask. |
items[].records[].fullName | string | |
items[].records[].value | string |
Disconnect a store domain
DELETE /organizations/{organizationId}/stores/{storeId}/domains/{domainId}
Destructive: the domain stops serving the store at once; links already sent with it stop working (the store stays at its SKUFlow address).
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | stores_removeDomain (toolset stores) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
domainId | path | string | Yes | The custom domain (GET /stores/{storeId}/domains). |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/domains/{domainId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
storeId | string | |
urls | object | |
urls.path | string | On the app: /store/{subdomain} (always works). |
urls.appUrl | string | |
urls.defaultUrl | string or null | https://{subdomain}.{sites domain} when the sites domain is configured. |
urls.customUrl | string or null | https://{custom domain} when the store has an ACTIVE custom domain (shopper links use it). |
items | array of object | |
items[].id | string | |
items[].hostname | string | |
items[].status | enum | ACTIVE domains serve the store; PENDING waits for DNS; FAILED after three days. One of PENDING, ACTIVE, FAILED. |
items[].isPrimary | boolean | The address shopper links use once it is ACTIVE. |
items[].lastError | string or null | What the last DNS check found missing. |
items[].apex | boolean | A bare domain (example.com): A records instead of a CNAME. |
items[].cnameTarget | string | Where a CNAME points (SKUFlow's sites host). |
items[].records | array of object | Every DNS record to add at the domain's DNS host. |
items[].records[].type | string | |
items[].records[].name | string | Relative to the domain, as most DNS providers ask. |
items[].records[].fullName | string | |
items[].records[].value | string |
Remove an invite
DELETE /organizations/{organizationId}/stores/{storeId}/invites/{inviteId}
Revokes access: the person's link stops working and their shopper session must pass the gate again.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | stores_deleteInvite (toolset stores) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
inviteId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/invites/{inviteId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
A store's products
GET /organizations/{organizationId}/stores/{storeId}/products
The catalog products sold in a store with the colours and sizes offered, the store price range, decoration, mockups and personalisation fields. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | storeProducts_list (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/products" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].storeId | string | |
items[].productId | string | |
items[].categoryId | string or null | |
items[].category | object or null | |
items[].category.id | string | |
items[].category.name | string | |
items[].displayName | string | |
items[].name | string or null | |
items[].description | string or null | |
items[].sortOrder | integer | |
items[].active | boolean | |
items[].colors | array of string | Colours offered; empty = every active colour. |
items[].sizes | array of string | Sizes offered; empty = every size. |
items[].priceMode | enum or null | Null follows the store's pricing. One of CATALOG, MARKUP, FIXED. |
items[].markupPercent | number or null | |
items[].fixedPriceCents | integer or null | |
items[].sizeUpchargeCents | object | |
items[].roundTo99 | boolean or null | |
items[].designId | string or null | The decoration design of this product (GET /designs/{designId}); its rendered mockups show after uploaded ones. |
items[].decorationName | string or null | |
items[].decorationPriceCents | integer | Integer cents. |
items[].mockups | array of object | |
items[].mockups[].id | string | Up to 40 characters. |
items[].mockups[].colorName | string or null | Up to 200 characters. |
items[].mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
items[].mockups[].url | string | Up to 2000 characters. |
items[].personalization | array of object | Up to 5 items. |
items[].personalization[].key | string | |
items[].personalization[].label | string | Up to 60 characters. |
items[].personalization[].kind | enum | One of TEXT, NUMBER. |
items[].personalization[].maxLength | integer | 1–40. Default 12. |
items[].personalization[].priceCents | integer | 0–100000. Default 0. |
items[].personalization[].required | boolean | Default false. |
items[].product | object | |
items[].product.id | string | |
items[].product.name | string | |
items[].product.slug | string | |
items[].product.image | string or null | |
items[].product.availableColors | array of object | |
items[].product.availableSizes | array of string | |
items[].variantCount | integer | |
items[].priceFromCents | integer or null | The lowest store price offered. |
items[].priceToCents | integer or null |
Add products to a store
POST /organizations/{organizationId}/stores/{storeId}/products
Adds catalog products (GET /products; active ones) to the store, into categoryId or, by default, the category each product's kind and name suggest (made when missing). Products already in the store are skipped. Prices follow the store's pricing until PATCHed. Up to 300 per store.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | storeProducts_add (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
productIds | array of string | Yes | Up to 300 items. |
categoryId | string or null | No | A category of this store. |
autoCategory | boolean | No | Put each product in its suggested category (default true). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/products" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"productIds":["product_id"]}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
added | integer | |
items | array of object | |
items[].id | string | |
items[].storeId | string | |
items[].productId | string | |
items[].categoryId | string or null | |
items[].category | object or null | |
items[].category.id | string | |
items[].category.name | string | |
items[].displayName | string | |
items[].name | string or null | |
items[].description | string or null | |
items[].sortOrder | integer | |
items[].active | boolean | |
items[].colors | array of string | Colours offered; empty = every active colour. |
items[].sizes | array of string | Sizes offered; empty = every size. |
items[].priceMode | enum or null | Null follows the store's pricing. One of CATALOG, MARKUP, FIXED. |
items[].markupPercent | number or null | |
items[].fixedPriceCents | integer or null | |
items[].sizeUpchargeCents | object | |
items[].roundTo99 | boolean or null | |
items[].designId | string or null | The decoration design of this product (GET /designs/{designId}); its rendered mockups show after uploaded ones. |
items[].decorationName | string or null | |
items[].decorationPriceCents | integer | Integer cents. |
items[].mockups | array of object | |
items[].mockups[].id | string | Up to 40 characters. |
items[].mockups[].colorName | string or null | Up to 200 characters. |
items[].mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
items[].mockups[].url | string | Up to 2000 characters. |
items[].personalization | array of object | Up to 5 items. |
items[].personalization[].key | string | |
items[].personalization[].label | string | Up to 60 characters. |
items[].personalization[].kind | enum | One of TEXT, NUMBER. |
items[].personalization[].maxLength | integer | 1–40. Default 12. |
items[].personalization[].priceCents | integer | 0–100000. Default 0. |
items[].personalization[].required | boolean | Default false. |
items[].product | object | |
items[].product.id | string | |
items[].product.name | string | |
items[].product.slug | string | |
items[].product.image | string or null | |
items[].product.availableColors | array of object | |
items[].product.availableSizes | array of string | |
items[].variantCount | integer | |
items[].priceFromCents | integer or null | The lowest store price offered. |
items[].priceToCents | integer or null |
Change a store product
PATCH /organizations/{organizationId}/stores/{storeId}/products/{storeProductId}
Changes the fields sent: category, display name and text, order, on or off, colours and sizes offered, pricing (priceMode, markupPercent, fixedPriceCents, size upcharges, roundTo99), decoration (name, per-unit price, designId), decorated mockups per colour and view (pictures from POST /stores/images) and personalisation fields (e.g. name and number, each with its price).
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | storeProducts_update (toolset stores) |
| Plan | Online stores: the Grow plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
storeProductId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
categoryId | string or null | No | |
name | string or null | No | Up to 200 characters. |
description | string or null | No | Up to 5000 characters. |
sortOrder | integer | No | 0–100000. |
active | boolean | No | |
colors | array of string | No | Up to 100 items. |
sizes | array of string | No | Up to 50 items. |
priceMode | enum or null | No | CATALOG (the catalog price + decoration), MARKUP (the catalog price raised by markupPercent + decoration) or FIXED (fixedPriceCents, all in). Size upcharges add on; CATALOG and MARKUP round up to .99 when roundTo99. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | No | 0–1000. |
fixedPriceCents | integer or null | No | 0–100000000. |
sizeUpchargeCents | object | No | |
roundTo99 | boolean or null | No | |
designId | string or null | No | A design of this product (GET /designs?productId=); its rendered mockups show in the store after uploaded ones. Null unlinks it. Up to 40 characters. |
decorationName | string or null | No | Up to 200 characters. |
decorationPriceCents | integer | No | 0–100000000. |
mockups | array of object | No | Up to 40 items. |
mockups[].id | string | Yes | Up to 40 characters. |
mockups[].colorName | string or null | Yes | Up to 200 characters. |
mockups[].view | enum | Yes | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].url | string | Yes | Up to 2000 characters. |
personalization | array of object | No | Up to 5 items. |
personalization[].key | string | Yes | |
personalization[].label | string | Yes | Up to 60 characters. |
personalization[].kind | enum | Yes | One of TEXT, NUMBER. |
personalization[].maxLength | integer | No | 1–40. Default 12. |
personalization[].priceCents | integer | No | 0–100000. Default 0. |
personalization[].required | boolean | No | Default false. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/products/{storeProductId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"categoryId":"category_id","name":"Dana Whitfield","description":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
storeId | string | |
productId | string | |
categoryId | string or null | |
category | object or null | |
category.id | string | |
category.name | string | |
displayName | string | |
name | string or null | |
description | string or null | |
sortOrder | integer | |
active | boolean | |
colors | array of string | Colours offered; empty = every active colour. |
sizes | array of string | Sizes offered; empty = every size. |
priceMode | enum or null | Null follows the store's pricing. One of CATALOG, MARKUP, FIXED. |
markupPercent | number or null | |
fixedPriceCents | integer or null | |
sizeUpchargeCents | object | |
roundTo99 | boolean or null | |
designId | string or null | The decoration design of this product (GET /designs/{designId}); its rendered mockups show after uploaded ones. |
decorationName | string or null | |
decorationPriceCents | integer | Integer cents. |
mockups | array of object | |
mockups[].id | string | Up to 40 characters. |
mockups[].colorName | string or null | Up to 200 characters. |
mockups[].view | enum | One of FRONT, BACK, SIDE, DETAIL, OTHER. |
mockups[].url | string | Up to 2000 characters. |
personalization | array of object | Up to 5 items. |
personalization[].key | string | |
personalization[].label | string | Up to 60 characters. |
personalization[].kind | enum | One of TEXT, NUMBER. |
personalization[].maxLength | integer | 1–40. Default 12. |
personalization[].priceCents | integer | 0–100000. Default 0. |
personalization[].required | boolean | Default false. |
product | object | |
product.id | string | |
product.name | string | |
product.slug | string | |
product.image | string or null | |
product.availableColors | array of object | |
product.availableColors[].name | string | |
product.availableColors[].hex | string or null | |
product.availableSizes | array of string | |
variantCount | integer | |
priceFromCents | integer or null | The lowest store price offered. |
priceToCents | integer or null |
Remove a product from a store
DELETE /organizations/{organizationId}/stores/{storeId}/products/{storeProductId}
Takes the product out of the store (the catalog product stays). Carts holding it show it as unavailable; past orders keep their snapshot.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | storeProducts_remove (toolset stores) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | path | string | Yes | The store (GET /stores). |
storeProductId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/stores/{storeId}/products/{storeProductId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
deleted | true |
List store orders
GET /organizations/{organizationId}/store-orders
Orders from the business's online stores, newest first, with their lines (snapshots), totals and invoice. Filter by store and status; query searches the order number, name and email. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | storeOrders_list (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeId | query | string | No | |
status | query | enum | No | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
query | query | string | No | 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/store-orders" \
-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[].identifier | string | SO-n. |
items[].storeId | string | |
items[].store | object | |
items[].store.id | string | |
items[].store.name | string | |
items[].status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
items[].checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
items[].customerId | string or null | Who is billed: the shopper (PAY_ONLINE) or the store's customer. |
items[].invoiceId | string or null | |
items[].invoice | object or null | |
items[].invoice.id | string | |
items[].invoice.identifier | string | |
items[].invoice.status | string | |
items[].buyerName | string | |
items[].buyerEmail | string | |
items[].buyerPhone | string or null | |
items[].shippingMethod | object | |
items[].shippingMethod.id | string | |
items[].shippingMethod.kind | string | |
items[].shippingMethod.label | string | |
items[].shippingAddress | object or null | |
items[].shippingAddress.name | string | |
items[].shippingAddress.line1 | string | |
items[].shippingAddress.line2 | string | |
items[].shippingAddress.city | string | |
items[].shippingAddress.state | string | |
items[].shippingAddress.postalCode | string | |
items[].shippingAddress.country | string | |
items[].subtotalCents | integer | Integer cents. |
items[].shippingCents | integer | Integer cents. |
items[].taxCents | integer | Integer cents. |
items[].totalCents | integer | Integer cents. |
items[].allowanceCents | integer | Integer cents. |
items[].raisedCents | integer | Integer cents. |
items[].approverName | string or null | |
items[].approverEmail | string or null | |
items[].costCenter | string or null | |
items[].poNumber | string or null | |
items[].note | string or null | |
items[].lines | array of object | |
items[].lines[].productName | string | |
items[].lines[].colorName | string or null | |
items[].lines[].size | string or null | |
items[].lines[].quantity | integer | |
items[].lines[].unitPriceCents | integer | Integer cents. |
items[].lines[].lineTotalCents | integer | Integer cents. |
items[].lines[].personalization | array of object | |
items[].orderUrl | string | The shopper's confirmation page. |
items[].placedAt | string (date-time) or null | |
items[].createdAt | string (date-time) |
A store order
GET /organizations/{organizationId}/store-orders/{storeOrderId}
One order with its lines, delivery, totals, approver and cost centre, and its invoice. Read-only.
| Permission | stores.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | storeOrders_get (toolset stores) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeOrderId | path | string | Yes | The store order (GET /store-orders). |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/store-orders/{storeOrderId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | SO-n. |
storeId | string | |
store | object | |
store.id | string | |
store.name | string | |
status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
customerId | string or null | Who is billed: the shopper (PAY_ONLINE) or the store's customer. |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
buyerName | string | |
buyerEmail | string | |
buyerPhone | string or null | |
shippingMethod | object | |
shippingMethod.id | string | |
shippingMethod.kind | string | |
shippingMethod.label | string | |
shippingAddress | object or null | |
shippingAddress.name | string | |
shippingAddress.line1 | string | |
shippingAddress.line2 | string | |
shippingAddress.city | string | |
shippingAddress.state | string | |
shippingAddress.postalCode | string | |
shippingAddress.country | string | |
subtotalCents | integer | Integer cents. |
shippingCents | integer | Integer cents. |
taxCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
allowanceCents | integer | Integer cents. |
raisedCents | integer | Integer cents. |
approverName | string or null | |
approverEmail | string or null | |
costCenter | string or null | |
poNumber | string or null | |
note | string or null | |
lines | array of object | |
lines[].productName | string | |
lines[].colorName | string or null | |
lines[].size | string or null | |
lines[].quantity | integer | |
lines[].unitPriceCents | integer | Integer cents. |
lines[].lineTotalCents | integer | Integer cents. |
lines[].personalization | array of object | |
lines[].personalization[].key | string | |
lines[].personalization[].label | string | |
lines[].personalization[].value | string | |
orderUrl | string | The shopper's confirmation page. |
placedAt | string (date-time) or null | |
createdAt | string (date-time) |
Approve a company-paid order
POST /organizations/{organizationId}/store-orders/{storeOrderId}/approve
BILLS THE CUSTOMER and EMAILS THE SHOPPER: an AWAITING_APPROVAL order becomes PLACED (in the production batch); its invoice to the store's customer stays a draft to send (POST /invoices/{invoiceId}/send or as part of a combined invoice). 409 for any other status.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | storeOrders_approve (toolset stores) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeOrderId | path | string | Yes | The store order (GET /store-orders). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/store-orders/{storeOrderId}/approve" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | SO-n. |
storeId | string | |
store | object | |
store.id | string | |
store.name | string | |
status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
customerId | string or null | Who is billed: the shopper (PAY_ONLINE) or the store's customer. |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
buyerName | string | |
buyerEmail | string | |
buyerPhone | string or null | |
shippingMethod | object | |
shippingMethod.id | string | |
shippingMethod.kind | string | |
shippingMethod.label | string | |
shippingAddress | object or null | |
shippingAddress.name | string | |
shippingAddress.line1 | string | |
shippingAddress.line2 | string | |
shippingAddress.city | string | |
shippingAddress.state | string | |
shippingAddress.postalCode | string | |
shippingAddress.country | string | |
subtotalCents | integer | Integer cents. |
shippingCents | integer | Integer cents. |
taxCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
allowanceCents | integer | Integer cents. |
raisedCents | integer | Integer cents. |
approverName | string or null | |
approverEmail | string or null | |
costCenter | string or null | |
poNumber | string or null | |
note | string or null | |
lines | array of object | |
lines[].productName | string | |
lines[].colorName | string or null | |
lines[].size | string or null | |
lines[].quantity | integer | |
lines[].unitPriceCents | integer | Integer cents. |
lines[].lineTotalCents | integer | Integer cents. |
lines[].personalization | array of object | |
lines[].personalization[].key | string | |
lines[].personalization[].label | string | |
lines[].personalization[].value | string | |
orderUrl | string | The shopper's confirmation page. |
placedAt | string (date-time) or null | |
createdAt | string (date-time) |
Reject a company-paid order
POST /organizations/{organizationId}/store-orders/{storeOrderId}/reject
EMAILS THE SHOPPER (with the reason): an AWAITING_APPROVAL order becomes REJECTED and its draft invoice is cancelled; a FREE store gives the allowance back. 409 for any other status.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | storeOrders_reject (toolset stores) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeOrderId | path | string | Yes | The store order (GET /store-orders). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string or null | No | Up to 500 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/store-orders/{storeOrderId}/reject" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"reason":"string"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | SO-n. |
storeId | string | |
store | object | |
store.id | string | |
store.name | string | |
status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
customerId | string or null | Who is billed: the shopper (PAY_ONLINE) or the store's customer. |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
buyerName | string | |
buyerEmail | string | |
buyerPhone | string or null | |
shippingMethod | object | |
shippingMethod.id | string | |
shippingMethod.kind | string | |
shippingMethod.label | string | |
shippingAddress | object or null | |
shippingAddress.name | string | |
shippingAddress.line1 | string | |
shippingAddress.line2 | string | |
shippingAddress.city | string | |
shippingAddress.state | string | |
shippingAddress.postalCode | string | |
shippingAddress.country | string | |
subtotalCents | integer | Integer cents. |
shippingCents | integer | Integer cents. |
taxCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
allowanceCents | integer | Integer cents. |
raisedCents | integer | Integer cents. |
approverName | string or null | |
approverEmail | string or null | |
costCenter | string or null | |
poNumber | string or null | |
note | string or null | |
lines | array of object | |
lines[].productName | string | |
lines[].colorName | string or null | |
lines[].size | string or null | |
lines[].quantity | integer | |
lines[].unitPriceCents | integer | Integer cents. |
lines[].lineTotalCents | integer | Integer cents. |
lines[].personalization | array of object | |
lines[].personalization[].key | string | |
lines[].personalization[].label | string | |
lines[].personalization[].value | string | |
orderUrl | string | The shopper's confirmation page. |
placedAt | string (date-time) or null | |
createdAt | string (date-time) |
Cancel a store order
POST /organizations/{organizationId}/store-orders/{storeOrderId}/cancel
Destructive: cancels the order and its unpaid invoice; it leaves the batch and a FREE store gives the allowance back. A paid order is 409: refund its payment first (POST /payments/{paymentId}/refunds), then cancel. Fulfilled orders can't be cancelled.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | storeOrders_cancel (toolset stores) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
storeOrderId | path | string | Yes | The store order (GET /store-orders). |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/store-orders/{storeOrderId}/cancel" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
identifier | string | SO-n. |
storeId | string | |
store | object | |
store.id | string | |
store.name | string | |
status | enum | PENDING_PAYMENT (waiting for Stripe Checkout), AWAITING_APPROVAL (company-paid), PLACED (paid or approved: in the batch), FULFILLED, REJECTED or CANCELLED. One of PENDING_PAYMENT, AWAITING_APPROVAL, PLACED, FULFILLED, REJECTED, CANCELLED. |
checkoutMode | enum | PAY_ONLINE (shoppers pay by card on Stripe Checkout, on the business's connected account), INVOICE_ACCOUNT (the store's customer is invoiced; orders wait for approval) or FREE (the customer pays; each person spends from allowanceCents). One of PAY_ONLINE, INVOICE_ACCOUNT, FREE. |
customerId | string or null | Who is billed: the shopper (PAY_ONLINE) or the store's customer. |
invoiceId | string or null | |
invoice | object or null | |
invoice.id | string | |
invoice.identifier | string | |
invoice.status | string | |
buyerName | string | |
buyerEmail | string | |
buyerPhone | string or null | |
shippingMethod | object | |
shippingMethod.id | string | |
shippingMethod.kind | string | |
shippingMethod.label | string | |
shippingAddress | object or null | |
shippingAddress.name | string | |
shippingAddress.line1 | string | |
shippingAddress.line2 | string | |
shippingAddress.city | string | |
shippingAddress.state | string | |
shippingAddress.postalCode | string | |
shippingAddress.country | string | |
subtotalCents | integer | Integer cents. |
shippingCents | integer | Integer cents. |
taxCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
allowanceCents | integer | Integer cents. |
raisedCents | integer | Integer cents. |
approverName | string or null | |
approverEmail | string or null | |
costCenter | string or null | |
poNumber | string or null | |
note | string or null | |
lines | array of object | |
lines[].productName | string | |
lines[].colorName | string or null | |
lines[].size | string or null | |
lines[].quantity | integer | |
lines[].unitPriceCents | integer | Integer cents. |
lines[].lineTotalCents | integer | Integer cents. |
lines[].personalization | array of object | |
lines[].personalization[].key | string | |
lines[].personalization[].label | string | |
lines[].personalization[].value | string | |
orderUrl | string | The shopper's confirmation page. |
placedAt | string (date-time) or null | |
createdAt | string (date-time) |
Mark store orders fulfilled
POST /organizations/{organizationId}/store-orders/fulfil
Marks PLACED orders as handed over or shipped: the storeOrderIds given (409 if one isn't PLACED), or every placed order of storeId.
| Permission | stores.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | storeOrders_fulfil (toolset stores) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
storeId | string or null | No | Every placed order of this store. |
storeOrderIds | array of string or null | No | Up to 500 items. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/store-orders/fulfil" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"storeId":"store_id","storeOrderIds":["storeOrder_id"]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
fulfilled | integer |