APIv3
Exit Documentation

Purchase orders

A purchase order records products or services ordered from a supplier, along with receiving dates, purchasing costs, taxes, shipping, and payments. API v3 can create, update, send, receive, delete, and create or delete manual payments against eligible purchase orders.


The purchase order object

FieldTypeDescription
idstringUnique purchase-order UUID.
objectstringAlways purchase_order.
purchase_order_numberintegerAccount-assigned purchase-order number.
custom_purchase_order_numberstring or nullOptional custom purchase-order number.
namestring or nullPurchase-order name.
supplier_idstringSupplier UUID.
supplier_namestringSupplier display name stored with the purchase order.
assigned_user_idstringSalesBinder user UUID assigned to the purchase order.
location_idstring or nullInventory location associated with the purchase order.
status_idintegerCurrent purchase-order status identifier.
statusstring or nullCurrent status name, such as Not Sent, Sent, Partially Received, or Received.
issue_datestring or nullIssue date in YYYY-MM-DD format.
date_sentstring or nullDate sent in YYYY-MM-DD format.
date_receivedstring or nullReceived date in YYYY-MM-DD format.
date_requestedstring or nullRequested date in YYYY-MM-DD format.
date_neededstring or nullNeeded-by date in YYYY-MM-DD format.
date_fully_paidstring or nullFully paid date in YYYY-MM-DD format.
requested_fromstring or nullPerson or team that requested the purchase order.
attentionstring or nullAttention line.
shipping_addressstring or nullShipping-address text.
public_notestring or nullSupplier-facing note.
payment_termsstring or nullPayment terms.
shipping_providerstring or nullShipping provider.
shipping_tracking_codestring or nullShipping tracking code.
subtotalstringSubtotal before shipping and taxes, as a four-decimal string.
shippingstringShipping charge as a four-decimal string.
taxstringPrimary tax amount as a four-decimal string.
tax_2stringSecondary tax amount as a four-decimal string.
totalstringPurchase-order total including shipping and taxes, as a four-decimal string.
amount_paidstringApplied purchase-order payments as a four-decimal string.
amount_duestringRemaining amount due as a four-decimal string.
created_atstring or nullISO 8601 creation timestamp.
updated_atstring or nullISO 8601 modification timestamp.
linesarrayCurrent purchase-order lines. Present only when retrieving one purchase order.

Monetary values use the SalesBinder account's base currency.


The purchase order line object

FieldTypeDescription
idstringUnique purchase-order-line UUID.
objectstringAlways purchase_order_line.
item_idstring or nullRelated inventory item UUID.
item_variation_location_idinteger or nullRelated item variation and location identifier.
namestring or nullLine-item name.
descriptionstring or nullLine-item description.
quantitynumberQuantity ordered.
quantity_receivednumberQuantity already received.
unit_idinteger or nullRelated unit identifier.
unit_coststringPurchasing cost per unit as a four-decimal string.
discount_percentstringDiscount percentage as a three-decimal string.
discounted_unit_coststring or nullDiscounted unit cost, or null when no discounted cost is stored.
tax_ratestringPrimary tax percentage as a three-decimal string.
tax_2_ratestringSecondary tax percentage as a three-decimal string.
subtotalstringQuantity multiplied by the effective unit cost, before tax, as a four-decimal string.

The unit_cost field is the purchasing amount recorded on the purchase order.


The purchase-order payment object

FieldTypeDescription
idstringUnique payment UUID.
objectstringAlways payment.
purchase_order_idstringPurchase-order UUID to which the payment or refund applies.
amountstringSigned amount as a four-decimal string. Payments are positive and refunds are negative.
typestringpayment for a positive amount or refund for a negative amount.
referencestringStored payment or refund reference.
payment_datestring or nullPayment date in YYYY-MM-DD format.
cardnullAlways null; card details are not available for purchase-order payments.

Create a purchase order

POST/api/v3/purchase-orders

Required scope: purchase_orders:write

Creates a purchase order in the Not Sent status. SalesBinder assigns the purchase-order number and current API user, calculates totals, and returns the complete purchase order with its lines.

Request fields

FieldTypeRequiredDescription
supplier_idstringYesUUID of an active supplier in the current account.
location_idstringYesUUID of the active inventory location that will receive the order.
linesarrayYesBetween 1 and 100 inventory or service lines.
namestringNoOptional name for your own reference.
issue_datestringNoIssue date in YYYY-MM-DD format. Defaults to the current date in the user's account timezone.
date_requestedstringNoRequested date in YYYY-MM-DD format.
date_neededstringNoNeeded-by date in YYYY-MM-DD format.
requested_fromstringNoPerson or team requesting the purchase order.
custom_purchase_order_numberstringNoCustom identifier of up to 24 characters.
attentionstringNoAttention line.
shipping_addressstringNoShipping-address text.
public_notestringNoSupplier-facing note.
payment_termsstringNoPayment terms.
shippingnumberNoNon-negative shipping charge. Defaults to 0.
shipping_providerstringNoShipping provider.
shipping_tracking_codestringNoShipping tracking code.
discount_percentnumberNoPurchase-order-wide discount from 0 through 100.

Line fields

FieldTypeRequiredDescription
item_idstringInventory linesUUID of an active inventory item in the purchase-order location. Omit for a service line.
item_variation_location_idintegerVariation itemsIdentifier of the variation at the purchase-order location.
namestringService linesService-line name. Inventory line names come from the selected item.
descriptionstringNoLine description. Inventory lines default to the item's description.
quantitynumberNoPositive quantity. Defaults to 1; unique inventory items are always ordered as one.
unit_costnumberService linesNon-negative purchasing cost. Inventory lines default to the item's resolved unit cost and may be overridden.
tax_ratenumberNoPrimary tax percentage from 0 through 100. Defaults to the supplier's primary tax rate.
tax_2_ratenumberNoSecondary tax percentage from 0 through 100. Defaults to the supplier's secondary tax rate.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders" \
  --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: warehouse-order-4021" \
  --data '{
    "supplier_id": "709d2a43-12a9-4d85-a9d9-cb16e66cef53",
    "location_id": "6d503033-433d-40f2-83a8-692687bfb384",
    "issue_date": "2026-07-19",
    "date_needed": "2026-07-31",
    "shipping": 12.5,
    "lines": [
      {
        "item_id": "d2fb4300-50ad-468f-a603-d5978acabb2e",
        "quantity": 5
      },
      {
        "name": "Setup service",
        "quantity": 1,
        "unit_cost": 50
      }
    ]
  }'

The optional Idempotency-Key supports short-lived replay. Repeating the same request with the same key during that window returns the original 201 response and includes Idempotent-Replayed: true. Reusing the key with different request data returns a conflict.

The API does not accept account, assigned-user, status, purchase-order-number, payment, receiving, total, cost-snapshot, or timestamp fields. Those values are controlled by SalesBinder.


Update a purchase order

PATCH/api/v3/purchase-orders/{purchase_order_id}

Required scope: purchase_orders:write

Updates supported fields on a purchase order in the Not Sent status. Sent, partially received, and received purchase orders cannot be updated through this endpoint.

PATCH requests are partial. Fields omitted from the request retain their current values. The supported detail fields are the same fields accepted when creating a purchase order.

Line replacement

If lines is omitted, every existing active line is preserved. If lines is supplied, it is the complete desired list of active lines:

  • Include an existing line's id to update and preserve that line.
  • Omit an existing line to remove it from the active purchase order.
  • Omit id to add a new line.
  • Each supplied line must contain the complete inventory-line or service-line data required for creation.
  • Discount lines are controlled with the top-level discount_percent field and must not be submitted directly.
  • A line ID must belong to the purchase order being updated and can appear only once.

Changing supplier_id or location_id requires lines in the same request. This ensures that supplier tax defaults and every inventory item's receiving location are revalidated together.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513" \
  --request PATCH \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: revise-warehouse-order-4021" \
  --data '{
    "date_needed": "2026-08-05",
    "shipping": 15,
    "lines": [
      {
        "id": "6087fabb-5252-42ef-948b-584ec3eb89f5",
        "item_id": "d2fb4300-50ad-468f-a603-d5978acabb2e",
        "quantity": 8,
        "unit_cost": 19.5
      },
      {
        "name": "Expedited handling",
        "quantity": 1,
        "unit_cost": 35
      }
    ]
  }'

The optional Idempotency-Key follows the same short-lived replay behavior as purchase-order creation.

The update does not change the purchase-order number or allocate another sequence number. It also does not change status, received quantities, payments, on-hand inventory, or incoming inventory.


Mark a purchase order as sent

POST/api/v3/purchase-orders/{purchase_order_id}/send

Required scope: purchase_orders:send

Marks an eligible Not Sent purchase order as Sent. This is a separate workflow permission from purchase_orders:write, so a restricted key must include the send scope explicitly.

The request body is optional. Supply date_sent in YYYY-MM-DD format to choose the sent date. If omitted, SalesBinder uses the current date in the API user's account timezone.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/send" \
  --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: send-warehouse-order-4021" \
  --data '{
    "date_sent": "2026-07-20"
  }'

The response is the complete purchase order with its status, sent date, and lines. The purchase-order number, totals, payments, received quantities, and line IDs are preserved.

Calling the endpoint again for a purchase order that is already Sent is safe. SalesBinder preserves the original date_sent and schedules the same incoming-inventory refresh again. Partially received and received purchase orders cannot use this endpoint.

The optional Idempotency-Key follows the same short-lived replay behavior as purchase-order creation and update. A replay returns the original response with Idempotent-Replayed: true.


Receive purchase-order quantities

POST/api/v3/purchase-orders/{purchase_order_id}/receive

Required scope: purchase_orders:receive

Records incremental quantities received against inventory lines on a Sent or Partially Received purchase order. Each request supplies the additional quantity received now, rather than the desired lifetime total.

Request fields

FieldTypeRequiredDescription
linesarrayYesBetween 1 and 100 inventory lines to receive.
received_datestringNoFinal received date in YYYY-MM-DD format. Stored only when this request fully receives the purchase order. Defaults to the current date in the API user's account timezone.

Line fields

FieldTypeRequiredDescription
line_idstringYesUUID of an inventory line on this purchase order. Service lines cannot be received through this endpoint.
quantitynumberYesPositive incremental quantity that does not exceed the line's remaining unreceived quantity.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/receive" \
  --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: warehouse-receipt-4021-1" \
  --data '{
    "received_date": "2026-07-21",
    "lines": [
      {
        "line_id": "6087fabb-5252-42ef-948b-584ec3eb89f5",
        "quantity": 3
      }
    ]
  }'

The response is the complete updated purchase order. A partial receipt changes the status to Partially Received and leaves date_received unset. Once every inventory line is fully received, the status changes to Received and SalesBinder stores the supplied or default received date.

The optional Idempotency-Key follows the same short-lived replay behavior as other purchase-order writes. It is strongly recommended for warehouse integrations so an immediate retry cannot apply the same incremental quantities twice.

Drop-shipped purchase orders, inactive receiving locations, draft or already received purchase orders, service lines, duplicate line IDs, and quantities above the remaining balance are rejected. The receipt and all line quantities are saved together or not at all.


List purchase orders

GET/api/v3/purchase-orders

Required scope: purchase_orders:read

Returns visible active purchase orders ordered by purchase-order number, newest first. Line items are omitted from list responses.

Query parameters

ParameterTypeRequiredDescription
pageintegerNoPage number. Defaults to 1.
limitintegerNoRecords per page. Defaults to 20; maximum 100.
qstringNoSearches supplier name, custom purchase-order number, and purchase-order name. A numeric value also matches an exact purchase-order number.
supplier_idstringNoReturns purchase orders for the supplier UUID.
status_idintegerNoReturns purchase orders with the status identifier.
location_idstringNoReturns purchase orders associated with the inventory location UUID.
issue_date_fromstringNoIncludes purchase orders issued on or after this YYYY-MM-DD date.
issue_date_tostringNoIncludes purchase orders issued on or before this YYYY-MM-DD date.
requested_date_fromstringNoIncludes purchase orders requested on or after this date.
requested_date_tostringNoIncludes purchase orders requested on or before this date.
needed_date_fromstringNoIncludes purchase orders needed on or after this date.
needed_date_tostringNoIncludes purchase orders needed on or before this date.
received_date_fromstringNoIncludes purchase orders received on or after this date.
received_date_tostringNoIncludes purchase orders received on or before this date.

All date filters require YYYY-MM-DD format.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders?supplier_id=709d2a43-12a9-4d85-a9d9-cb16e66cef53&limit=20" \
  --header "Authorization: Bearer YOUR_API_KEY"

Example response

json
{
  "object": "list",
  "url": "/api/v3/purchase-orders",
  "has_more": false,
  "data": [
    {
      "id": "c40e5d25-c573-48ec-aa46-9737eddf2513",
      "object": "purchase_order",
      "purchase_order_number": 4021,
      "supplier_id": "709d2a43-12a9-4d85-a9d9-cb16e66cef53",
      "supplier_name": "Example Supplier",
      "status_id": 18,
      "status": "Sent",
      "issue_date": "2026-07-18",
      "subtotal": "100.0000",
      "shipping": "10.0000",
      "tax": "5.5000",
      "tax_2": "2.2000",
      "total": "117.7000",
      "amount_paid": "25.0000",
      "amount_due": "92.7000"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total_pages": 1,
    "total_records": 1
  }
}

Examples may omit unchanged fields for readability.


Retrieve a purchase order

GET/api/v3/purchase-orders/{purchase_order_id}

Required scope: purchase_orders:read

Returns one visible active purchase order. The response includes the lines array in stored line order. Deleted lines are excluded.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513" \
  --header "Authorization: Bearer YOUR_API_KEY"

If the purchase order is outside the current account or assigned-user boundary, is a different document type, has been archived, or does not exist, the API returns 404 resource_missing.


List purchase-order payments

GET/api/v3/purchase-orders/{purchase_order_id}/payments

Required scope: purchase_orders:read

Returns recorded payments and refunds for one visible purchase order, ordered by payment date with the newest first. Purchase-order payments are separate from invoice payments.

ParameterTypeRequiredDescription
pageintegerNoPage number. Defaults to 1.
limitintegerNoRecords per page from 1 through 100. Defaults to 20.
bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/payments?limit=20" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Accept: application/json"
json
{
  "object": "list",
  "url": "/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/payments",
  "has_more": false,
  "data": [
    {
      "id": "2ce987a5-19a8-4bbe-ae2b-cff6da9fbfab",
      "object": "payment",
      "purchase_order_id": "c40e5d25-c573-48ec-aa46-9737eddf2513",
      "amount": "50.0000",
      "type": "payment",
      "reference": "Check 123",
      "payment_date": "2026-07-21",
      "card": null
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total_pages": 1,
    "total_records": 1
  }
}

The endpoint applies the same account, purchase-order type, active-record, assigned-user visibility, and permission boundaries as purchase-order retrieval. It never returns payments from another purchase order or account. An eligible purchase order with no recorded payments returns an empty data array and zero pagination totals.


Record a purchase-order payment

POST/api/v3/purchase-orders/{purchase_order_id}/payments

Required scope: purchase_orders:payments

Records a positive manual payment against the current purchase-order balance and returns the purchase-order payment object with 201 Created. The account must have purchase-order payments enabled, and the purchase order must be Sent, Partially Received, or Received.

Request fields

FieldTypeRequiredDescription
amountnumber or numeric stringYesPositive payment amount with no more than two decimal places. It cannot exceed the remaining balance.
payment_datestringYesPayment date in YYYY-MM-DD format.
referencestringNoOptional payment reference up to 255 characters.
bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/payments" \
  --request POST \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: po-payment-20260720-001" \
  --data '{
    "amount": "125.50",
    "payment_date": "2026-07-20",
    "reference": "Bank transfer 1042"
  }'
json
{
  "id": "2ce987a5-19a8-4bbe-ae2b-cff6da9fbfab",
  "object": "payment",
  "purchase_order_id": "c40e5d25-c573-48ec-aa46-9737eddf2513",
  "amount": "125.5000",
  "type": "payment",
  "reference": "Bank transfer 1042",
  "payment_date": "2026-07-20",
  "card": null
}

The payment and the purchase order's amount_paid, amount_due, and date_fully_paid values are updated together. SalesBinder rechecks the current balance and prevents concurrent or stale requests from overpaying the purchase order. A fully paid or ineligible purchase order returns 409 purchase_order_payment_not_allowed. Invalid amounts, dates, and fields return a field-specific 422 error.

Use an optional Idempotency-Key when retrying the same logical payment. An identical retry within the short idempotency window returns the original 201 response with Idempotent-Replayed: true; reusing the key with different request data returns 409 idempotency_key_reused.


Delete a purchase-order payment

DELETE/api/v3/purchase-orders/{purchase_order_id}/payments/{payment_id}

Required scope: purchase_orders:payments

Deletes one positive manual payment and recalculates the purchase order's paid state as part of the same operation. Use this endpoint when a payment was entered in error or the purchase order should no longer be marked as paid.

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513/payments/2ce987a5-19a8-4bbe-ae2b-cff6da9fbfab" \
  --request DELETE \
  --header "Authorization: Bearer YOUR_API_KEY"
json
{
  "id": "2ce987a5-19a8-4bbe-ae2b-cff6da9fbfab",
  "object": "payment",
  "purchase_order_id": "c40e5d25-c573-48ec-aa46-9737eddf2513",
  "deleted": true
}

The payment must belong to the visible purchase order and current account. Negative historical adjustment records cannot be deleted through this endpoint, and SalesBinder returns 409 purchase_order_payment_delete_not_allowed if deleting a payment would leave a negative paid balance. Deleting a payment from a fully paid purchase order clears date_fully_paid when a balance becomes due again.

Payment deletion does not use an idempotency key. Repeating a completed deletion returns 404 resource_missing because the payment no longer exists.


Delete a purchase order

DELETE/api/v3/purchase-orders/{purchase_order_id}

Required scope: purchase_orders:delete

Deletes an eligible purchase order and its lines. Deletion is limited to a Not Sent purchase order for which no related processing has begun. The purchase order must have:

  • no payments;
  • no received quantities or received date;
  • no sent date;
  • no drop-shipping activity;
  • no associated sales order or other linked document; and
  • no packing list or shipping shipment.

SalesBinder returns 409 purchase_order_delete_not_allowed when the purchase order exists within the key's visibility boundary but does not meet every deletion condition. Deleting a purchase order never deletes related payments, sales orders, packing lists, or shipments.

Example request

bash
curl "https://yourbusiness.salesbinder.com/api/v3/purchase-orders/c40e5d25-c573-48ec-aa46-9737eddf2513" \
  --request DELETE \
  --header "Authorization: Bearer YOUR_API_KEY"

Example response

json
{
  "id": "c40e5d25-c573-48ec-aa46-9737eddf2513",
  "object": "purchase_order",
  "deleted": true
}

Deleting a not-sent draft does not change on-hand or incoming inventory quantities. The purchase order and its lines are deleted together, and related account totals and activity are refreshed automatically.


Permissions and write behavior

API key scopes can reduce access but cannot exceed the current user's SalesBinder permissions. Purchase-order access requires the current purchase-order and unit-cost permissions. Without current view-all-purchase-orders permission, operations are limited to purchase orders assigned to the user. Creation, receiving, and managing payments also require current purchase-order-modify permission and follow the user's inventory-location restriction.

If a dedicated purchase-order permission is not configured, SalesBinder may use the corresponding inventory-modify permission. An explicit purchase-order permission denial is always respected.

Receiving is limited to incremental inventory-line quantities on sent, non-drop-shipped purchase orders. To correct a positive manual payment entered in error, delete that payment; API v3 does not create a separate purchase-order refund record. API v3 does not support service-only receiving, archiving, or restoring purchase orders. Unsupported fields and actions are rejected.