DevelopersAPI reference

Purchasing API

REST endpoints for purchasing in ServFlo: 14 operations with parameters, request and response fields, permissions and curl examples.

Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.

OperationEndpointRisk
List vendorsGET /organizations/{organizationId}/vendorsread
Create a vendorPOST /organizations/{organizationId}/vendorswrite
Get a vendorGET /organizations/{organizationId}/vendors/{vendorId}read
Update a vendorPATCH /organizations/{organizationId}/vendors/{vendorId}write
Delete a vendorDELETE /organizations/{organizationId}/vendors/{vendorId}sensitive
List purchase ordersGET /organizations/{organizationId}/purchase-ordersread
Create a draft purchase orderPOST /organizations/{organizationId}/purchase-orderswrite
Get a purchase orderGET /organizations/{organizationId}/purchase-orders/{purchaseOrderId}read
Update a purchase orderPATCH /organizations/{organizationId}/purchase-orders/{purchaseOrderId}write
Delete a purchase orderDELETE /organizations/{organizationId}/purchase-orders/{purchaseOrderId}sensitive
Mark a purchase order sentPOST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/sendwrite
Receive a purchase order (in full or in part)POST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/receivewrite
Cancel a purchase orderPOST /organizations/{organizationId}/purchase-orders/{purchaseOrderId}/cancelwrite
Create purchase orders from low stockPOST /organizations/{organizationId}/purchase-orders/from-low-stockwrite

List vendors

GET /organizations/{organizationId}/vendors

Suppliers with their item count, purchase-order count and open orders; active only unless includeInactive. Read-only.

Permissionpurchasing.manage (Owner, Admin)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolvendors_list (toolset pricebook)

Parameters

NameInTypeRequiredDescription
queryquerystringNoFree-text search over the list's names, numbers and contact details. Up to 200 characters.
includeInactivequeryboolean or enumNo

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/vendors" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
idstring
organizationIdstring
namestring
contactNamestring or null
emailstring or null
phonestring or null
termsstring or null
notesstring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (date-time)
itemCountinteger
purchaseOrderCountinteger
openPurchaseOrdersinteger

Create a vendor

POST /organizations/{organizationId}/vendors

Adds a supplier (who purchase orders go to; items may name one). Returns it.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolvendors_create (toolset pricebook)

Request body

FieldTypeRequiredDescription
namestringYesUp to 200 characters.
contactNamestring or nullNoUp to 200 characters.
emailempty string or string (email) or nullNo
phonestring or nullNoUp to 100 characters.
termsstring or nullNoPayment terms as agreed, e.g. "Net 30". Up to 200 characters.
notesstring or nullNo
activebooleanNoRetired vendors (false) leave the pickers.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/vendors" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
namestring
contactNamestring or null
emailstring or null
phonestring or null
termsstring or null
notesstring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (date-time)

Get a vendor

GET /organizations/{organizationId}/vendors/{vendorId}

One vendor with its item count and latest 20 purchase orders. Read-only.

Permissionpurchasing.manage (Owner, Admin)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolvendors_get (toolset pricebook)

Parameters

NameInTypeRequiredDescription
vendorIdpathstringYes

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
namestring
contactNamestring or null
emailstring or null
phonestring or null
termsstring or null
notesstring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (date-time)
itemCountinteger
purchaseOrdersarray of object
purchaseOrders[].idstring
purchaseOrders[].identifierstring
purchaseOrders[].statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
purchaseOrders[].totalCentsintegerInteger cents.
purchaseOrders[].createdAtstring (date-time)

Update a vendor

PATCH /organizations/{organizationId}/vendors/{vendorId}

Changes the fields sent; active: false retires it. Returns it.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolvendors_update (toolset pricebook)

Parameters

NameInTypeRequiredDescription
vendorIdpathstringYes

Request body

FieldTypeRequiredDescription
namestringNoUp to 200 characters.
contactNamestring or nullNoUp to 200 characters.
emailempty string or string (email) or nullNo
phonestring or nullNoUp to 100 characters.
termsstring or nullNoPayment terms as agreed, e.g. "Net 30". Up to 200 characters.
notesstring or nullNo
activebooleanNoRetired vendors (false) leave the pickers.

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Dana Whitfield","contactName":"string","email":"dana@example.com"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
namestring
contactNamestring or null
emailstring or null
phonestring or null
termsstring or null
notesstring or null
activeboolean
createdAtstring (date-time)
updatedAtstring (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.

Permissionpurchasing.manage (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolvendors_delete (toolset pricebook)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
vendorIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/vendors/{vendorId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue

List purchase orders

GET /organizations/{organizationId}/purchase-orders

Purchase orders (PO-n) newest first, filtered by status, vendor, job, location or text; with lines and totals. Paged with a total. Read-only.

Permissionpurchasing.manage (Owner, Admin)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolpurchaseOrders_list (toolset pricebook)

Parameters

NameInTypeRequiredDescription
statusqueryenumNoDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
vendorIdquerystringNo
jobIdquerystringNo
locationIdquerystringNo
queryquerystringNoFree-text search over the list's names, numbers and contact details. Up to 200 characters.
limitqueryintegerNoPage size, 1–200. Default 50.
offsetqueryintegerNoRows to skip; the answer's total counts every match. Default 0.

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].organizationIdstring
items[].identifierstringPO-n
items[].vendorIdstring
items[].locationIdstring
items[].jobIdstring or null
items[].statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
items[].expectedDatestring or null
items[].notesstring or null
items[].subtotalCentsintegerInteger cents.
items[].totalCentsintegerInteger cents.
items[].sentAtstring (date-time) or null
items[].receivedAtstring (date-time) or null
items[].cancelledAtstring (date-time) or null
items[].createdByUserIdstring or null
items[].createdAtstring (date-time)
items[].updatedAtstring (date-time)
items[].vendorobject
items[].vendor.idstring
items[].vendor.namestring
items[].vendor.contactNamestring or null
items[].vendor.emailstring or null
items[].vendor.phonestring or null
items[].vendor.termsstring or null
items[].locationobject
items[].location.idstring
items[].location.namestring
items[].location.kindstring
items[].location.addressstring or null
items[].jobobject or null
items[].job.idstring
items[].job.identifierstring
items[].job.customerobject
items[].linesarray of object
items[].lines[].idstring
items[].lines[].purchaseOrderIdstring
items[].lines[].itemIdstring
items[].lines[].descriptionstring
items[].lines[].quantitynumber
items[].lines[].quantityReceivednumber
items[].lines[].unitCostCentsintegerInteger cents.
items[].lines[].sortOrderinteger
items[].lines[].totalCentsintegerInteger cents.
items[].lines[].remainingnumberStill to receive.
items[].lines[].itemobject
items[].receivedValueCentsintegerWhat has arrived so far, at the PO's unit costs.
items[].lineCountinteger
totalinteger

Create a draft purchase order

POST /organizations/{organizationId}/purchase-orders

Creates a DRAFT purchase order (PO-n) to a vendor for delivery to a location, optionally for a job; lines of stocked items (MATERIAL / EQUIPMENT) at their cost unless given. Nothing is sent. Returns it.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_create (toolset pricebook)

Request body

FieldTypeRequiredDescription
vendorIdstringYesFrom GET /vendors.
locationIdstringYesWhere it is delivered (GET /inventory/locations).
jobIdstring or nullNoThe job it is bought for: its received cost counts in the job's costing.
expectedDateempty string or string or nullNo
notesstring or nullNo
linesarray of objectYesUp to 500 items.
lines[].itemIdstringYesA MATERIAL or EQUIPMENT item (GET /pricebook/items).
lines[].quantitynumberYesAt most 1000000.
lines[].unitCostCentsintegerNoUnit cost in cents; defaults to the item's current cost. 0–100000000.
lines[].descriptionstring or nullNoDefaults to the item's name and vendor part number. Up to 500 characters.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"vendorId":"vendor_id","locationId":"location_id","lines":[{"itemId":"item_id","quantity":1}]}'

Response

201: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
identifierstringPO-n
vendorIdstring
locationIdstring
jobIdstring or null
statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
expectedDatestring or null
notesstring or null
subtotalCentsintegerInteger cents.
totalCentsintegerInteger cents.
sentAtstring (date-time) or null
receivedAtstring (date-time) or null
cancelledAtstring (date-time) or null
createdByUserIdstring or null
createdAtstring (date-time)
updatedAtstring (date-time)
vendorobject
vendor.idstring
vendor.namestring
vendor.contactNamestring or null
vendor.emailstring or null
vendor.phonestring or null
vendor.termsstring or null
locationobject
location.idstring
location.namestring
location.kindstring
location.addressstring or null
jobobject or null
job.idstring
job.identifierstring
job.customerobject
job.customer.idstring
job.customer.namestring
linesarray of object
lines[].idstring
lines[].purchaseOrderIdstring
lines[].itemIdstring
lines[].descriptionstring
lines[].quantitynumber
lines[].quantityReceivednumber
lines[].unitCostCentsintegerInteger cents.
lines[].sortOrderinteger
lines[].totalCentsintegerInteger cents.
lines[].remainingnumberStill to receive.
lines[].itemobject
lines[].item.idstring
lines[].item.codestring or null
lines[].item.namestring
lines[].item.unitstring
lines[].item.vendorPartNumberstring or null
receivedValueCentsintegerWhat 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 location, job, lines (ordered, received, remaining) and totals. Read-only.

Permissionpurchasing.manage (Owner, Admin)
Riskread, OAuth scope servflo.read. Read: reads only.
MCP toolpurchaseOrders_get (toolset pricebook)

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Example

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
identifierstringPO-n
vendorIdstring
locationIdstring
jobIdstring or null
statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
expectedDatestring or null
notesstring or null
subtotalCentsintegerInteger cents.
totalCentsintegerInteger cents.
sentAtstring (date-time) or null
receivedAtstring (date-time) or null
cancelledAtstring (date-time) or null
createdByUserIdstring or null
createdAtstring (date-time)
updatedAtstring (date-time)
vendorobject
vendor.idstring
vendor.namestring
vendor.contactNamestring or null
vendor.emailstring or null
vendor.phonestring or null
vendor.termsstring or null
locationobject
location.idstring
location.namestring
location.kindstring
location.addressstring or null
jobobject or null
job.idstring
job.identifierstring
job.customerobject
job.customer.idstring
job.customer.namestring
linesarray of object
lines[].idstring
lines[].purchaseOrderIdstring
lines[].itemIdstring
lines[].descriptionstring
lines[].quantitynumber
lines[].quantityReceivednumber
lines[].unitCostCentsintegerInteger cents.
lines[].sortOrderinteger
lines[].totalCentsintegerInteger cents.
lines[].remainingnumberStill to receive.
lines[].itemobject
lines[].item.idstring
lines[].item.codestring or null
lines[].item.namestring
lines[].item.unitstring
lines[].item.vendorPartNumberstring or null
receivedValueCentsintegerWhat 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.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_update (toolset pricebook)

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Request body

FieldTypeRequiredDescription
vendorIdstringNoFrom GET /vendors.
locationIdstringNoWhere it is delivered (GET /inventory/locations).
jobIdstring or nullNoThe job it is bought for: its received cost counts in the job's costing.
expectedDateempty string or string or nullNo
notesstring or nullNo
linesarray of objectNoUp to 500 items.
lines[].itemIdstringYesA MATERIAL or EQUIPMENT item (GET /pricebook/items).
lines[].quantitynumberYesAt most 1000000.
lines[].unitCostCentsintegerNoUnit cost in cents; defaults to the item's current cost. 0–100000000.
lines[].descriptionstring or nullNoDefaults to the item's name and vendor part number. Up to 500 characters.

Example

curl -X PATCH "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"vendorId":"vendor_id","locationId":"location_id","jobId":"job_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
identifierstringPO-n
vendorIdstring
locationIdstring
jobIdstring or null
statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
expectedDatestring or null
notesstring or null
subtotalCentsintegerInteger cents.
totalCentsintegerInteger cents.
sentAtstring (date-time) or null
receivedAtstring (date-time) or null
cancelledAtstring (date-time) or null
createdByUserIdstring or null
createdAtstring (date-time)
updatedAtstring (date-time)
vendorobject
vendor.idstring
vendor.namestring
vendor.contactNamestring or null
vendor.emailstring or null
vendor.phonestring or null
vendor.termsstring or null
locationobject
location.idstring
location.namestring
location.kindstring
location.addressstring or null
jobobject or null
job.idstring
job.identifierstring
job.customerobject
job.customer.idstring
job.customer.namestring
linesarray of object
lines[].idstring
lines[].purchaseOrderIdstring
lines[].itemIdstring
lines[].descriptionstring
lines[].quantitynumber
lines[].quantityReceivednumber
lines[].unitCostCentsintegerInteger cents.
lines[].sortOrderinteger
lines[].totalCentsintegerInteger cents.
lines[].remainingnumberStill to receive.
lines[].itemobject
lines[].item.idstring
lines[].item.codestring or null
lines[].item.namestring
lines[].item.unitstring
lines[].item.vendorPartNumberstring or null
receivedValueCentsintegerWhat 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.

Permissionpurchasing.manage (Owner, Admin)
Risksensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolpurchaseOrders_delete (toolset pricebook)
ApprovalOver MCP, this tool always waits for your approval in ServFlo. See Approvals.

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Example

curl -X DELETE "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
oktrue

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 ServFlo. Returns it.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_send (toolset pricebook)

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/send" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
identifierstringPO-n
vendorIdstring
locationIdstring
jobIdstring or null
statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
expectedDatestring or null
notesstring or null
subtotalCentsintegerInteger cents.
totalCentsintegerInteger cents.
sentAtstring (date-time) or null
receivedAtstring (date-time) or null
cancelledAtstring (date-time) or null
createdByUserIdstring or null
createdAtstring (date-time)
updatedAtstring (date-time)
vendorobject
vendor.idstring
vendor.namestring
vendor.contactNamestring or null
vendor.emailstring or null
vendor.phonestring or null
vendor.termsstring or null
locationobject
location.idstring
location.namestring
location.kindstring
location.addressstring or null
jobobject or null
job.idstring
job.identifierstring
job.customerobject
job.customer.idstring
job.customer.namestring
linesarray of object
lines[].idstring
lines[].purchaseOrderIdstring
lines[].itemIdstring
lines[].descriptionstring
lines[].quantitynumber
lines[].quantityReceivednumber
lines[].unitCostCentsintegerInteger cents.
lines[].sortOrderinteger
lines[].totalCentsintegerInteger cents.
lines[].remainingnumberStill to receive.
lines[].itemobject
lines[].item.idstring
lines[].item.codestring or null
lines[].item.namestring
lines[].item.unitstring
lines[].item.vendorPartNumberstring or null
receivedValueCentsintegerWhat 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 location for what arrived (all that is outstanding without receipts; never more than ordered, 400), updates each item's cost by moving average (MARKUP items are repriced), links the cost to the order's job, and sets PARTIALLY_RECEIVED or RECEIVED. Returns the order, what was received and the cost changes.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_receive (toolset pricebook)

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Request body

FieldTypeRequiredDescription
receiptsarray of objectNoPer line: the quantity that arrived. Omit to receive everything outstanding. Up to 500 items.
receipts[].lineIdstringYes
receipts[].quantitynumberYesAt most 1000000.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/receive" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"receipts":[{"lineId":"line_id","quantity":1}]}'

Response

200: the answer's fields
FieldTypeDescription
purchaseOrderobject
purchaseOrder.idstring
purchaseOrder.organizationIdstring
purchaseOrder.identifierstringPO-n
purchaseOrder.vendorIdstring
purchaseOrder.locationIdstring
purchaseOrder.jobIdstring or null
purchaseOrder.statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
purchaseOrder.expectedDatestring or null
purchaseOrder.notesstring or null
purchaseOrder.subtotalCentsintegerInteger cents.
purchaseOrder.totalCentsintegerInteger cents.
purchaseOrder.sentAtstring (date-time) or null
purchaseOrder.receivedAtstring (date-time) or null
purchaseOrder.cancelledAtstring (date-time) or null
purchaseOrder.createdByUserIdstring or null
purchaseOrder.createdAtstring (date-time)
purchaseOrder.updatedAtstring (date-time)
purchaseOrder.vendorobject
purchaseOrder.vendor.idstring
purchaseOrder.vendor.namestring
purchaseOrder.vendor.contactNamestring or null
purchaseOrder.vendor.emailstring or null
purchaseOrder.vendor.phonestring or null
purchaseOrder.vendor.termsstring or null
purchaseOrder.locationobject
purchaseOrder.location.idstring
purchaseOrder.location.namestring
purchaseOrder.location.kindstring
purchaseOrder.location.addressstring or null
purchaseOrder.jobobject or null
purchaseOrder.job.idstring
purchaseOrder.job.identifierstring
purchaseOrder.job.customerobject
purchaseOrder.linesarray of object
purchaseOrder.lines[].idstring
purchaseOrder.lines[].purchaseOrderIdstring
purchaseOrder.lines[].itemIdstring
purchaseOrder.lines[].descriptionstring
purchaseOrder.lines[].quantitynumber
purchaseOrder.lines[].quantityReceivednumber
purchaseOrder.lines[].unitCostCentsintegerInteger cents.
purchaseOrder.lines[].sortOrderinteger
purchaseOrder.lines[].totalCentsintegerInteger cents.
purchaseOrder.lines[].remainingnumberStill to receive.
purchaseOrder.lines[].itemobject
purchaseOrder.receivedValueCentsintegerWhat has arrived so far, at the PO's unit costs.
receivedarray of object
received[].lineIdstring
received[].quantitynumber
costChangesarray of object
costChanges[].itemIdstring
costChanges[].fromintegerThe item's unit cost before.
costChanges[].tointegerIts 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.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_cancel (toolset pricebook)

Parameters

NameInTypeRequiredDescription
purchaseOrderIdpathstringYes

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/{purchaseOrderId}/cancel" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
idstring
organizationIdstring
identifierstringPO-n
vendorIdstring
locationIdstring
jobIdstring or null
statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
expectedDatestring or null
notesstring or null
subtotalCentsintegerInteger cents.
totalCentsintegerInteger cents.
sentAtstring (date-time) or null
receivedAtstring (date-time) or null
cancelledAtstring (date-time) or null
createdByUserIdstring or null
createdAtstring (date-time)
updatedAtstring (date-time)
vendorobject
vendor.idstring
vendor.namestring
vendor.contactNamestring or null
vendor.emailstring or null
vendor.phonestring or null
vendor.termsstring or null
locationobject
location.idstring
location.namestring
location.kindstring
location.addressstring or null
jobobject or null
job.idstring
job.identifierstring
job.customerobject
job.customer.idstring
job.customer.namestring
linesarray of object
lines[].idstring
lines[].purchaseOrderIdstring
lines[].itemIdstring
lines[].descriptionstring
lines[].quantitynumber
lines[].quantityReceivednumber
lines[].unitCostCentsintegerInteger cents.
lines[].sortOrderinteger
lines[].totalCentsintegerInteger cents.
lines[].remainingnumberStill to receive.
lines[].itemobject
lines[].item.idstring
lines[].item.codestring or null
lines[].item.namestring
lines[].item.unitstring
lines[].item.vendorPartNumberstring or null
receivedValueCentsintegerWhat 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.

Permissionpurchasing.manage (Owner, Admin)
Riskwrite, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolpurchaseOrders_fromLowStock (toolset pricebook)

Request body

FieldTypeRequiredDescription
locationIdstringYes
vendorIdstring or nullNo
itemIdsarray of stringNoUp to 500 items.

Example

curl -X POST "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/purchase-orders/from-low-stock" \
  -H "Authorization: Bearer $SERVFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"locationId":"location_id"}'

Response

201: the answer's fields
FieldTypeDescription
purchaseOrdersarray of object
purchaseOrders[].idstring
purchaseOrders[].organizationIdstring
purchaseOrders[].identifierstringPO-n
purchaseOrders[].vendorIdstring
purchaseOrders[].locationIdstring
purchaseOrders[].jobIdstring or null
purchaseOrders[].statusenumDRAFT (editable), SENT (ordered; still editable until something arrives), PARTIALLY_RECEIVED, RECEIVED, CANCELLED. One of DRAFT, SENT, PARTIALLY_RECEIVED, RECEIVED, CANCELLED.
purchaseOrders[].expectedDatestring or null
purchaseOrders[].notesstring or null
purchaseOrders[].subtotalCentsintegerInteger cents.
purchaseOrders[].totalCentsintegerInteger cents.
purchaseOrders[].sentAtstring (date-time) or null
purchaseOrders[].receivedAtstring (date-time) or null
purchaseOrders[].cancelledAtstring (date-time) or null
purchaseOrders[].createdByUserIdstring or null
purchaseOrders[].createdAtstring (date-time)
purchaseOrders[].updatedAtstring (date-time)
purchaseOrders[].vendorobject
purchaseOrders[].vendor.idstring
purchaseOrders[].vendor.namestring
purchaseOrders[].vendor.contactNamestring or null
purchaseOrders[].vendor.emailstring or null
purchaseOrders[].vendor.phonestring or null
purchaseOrders[].vendor.termsstring or null
purchaseOrders[].locationobject
purchaseOrders[].location.idstring
purchaseOrders[].location.namestring
purchaseOrders[].location.kindstring
purchaseOrders[].location.addressstring or null
purchaseOrders[].jobobject or null
purchaseOrders[].job.idstring
purchaseOrders[].job.identifierstring
purchaseOrders[].job.customerobject
purchaseOrders[].linesarray of object
purchaseOrders[].lines[].idstring
purchaseOrders[].lines[].purchaseOrderIdstring
purchaseOrders[].lines[].itemIdstring
purchaseOrders[].lines[].descriptionstring
purchaseOrders[].lines[].quantitynumber
purchaseOrders[].lines[].quantityReceivednumber
purchaseOrders[].lines[].unitCostCentsintegerInteger cents.
purchaseOrders[].lines[].sortOrderinteger
purchaseOrders[].lines[].totalCentsintegerInteger cents.
purchaseOrders[].lines[].remainingnumberStill to receive.
purchaseOrders[].lines[].itemobject
purchaseOrders[].receivedValueCentsintegerWhat has arrived so far, at the PO's unit costs.
itemsWithoutVendorarray of string

On this page