Purchasing API
REST endpoints for purchasing in SKUFlow: 14 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 vendors | GET /organizations/{organizationId}/vendors | read |
| Create a vendor | POST /organizations/{organizationId}/vendors | write |
| Get a vendor | GET /organizations/{organizationId}/vendors/{vendorId} | read |
| Update a vendor | PATCH /organizations/{organizationId}/vendors/{vendorId} | write |
| Delete a vendor | DELETE /organizations/{organizationId}/vendors/{vendorId} | sensitive |
| List purchase orders | GET /organizations/{organizationId}/purchase-orders | read |
| Create a draft purchase order | POST /organizations/{organizationId}/purchase-orders | write |
| Get a purchase order | GET /organizations/{organizationId}/purchase-orders/{purchaseOrderId} | read |
| Update a purchase order | PATCH /organizations/{organizationId}/purchase-orders/{purchaseOrderId} | write |
| Delete a purchase order | DELETE /organizations/{organizationId}/purchase-orders/{purchaseOrderId} | sensitive |
| Mark a purchase order sent | POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/send | write |
| Receive a purchase order (in full or in part) | POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/receive | write |
| Cancel a purchase order | POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/cancel | write |
| Create purchase orders from low stock | POST /organizations/{organizationId}/purchase-orders/from-low-stock | write |
List vendors
GET /organizations/{organizationId}/vendors
Suppliers with their item count, purchase-order count and open orders; active only unless includeInactive. Read-only.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | vendors_list (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
query | query | string | No | Free-text search over the list's names, numbers and contact details. Up to 200 characters. |
includeInactive | query | boolean or enum | No |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/vendors" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
An array of objects:
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
contactName | string or null | |
email | string or null | |
phone | string or null | |
terms | string or null | |
notes | string or null | |
active | boolean | |
supplierConnectionId | string or null | The supplier connection blanks from this vendor are bought through (GET /suppliers). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
itemCount | integer | |
purchaseOrderCount | integer | |
openPurchaseOrders | integer |
Create a vendor
POST /organizations/{organizationId}/vendors
Adds a supplier (who purchase orders go to; items may name one). Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | vendors_create (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
contactName | string or null | No | Up to 200 characters. |
email | empty string or string (email) or null | No | |
phone | string or null | No | Up to 100 characters. |
terms | string or null | No | Payment terms as agreed, e.g. "Net 30". Up to 200 characters. |
notes | string or null | No | |
active | boolean | No | Retired vendors (false) leave the pickers. |
supplierConnectionId | string or null | No | The supplier connection (GET /suppliers) this vendor sells through: orders' blanks of that supplier are bought from it. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/vendors" \
-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 | |
organizationId | string | |
name | string | |
contactName | string or null | |
email | string or null | |
phone | string or null | |
terms | string or null | |
notes | string or null | |
active | boolean | |
supplierConnectionId | string or null | The supplier connection blanks from this vendor are bought through (GET /suppliers). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Get a vendor
GET /organizations/{organizationId}/vendors/{vendorId}
One vendor with its item count and latest 20 purchase orders. Read-only.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | vendors_get (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
vendorId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
contactName | string or null | |
email | string or null | |
phone | string or null | |
terms | string or null | |
notes | string or null | |
active | boolean | |
supplierConnectionId | string or null | The supplier connection blanks from this vendor are bought through (GET /suppliers). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
itemCount | integer | |
purchaseOrders | array of object | |
purchaseOrders[].id | string | |
purchaseOrders[].identifier | string | |
purchaseOrders[].status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
purchaseOrders[].totalCents | integer | Integer cents. |
purchaseOrders[].createdAt | string (date-time) |
Update a vendor
PATCH /organizations/{organizationId}/vendors/{vendorId}
Changes the fields sent; active: false retires it. Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | vendors_update (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
vendorId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Up to 200 characters. |
contactName | string or null | No | Up to 200 characters. |
email | empty string or string (email) or null | No | |
phone | string or null | No | Up to 100 characters. |
terms | string or null | No | Payment terms as agreed, e.g. "Net 30". Up to 200 characters. |
notes | string or null | No | |
active | boolean | No | Retired vendors (false) leave the pickers. |
supplierConnectionId | string or null | No | The supplier connection (GET /suppliers) this vendor sells through: orders' blanks of that supplier are bought from it. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","contactName":"string","email":"dana@example.com"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
contactName | string or null | |
email | string or null | |
phone | string or null | |
terms | string or null | |
notes | string or null | |
active | boolean | |
supplierConnectionId | string or null | The supplier connection blanks from this vendor are bought through (GET /suppliers). |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Delete a vendor
DELETE /organizations/{organizationId}/vendors/{vendorId}
Destructive: deletes a vendor without purchase orders (409 otherwise: retire it). Its items keep existing without a vendor.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | vendors_delete (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
vendorId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | true |
List purchase orders
GET /organizations/{organizationId}/purchase-orders
Purchase orders (PO-n) newest first, filtered by status, vendor, warehouse or text; with lines and totals. Paged with a total. Read-only.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | purchaseOrders_list (toolset pricebook, in the default set) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | enum | No | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
vendorId | query | string | No | |
locationId | query | string | No | |
query | query | string | No | Free-text search over the list's names, numbers and contact details. Up to 200 characters. |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].organizationId | string | |
items[].identifier | string | PO-n |
items[].vendorId | string | |
items[].locationId | string | |
items[].status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
items[].kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
items[].vendorReference | string or null | The vendor's order number. |
items[].carrier | string or null | |
items[].trackingNumbers | array of string | |
items[].expectedDate | string or null | |
items[].notes | string or null | |
items[].subtotalCents | integer | Integer cents. |
items[].totalCents | integer | Integer cents. |
items[].sentAt | string (date-time) or null | |
items[].receivedAt | string (date-time) or null | |
items[].cancelledAt | string (date-time) or null | |
items[].createdByUserId | string or null | |
items[].createdAt | string (date-time) | |
items[].updatedAt | string (date-time) | |
items[].vendor | object | |
items[].vendor.id | string | |
items[].vendor.name | string | |
items[].vendor.contactName | string or null | |
items[].vendor.email | string or null | |
items[].vendor.phone | string or null | |
items[].vendor.terms | string or null | |
items[].location | object | |
items[].location.id | string | |
items[].location.name | string | |
items[].location.address | string or null | |
items[].lines | array of object | |
items[].lines[].id | string | |
items[].lines[].purchaseOrderId | string | |
items[].lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
items[].lines[].productVariantId | string or null | |
items[].lines[].sku | string or null | |
items[].lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
items[].lines[].productionJobId | string or null | The outsourced job this pays for. |
items[].lines[].description | string | |
items[].lines[].quantity | number | |
items[].lines[].quantityReceived | number | |
items[].lines[].unitCostCents | integer | Integer cents. |
items[].lines[].sortOrder | integer | |
items[].lines[].totalCents | integer | Integer cents. |
items[].lines[].remaining | number | Still to receive. |
items[].lines[].item | object or null | |
items[].lines[].productVariant | object or null | |
items[].lines[].salesOrderLine | object or null | |
items[].lines[].productionJob | object or null | |
items[].receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
items[].lineCount | integer | |
total | integer |
Create a draft purchase order
POST /organizations/{organizationId}/purchase-orders
Creates a DRAFT purchase order (PO-n) to a vendor for delivery to a warehouse; lines of stocked items (MATERIAL) at their cost unless given. Nothing is sent. Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_create (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
vendorId | string | Yes | From GET /vendors. |
locationId | string | Yes | The warehouse it is delivered to (GET /inventory/locations). |
kind | enum | No | GOODS (default) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
expectedDate | empty string or string or null | No | |
notes | string or null | No | |
vendorReference | string or null | No | The vendor's order number. Up to 100 characters. |
carrier | string or null | No | Who is shipping it (UPS, FedEx…). Up to 100 characters. |
trackingNumbers | array of string | No | Up to 20 items. |
lines | array of object | Yes | Up to 500 items. |
lines[].itemId | string or null | No | A stocked MATERIAL item (GET /pricebook/items); receiving posts it to stock. |
lines[].productVariantId | string or null | No | Or a catalog blank (a product variant): bought for orders, not stocked. |
lines[].sku | string or null | No | The vendor's SKU or part number. Up to 100 characters. |
lines[].salesOrderLineId | string or null | No | The order line it buys for (GET /orders/{orderId}). |
lines[].productionJobId | string or null | No | The outsourced decoration job it pays for. |
lines[].quantity | number | Yes | At most 1000000. |
lines[].unitCostCents | integer | No | Unit cost in cents; defaults to the item's current cost. 0–100000000. |
lines[].description | string or null | No | Defaults to the item's name and vendor part number. Up to 500 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id","locationId":"location_id","lines":[{"quantity":1}]}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
identifier | string | PO-n |
vendorId | string | |
locationId | string | |
status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
vendorReference | string or null | The vendor's order number. |
carrier | string or null | |
trackingNumbers | array of string | |
expectedDate | string or null | |
notes | string or null | |
subtotalCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
sentAt | string (date-time) or null | |
receivedAt | string (date-time) or null | |
cancelledAt | string (date-time) or null | |
createdByUserId | string or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
vendor | object | |
vendor.id | string | |
vendor.name | string | |
vendor.contactName | string or null | |
vendor.email | string or null | |
vendor.phone | string or null | |
vendor.terms | string or null | |
location | object | |
location.id | string | |
location.name | string | |
location.address | string or null | |
lines | array of object | |
lines[].id | string | |
lines[].purchaseOrderId | string | |
lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
lines[].productVariantId | string or null | |
lines[].sku | string or null | |
lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
lines[].productionJobId | string or null | The outsourced job this pays for. |
lines[].description | string | |
lines[].quantity | number | |
lines[].quantityReceived | number | |
lines[].unitCostCents | integer | Integer cents. |
lines[].sortOrder | integer | |
lines[].totalCents | integer | Integer cents. |
lines[].remaining | number | Still to receive. |
lines[].item | object or null | |
lines[].item.id | string | |
lines[].item.code | string or null | |
lines[].item.name | string | |
lines[].item.unit | string | |
lines[].item.vendorPartNumber | string or null | |
lines[].productVariant | object or null | |
lines[].productVariant.id | string | |
lines[].productVariant.sku | string or null | |
lines[].productVariant.colorName | string or null | |
lines[].productVariant.size | string or null | |
lines[].salesOrderLine | object or null | |
lines[].salesOrderLine.id | string | |
lines[].salesOrderLine.order | object | |
lines[].productionJob | object or null | |
lines[].productionJob.id | string | |
lines[].productionJob.name | string | |
lines[].productionJob.order | object | |
receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
Get a purchase order
GET /organizations/{organizationId}/purchase-orders/{purchaseOrderId}
One purchase order with its vendor, delivery warehouse, lines (ordered, received, remaining) and totals. Read-only.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | purchaseOrders_get (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
identifier | string | PO-n |
vendorId | string | |
locationId | string | |
status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
vendorReference | string or null | The vendor's order number. |
carrier | string or null | |
trackingNumbers | array of string | |
expectedDate | string or null | |
notes | string or null | |
subtotalCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
sentAt | string (date-time) or null | |
receivedAt | string (date-time) or null | |
cancelledAt | string (date-time) or null | |
createdByUserId | string or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
vendor | object | |
vendor.id | string | |
vendor.name | string | |
vendor.contactName | string or null | |
vendor.email | string or null | |
vendor.phone | string or null | |
vendor.terms | string or null | |
location | object | |
location.id | string | |
location.name | string | |
location.address | string or null | |
lines | array of object | |
lines[].id | string | |
lines[].purchaseOrderId | string | |
lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
lines[].productVariantId | string or null | |
lines[].sku | string or null | |
lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
lines[].productionJobId | string or null | The outsourced job this pays for. |
lines[].description | string | |
lines[].quantity | number | |
lines[].quantityReceived | number | |
lines[].unitCostCents | integer | Integer cents. |
lines[].sortOrder | integer | |
lines[].totalCents | integer | Integer cents. |
lines[].remaining | number | Still to receive. |
lines[].item | object or null | |
lines[].item.id | string | |
lines[].item.code | string or null | |
lines[].item.name | string | |
lines[].item.unit | string | |
lines[].item.vendorPartNumber | string or null | |
lines[].productVariant | object or null | |
lines[].productVariant.id | string | |
lines[].productVariant.sku | string or null | |
lines[].productVariant.colorName | string or null | |
lines[].productVariant.size | string or null | |
lines[].salesOrderLine | object or null | |
lines[].salesOrderLine.id | string | |
lines[].salesOrderLine.order | object | |
lines[].productionJob | object or null | |
lines[].productionJob.id | string | |
lines[].productionJob.name | string | |
lines[].productionJob.order | object | |
receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
Update a purchase order
PATCH /organizations/{organizationId}/purchase-orders/{purchaseOrderId}
Changes a DRAFT or SENT order (409 once anything was received); lines replaces every line. Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_update (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
vendorId | string | No | From GET /vendors. |
locationId | string | No | The warehouse it is delivered to (GET /inventory/locations). |
kind | enum | No | GOODS (default) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
expectedDate | empty string or string or null | No | |
notes | string or null | No | |
vendorReference | string or null | No | The vendor's order number. Up to 100 characters. |
carrier | string or null | No | Who is shipping it (UPS, FedEx…). Up to 100 characters. |
trackingNumbers | array of string | No | Up to 20 items. |
lines | array of object | No | Up to 500 items. |
lines[].itemId | string or null | No | A stocked MATERIAL item (GET /pricebook/items); receiving posts it to stock. |
lines[].productVariantId | string or null | No | Or a catalog blank (a product variant): bought for orders, not stocked. |
lines[].sku | string or null | No | The vendor's SKU or part number. Up to 100 characters. |
lines[].salesOrderLineId | string or null | No | The order line it buys for (GET /orders/{orderId}). |
lines[].productionJobId | string or null | No | The outsourced decoration job it pays for. |
lines[].quantity | number | Yes | At most 1000000. |
lines[].unitCostCents | integer | No | Unit cost in cents; defaults to the item's current cost. 0–100000000. |
lines[].description | string or null | No | Defaults to the item's name and vendor part number. Up to 500 characters. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vendorId":"vendor_id","locationId":"location_id","kind":"GOODS"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
identifier | string | PO-n |
vendorId | string | |
locationId | string | |
status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
vendorReference | string or null | The vendor's order number. |
carrier | string or null | |
trackingNumbers | array of string | |
expectedDate | string or null | |
notes | string or null | |
subtotalCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
sentAt | string (date-time) or null | |
receivedAt | string (date-time) or null | |
cancelledAt | string (date-time) or null | |
createdByUserId | string or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
vendor | object | |
vendor.id | string | |
vendor.name | string | |
vendor.contactName | string or null | |
vendor.email | string or null | |
vendor.phone | string or null | |
vendor.terms | string or null | |
location | object | |
location.id | string | |
location.name | string | |
location.address | string or null | |
lines | array of object | |
lines[].id | string | |
lines[].purchaseOrderId | string | |
lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
lines[].productVariantId | string or null | |
lines[].sku | string or null | |
lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
lines[].productionJobId | string or null | The outsourced job this pays for. |
lines[].description | string | |
lines[].quantity | number | |
lines[].quantityReceived | number | |
lines[].unitCostCents | integer | Integer cents. |
lines[].sortOrder | integer | |
lines[].totalCents | integer | Integer cents. |
lines[].remaining | number | Still to receive. |
lines[].item | object or null | |
lines[].item.id | string | |
lines[].item.code | string or null | |
lines[].item.name | string | |
lines[].item.unit | string | |
lines[].item.vendorPartNumber | string or null | |
lines[].productVariant | object or null | |
lines[].productVariant.id | string | |
lines[].productVariant.sku | string or null | |
lines[].productVariant.colorName | string or null | |
lines[].productVariant.size | string or null | |
lines[].salesOrderLine | object or null | |
lines[].salesOrderLine.id | string | |
lines[].salesOrderLine.order | object | |
lines[].productionJob | object or null | |
lines[].productionJob.id | string | |
lines[].productionJob.name | string | |
lines[].productionJob.order | object | |
receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
Delete a purchase order
DELETE /organizations/{organizationId}/purchase-orders/{purchaseOrderId}
Destructive: deletes an order nothing was received on (409 otherwise: cancel it). Its number is not reused.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | purchaseOrders_delete (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | true |
Mark a purchase order sent
POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/send
Marks a DRAFT order SENT and records the date (you ordered by phone, email or the printed PO). Nothing is emailed by SKUFlow. Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_send (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/send" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
identifier | string | PO-n |
vendorId | string | |
locationId | string | |
status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
vendorReference | string or null | The vendor's order number. |
carrier | string or null | |
trackingNumbers | array of string | |
expectedDate | string or null | |
notes | string or null | |
subtotalCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
sentAt | string (date-time) or null | |
receivedAt | string (date-time) or null | |
cancelledAt | string (date-time) or null | |
createdByUserId | string or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
vendor | object | |
vendor.id | string | |
vendor.name | string | |
vendor.contactName | string or null | |
vendor.email | string or null | |
vendor.phone | string or null | |
vendor.terms | string or null | |
location | object | |
location.id | string | |
location.name | string | |
location.address | string or null | |
lines | array of object | |
lines[].id | string | |
lines[].purchaseOrderId | string | |
lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
lines[].productVariantId | string or null | |
lines[].sku | string or null | |
lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
lines[].productionJobId | string or null | The outsourced job this pays for. |
lines[].description | string | |
lines[].quantity | number | |
lines[].quantityReceived | number | |
lines[].unitCostCents | integer | Integer cents. |
lines[].sortOrder | integer | |
lines[].totalCents | integer | Integer cents. |
lines[].remaining | number | Still to receive. |
lines[].item | object or null | |
lines[].item.id | string | |
lines[].item.code | string or null | |
lines[].item.name | string | |
lines[].item.unit | string | |
lines[].item.vendorPartNumber | string or null | |
lines[].productVariant | object or null | |
lines[].productVariant.id | string | |
lines[].productVariant.sku | string or null | |
lines[].productVariant.colorName | string or null | |
lines[].productVariant.size | string or null | |
lines[].salesOrderLine | object or null | |
lines[].salesOrderLine.id | string | |
lines[].salesOrderLine.order | object | |
lines[].productionJob | object or null | |
lines[].productionJob.id | string | |
lines[].productionJob.name | string | |
lines[].productionJob.order | object | |
receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
Receive a purchase order (in full or in part)
POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/receive
Stock and costs: posts RECEIVE movements into the order's warehouse for what arrived (all that is outstanding without receipts; never more than ordered, 400), updates each item's cost by moving average, and sets PARTIALLY_RECEIVED or RECEIVED. Returns the order, what was received and the cost changes.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_receive (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
receipts | array of object | No | Per line: the quantity that arrived. Omit to receive everything outstanding. Up to 500 items. |
receipts[].lineId | string | Yes | |
receipts[].quantity | number | Yes | At most 1000000. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/receive" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"receipts":[{"lineId":"line_id","quantity":1}]}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
purchaseOrder | object | |
purchaseOrder.id | string | |
purchaseOrder.organizationId | string | |
purchaseOrder.identifier | string | PO-n |
purchaseOrder.vendorId | string | |
purchaseOrder.locationId | string | |
purchaseOrder.status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
purchaseOrder.kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
purchaseOrder.vendorReference | string or null | The vendor's order number. |
purchaseOrder.carrier | string or null | |
purchaseOrder.trackingNumbers | array of string | |
purchaseOrder.expectedDate | string or null | |
purchaseOrder.notes | string or null | |
purchaseOrder.subtotalCents | integer | Integer cents. |
purchaseOrder.totalCents | integer | Integer cents. |
purchaseOrder.sentAt | string (date-time) or null | |
purchaseOrder.receivedAt | string (date-time) or null | |
purchaseOrder.cancelledAt | string (date-time) or null | |
purchaseOrder.createdByUserId | string or null | |
purchaseOrder.createdAt | string (date-time) | |
purchaseOrder.updatedAt | string (date-time) | |
purchaseOrder.vendor | object | |
purchaseOrder.vendor.id | string | |
purchaseOrder.vendor.name | string | |
purchaseOrder.vendor.contactName | string or null | |
purchaseOrder.vendor.email | string or null | |
purchaseOrder.vendor.phone | string or null | |
purchaseOrder.vendor.terms | string or null | |
purchaseOrder.location | object | |
purchaseOrder.location.id | string | |
purchaseOrder.location.name | string | |
purchaseOrder.location.address | string or null | |
purchaseOrder.lines | array of object | |
purchaseOrder.lines[].id | string | |
purchaseOrder.lines[].purchaseOrderId | string | |
purchaseOrder.lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
purchaseOrder.lines[].productVariantId | string or null | |
purchaseOrder.lines[].sku | string or null | |
purchaseOrder.lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
purchaseOrder.lines[].productionJobId | string or null | The outsourced job this pays for. |
purchaseOrder.lines[].description | string | |
purchaseOrder.lines[].quantity | number | |
purchaseOrder.lines[].quantityReceived | number | |
purchaseOrder.lines[].unitCostCents | integer | Integer cents. |
purchaseOrder.lines[].sortOrder | integer | |
purchaseOrder.lines[].totalCents | integer | Integer cents. |
purchaseOrder.lines[].remaining | number | Still to receive. |
purchaseOrder.lines[].item | object or null | |
purchaseOrder.lines[].productVariant | object or null | |
purchaseOrder.lines[].salesOrderLine | object or null | |
purchaseOrder.lines[].productionJob | object or null | |
purchaseOrder.receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
received | array of object | |
received[].lineId | string | |
received[].quantity | number | |
costChanges | array of object | |
costChanges[].itemId | string | |
costChanges[].from | integer | The item's unit cost before. |
costChanges[].to | integer | Its moving-average cost now. |
Cancel a purchase order
POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/cancel
Cancels an open order; what was already received stays in stock. A received order cannot be cancelled (409). Returns it.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_cancel (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
purchaseOrderId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/cancel" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
identifier | string | PO-n |
vendorId | string | |
locationId | string | |
status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
vendorReference | string or null | The vendor's order number. |
carrier | string or null | |
trackingNumbers | array of string | |
expectedDate | string or null | |
notes | string or null | |
subtotalCents | integer | Integer cents. |
totalCents | integer | Integer cents. |
sentAt | string (date-time) or null | |
receivedAt | string (date-time) or null | |
cancelledAt | string (date-time) or null | |
createdByUserId | string or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
vendor | object | |
vendor.id | string | |
vendor.name | string | |
vendor.contactName | string or null | |
vendor.email | string or null | |
vendor.phone | string or null | |
vendor.terms | string or null | |
location | object | |
location.id | string | |
location.name | string | |
location.address | string or null | |
lines | array of object | |
lines[].id | string | |
lines[].purchaseOrderId | string | |
lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
lines[].productVariantId | string or null | |
lines[].sku | string or null | |
lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
lines[].productionJobId | string or null | The outsourced job this pays for. |
lines[].description | string | |
lines[].quantity | number | |
lines[].quantityReceived | number | |
lines[].unitCostCents | integer | Integer cents. |
lines[].sortOrder | integer | |
lines[].totalCents | integer | Integer cents. |
lines[].remaining | number | Still to receive. |
lines[].item | object or null | |
lines[].item.id | string | |
lines[].item.code | string or null | |
lines[].item.name | string | |
lines[].item.unit | string | |
lines[].item.vendorPartNumber | string or null | |
lines[].productVariant | object or null | |
lines[].productVariant.id | string | |
lines[].productVariant.sku | string or null | |
lines[].productVariant.colorName | string or null | |
lines[].productVariant.size | string or null | |
lines[].salesOrderLine | object or null | |
lines[].salesOrderLine.id | string | |
lines[].salesOrderLine.order | object | |
lines[].productionJob | object or null | |
lines[].productionJob.id | string | |
lines[].productionJob.name | string | |
lines[].productionJob.order | object | |
receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
Create purchase orders from low stock
POST /organizations/{organizationId}/purchase-orders/from-low-stock
Low stock → "Create PO": one DRAFT order per vendor for a location's items at or below their reorder point (or itemIds), each for its suggested quantity at the item's cost. Items without a vendor are listed in itemsWithoutVendor unless vendorId orders everything from one vendor. Returns the orders.
| Permission | purchasing.manage (Owner, Admin) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | purchaseOrders_fromLowStock (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
locationId | string | Yes | |
vendorId | string or null | No | |
itemIds | array of string | No | Up to 500 items. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/from-low-stock" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"locationId":"location_id"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
purchaseOrders | array of object | |
purchaseOrders[].id | string | |
purchaseOrders[].organizationId | string | |
purchaseOrders[].identifier | string | PO-n |
purchaseOrders[].vendorId | string | |
purchaseOrders[].locationId | string | |
purchaseOrders[].status | enum | DRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED. |
purchaseOrders[].kind | enum | GOODS (stock or blanks) or DECORATION (work sent to an outsourced decorator). One of GOODS, DECORATION. |
purchaseOrders[].vendorReference | string or null | The vendor's order number. |
purchaseOrders[].carrier | string or null | |
purchaseOrders[].trackingNumbers | array of string | |
purchaseOrders[].expectedDate | string or null | |
purchaseOrders[].notes | string or null | |
purchaseOrders[].subtotalCents | integer | Integer cents. |
purchaseOrders[].totalCents | integer | Integer cents. |
purchaseOrders[].sentAt | string (date-time) or null | |
purchaseOrders[].receivedAt | string (date-time) or null | |
purchaseOrders[].cancelledAt | string (date-time) or null | |
purchaseOrders[].createdByUserId | string or null | |
purchaseOrders[].createdAt | string (date-time) | |
purchaseOrders[].updatedAt | string (date-time) | |
purchaseOrders[].vendor | object | |
purchaseOrders[].vendor.id | string | |
purchaseOrders[].vendor.name | string | |
purchaseOrders[].vendor.contactName | string or null | |
purchaseOrders[].vendor.email | string or null | |
purchaseOrders[].vendor.phone | string or null | |
purchaseOrders[].vendor.terms | string or null | |
purchaseOrders[].location | object | |
purchaseOrders[].location.id | string | |
purchaseOrders[].location.name | string | |
purchaseOrders[].location.address | string or null | |
purchaseOrders[].lines | array of object | |
purchaseOrders[].lines[].id | string | |
purchaseOrders[].lines[].purchaseOrderId | string | |
purchaseOrders[].lines[].itemId | string or null | A stocked pricebook item; null for a catalog blank or decoration work. |
purchaseOrders[].lines[].productVariantId | string or null | |
purchaseOrders[].lines[].sku | string or null | |
purchaseOrders[].lines[].salesOrderLineId | string or null | The order line this buys for; receiving moves the order on. |
purchaseOrders[].lines[].productionJobId | string or null | The outsourced job this pays for. |
purchaseOrders[].lines[].description | string | |
purchaseOrders[].lines[].quantity | number | |
purchaseOrders[].lines[].quantityReceived | number | |
purchaseOrders[].lines[].unitCostCents | integer | Integer cents. |
purchaseOrders[].lines[].sortOrder | integer | |
purchaseOrders[].lines[].totalCents | integer | Integer cents. |
purchaseOrders[].lines[].remaining | number | Still to receive. |
purchaseOrders[].lines[].item | object or null | |
purchaseOrders[].lines[].productVariant | object or null | |
purchaseOrders[].lines[].salesOrderLine | object or null | |
purchaseOrders[].lines[].productionJob | object or null | |
purchaseOrders[].receivedValueCents | integer | What has arrived so far, at the PO's unit costs. |
itemsWithoutVendor | array of string |