APIv3
Exit Documentation

Sales orders

A sales order records products or services that a customer has ordered and tracks how much has been invoiced, packed, and shipped. API v3 can create open sales orders, invoice or pack selected remaining quantities, mark packing fulfillments as shipped, update or delete eligible orders, and read visible sales orders with their current line items and fulfillment history.


The sales order object

FieldTypeDescription
idstringSalesBinder UUID for the sales order.
objectstringAlways sales_order.
sales_order_numberintegerAccount-local SalesBinder sales-order number.
namestring or nullOptional sales-order name or reference.
customer_idstringUUID of the customer.
customer_namestring or nullCustomer name stored with the sales order.
salesperson_idstringUUID of the assigned SalesBinder user.
location_idstring or nullUUID of the assigned inventory location.
status_idintegerCurrent SalesBinder sales-order status ID.
statusstring or nullCurrent status name.
issue_datestring or nullIssue date in YYYY-MM-DD format.
expiry_datestring or nullExpiry date in YYYY-MM-DD format.
purchase_order_numberstring or nullCustomer-provided purchase-order number.
attentionstring or nullAttention or recipient information.
shipping_addressstring or nullShipping address stored on the sales order.
drop_shippedbooleanWhether the sales order is drop-shipped.
drop_ship_customer_idstring or nullUUID of the drop-ship customer when applicable.
drop_ship_addressstring or nullDrop-ship address when applicable.
public_notestring or nullCustomer-visible note.
packing_list_notestring or nullNote intended for packing-list workflows.
payment_termsstring or nullPayment terms stored on the sales order.
subtotalstringSubtotal excluding shipping and taxes, with four decimal places.
shippingstringCustomer shipping charge, with four decimal places.
taxstringFirst tax total, with four decimal places.
tax_2stringSecond tax total, with four decimal places.
totalstringSales-order total including taxes, with four decimal places.
amount_paidstringApplied payment total, with four decimal places.
amount_duestringRemaining balance, with four decimal places.
invoiced_percentnumber or nullPercentage of the sales order invoiced.
paid_percentnumber or nullPercentage of the sales order paid.
packed_percentnumber or nullPercentage of the sales order packed.
shipped_percentnumber or nullPercentage of the sales order shipped.
invoice_countintegerNumber of invoices currently associated with the sales order.
created_atstring or nullCreation timestamp in ISO 8601 format.
updated_atstring or nullLast-modified timestamp in ISO 8601 format.
linesarrayCurrent line items. Included only when retrieving one sales order.

Sales-order and line-item unit costs are not included in API v3 responses.

The sales order line object

FieldTypeDescription
idstringUUID of the sales-order line.
objectstringAlways sales_order_line.
item_idstring or nullInventory item UUID, or null for a service line.
item_variation_location_idinteger or nullSelected variation-location identifier when applicable.
namestring or nullLine-item name.
descriptionstring or nullLine-item description.
quantitynumberQuantity ordered.
quantity_invoicednumberQuantity already invoiced.
quantity_packednumberQuantity already packed.
quantity_shippednumberQuantity already shipped.
unit_idinteger or nullSalesBinder unit ID.
unit_pricestringUnit selling price, with four decimal places.
discount_percentstringLine discount rate, with three decimal places.
discounted_unit_pricestring or nullDiscounted unit price when one is stored.
tax_ratestringFirst tax rate, with three decimal places.
tax_2_ratestringSecond tax rate, with three decimal places.
subtotalstringLine quantity multiplied by its effective unit price, with four decimal places.

The fulfillment object

FieldTypeDescription
idstringUUID of the packing-list fulfillment.
objectstringAlways fulfillment.
sales_order_idstringUUID of the related sales order.
packing_list_numberintegerAccount-local packing-list number.
statusstringpacked until a shipped date is recorded, then shipped.
units_packednumberTotal quantity represented by the packing snapshot.
shipped_datestring or nullShipment date in YYYY-MM-DD format.
carrierstring or nullManual or provider shipping carrier.
tracking_numberstring or nullCarrier tracking number.
tracking_urlstring or nullPublic shipment-tracking URL.
tracking_statusstring or nullLatest stored provider tracking status.
tracking_status_detailsstring or nullLatest stored provider tracking detail.
estimated_delivery_datestring or nullEstimated delivery in YYYY-MM-DD format.
tracking_updated_atstring or nullISO 8601 timestamp of the latest tracking update.
linesarrayHistorical packed-line snapshot.
lines[].sales_order_line_idstringUUID of the sales-order line that was packed.
lines[].quantitynumberQuantity packed for the line in this fulfillment.
created_atstring or nullCreation timestamp in ISO 8601 format.
updated_atstring or nullLast-modified timestamp in ISO 8601 format.

Create a sales order

POST/api/v3/sales-orders

Required scope: sales_orders:write

Creates an open sales order assigned to the API key's current user. SalesBinder assigns the sales-order number and derives status, costs, totals, fulfillment quantities, and customer information server-side.

FieldTypeRequiredDescription
customer_idstringYesUUID of an active customer in the current account.
location_idstringNoInventory-location UUID. It must follow the user's location restriction, when one exists.
namestringNoSales-order name or reference.
issue_datestringNoYYYY-MM-DD; defaults to the user's current local date.
expiry_datestringNoYYYY-MM-DD; cannot be before issue_date.
purchase_order_numberstringNoCustomer purchase-order reference.
attentionstringNoAttention or recipient information.
shipping_addressstringNoShipping address for the order.
public_notestringNoCustomer-visible note.
packing_list_notestringNoNote for packing-list workflows.
payment_termsstringNoPayment terms. Account defaults apply when omitted.
shippingnumberNoNon-negative customer shipping charge. Defaults to 0.
discount_percentnumberNoOrder-wide discount from 0 through 100.
linesarrayYesFrom 1 through 100 inventory or service lines.

Inventory lines use item_id, optional item_variation_location_id, quantity, optional description, and optional tax rates. SalesBinder supplies the item's current selling price unless unit_price is provided and the user currently has permission to modify selling prices. Service lines omit item_id and require name and unit_price.

bash
curl https://yourbusiness.salesbinder.com/api/v3/sales-orders \
  -X POST \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: warehouse-order-2026-07-19-001" \
  -d '{
    "customer_id": "06be9b09-bb9c-4555-aa95-0629285ee050",
    "location_id": "2e665b38-3a31-451f-a61e-e7da20e09b29",
    "issue_date": "2026-07-19",
    "shipping": 5,
    "lines": [
      {"item_id": "3f7cdc78-64e4-4897-b465-e9de6c14cdea", "quantity": 2},
      {"name": "Setup", "quantity": 1, "unit_price": 50}
    ]
  }'

The response is the newly created sales order object with lines and HTTP status 201. Repeating the same request with the same short-lived Idempotency-Key returns the original response instead of creating a quick duplicate.


List sales orders

GET/api/v3/sales-orders

Required scope: sales_orders:read

Returns a page of visible sales orders ordered by sales-order number, newest first. Line items are omitted from list responses.

Query parameters

ParameterTypeRequiredDescription
pageintegerNoPage number. Defaults to 1.
limitintegerNoRecords per page from 1 to 100. Defaults to 20.
qstringNoSearches customer name, customer purchase-order number, sales-order name, or an exact numeric sales-order number.
customer_idstringNoReturns sales orders for this customer UUID.
status_idintegerNoReturns sales orders with this status ID.
location_idstringNoReturns sales orders assigned to this inventory-location UUID.
assigned_user_idstringNoReturns sales orders assigned to this user UUID. This filter cannot expand the key user's visibility.
issue_date_fromstringNoIncludes sales orders issued on or after this YYYY-MM-DD date.
issue_date_tostringNoIncludes sales orders issued on or before this YYYY-MM-DD date.
expiry_date_fromstringNoIncludes sales orders expiring on or after this YYYY-MM-DD date.
expiry_date_tostringNoIncludes sales orders expiring on or before this YYYY-MM-DD date.
bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders?customer_id=06be9b09-bb9c-4555-aa95-0629285ee050&status_id=29&limit=20" \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Accept: application/json"
json
{
  "object": "list",
  "url": "/api/v3/sales-orders",
  "has_more": false,
  "data": [
    {
      "id": "95000000-0000-4000-8000-000000000101",
      "object": "sales_order",
      "sales_order_number": 7002,
      "name": "Warehouse restock",
      "customer_id": "06be9b09-bb9c-4555-aa95-0629285ee050",
      "customer_name": "Acme Customer",
      "salesperson_id": "10f36523-23ef-442d-8d68-4aa206d93160",
      "location_id": "2e665b38-3a31-451f-a61e-e7da20e09b29",
      "status_id": 29,
      "status": "Open",
      "issue_date": "2026-07-01",
      "expiry_date": "2026-08-01",
      "purchase_order_number": "CUSTOMER-PO-7002",
      "attention": "Receiving",
      "shipping_address": "123 Customer Road",
      "drop_shipped": false,
      "drop_ship_customer_id": null,
      "drop_ship_address": "",
      "public_note": "Sales-order terms.",
      "packing_list_note": "Pack carefully.",
      "payment_terms": "Net 30",
      "subtotal": "100.0000",
      "shipping": "10.0000",
      "tax": "5.5000",
      "tax_2": "2.2000",
      "total": "117.7000",
      "amount_paid": "25.0000",
      "amount_due": "92.7000",
      "invoiced_percent": 50,
      "paid_percent": 25,
      "packed_percent": 50,
      "shipped_percent": 25,
      "invoice_count": 1,
      "created_at": "2026-07-01T12:00:00+00:00",
      "updated_at": "2026-07-02T12:00:00+00:00"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total_pages": 1,
    "total_records": 1
  }
}

Retrieve a sales order

GET/api/v3/sales-orders/{sales_order_id}

Required scope: sales_orders:read

Returns one visible sales order and its current line items.

bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101" \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Accept: application/json"

The response uses the sales order object above and adds lines:

json
{
  "id": "95000000-0000-4000-8000-000000000101",
  "object": "sales_order",
  "sales_order_number": 7002,
  "customer_id": "06be9b09-bb9c-4555-aa95-0629285ee050",
  "customer_name": "Acme Customer",
  "status_id": 29,
  "status": "Open",
  "total": "117.7000",
  "invoiced_percent": 50,
  "packed_percent": 50,
  "shipped_percent": 25,
  "lines": [
    {
      "id": "95000000-0000-4000-8000-000000000201",
      "object": "sales_order_line",
      "item_id": "95000000-0000-4000-8000-000000000601",
      "item_variation_location_id": null,
      "name": "Warehouse supplies",
      "description": "Sales-order line",
      "quantity": 2,
      "quantity_invoiced": 1,
      "quantity_packed": 1,
      "quantity_shipped": 0.5,
      "unit_id": 1,
      "unit_price": "50.0000",
      "discount_percent": "10.000",
      "discounted_unit_price": "45.0000",
      "tax_rate": "5.000",
      "tax_2_rate": "2.000",
      "subtotal": "90.0000"
    }
  ]
}

A sales order outside the key user's account or assigned-user visibility is returned as a missing resource rather than revealing that the record exists.


List fulfillments for a sales order

GET/api/v3/sales-orders/{sales_order_id}/fulfillments

Required scope: sales_orders:read

Returns the sales order's packing lists with their historical packed-line quantities and current shipping or tracking state. Packing lists are ordered by number with the newest first and use the standard page-based list envelope.

ParameterTypeRequiredDescription
pageintegerNoPage number. Defaults to 1.
limitintegerNoRecords per page from 1 through 100. Defaults to 20.
bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/fulfillments?limit=20" \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Accept: application/json"
json
{
  "object": "list",
  "url": "/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/fulfillments",
  "has_more": false,
  "data": [
    {
      "id": "95000000-0000-4000-8000-000000000401",
      "object": "fulfillment",
      "sales_order_id": "95000000-0000-4000-8000-000000000101",
      "packing_list_number": 2,
      "status": "shipped",
      "units_packed": 1.5,
      "shipped_date": "2026-07-20",
      "carrier": "Canada Post",
      "tracking_number": "TRACK-7002-2",
      "tracking_url": "https://tracking.example/7002-2",
      "tracking_status": "in_transit",
      "tracking_status_details": "Package is moving",
      "estimated_delivery_date": "2026-07-24",
      "tracking_updated_at": "2026-07-20T14:30:00+00:00",
      "lines": [
        {
          "sales_order_line_id": "95000000-0000-4000-8000-000000000201",
          "quantity": 1.5
        }
      ],
      "created_at": "2026-07-20T12:00:00+00:00",
      "updated_at": "2026-07-20T14:30:00+00:00"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total_pages": 1,
    "total_records": 1
  }
}

The fulfillment object is the public representation of SalesBinder's packing-list record. status is packed until a shipped date is recorded and shipped afterward. Manual shipping details and provider-backed label or tracking updates converge on the same public carrier and tracking fields.

The lines array preserves what was packed, even if the current sales-order line later changes. The response includes only the fulfillment fields documented above.

The endpoint applies the same current account, live sales-order permission, and assigned-user visibility boundary as retrieving the sales order. An inaccessible sales order returns 404 resource_missing.


Create a packing fulfillment

POST/api/v3/sales-orders/{sales_order_id}/fulfillments

Required scope: sales_orders:pack

Creates one packing list from explicit remaining sales-order quantities and returns the new fulfillment object with 201 Created.

bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/fulfillments" \
  --request POST \
  --header "Authorization: Bearer sb_live_your_api_key" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: pack-order-7002-1" \
  --data '{
    "lines": [
      {
        "id": "95000000-0000-4000-8000-000000000201",
        "quantity": 1.5
      }
    ]
  }'

lines must be a non-empty array of at most 100 entries. Each entry accepts only:

FieldTypeRequiredDescription
idstringYesUUID of one line on the sales order. Each line can appear once.
quantitynumberYesPositive incremental quantity to pack. It cannot exceed the line's current unpacked quantity.

Inventory lines are packable. Service lines are packable only when the account's packing-list service-item setting is enabled. Discount lines cannot be packed.

The account must have packing lists enabled, the sales order must remain open and visible, and the user must retain sales-order-modify permission and access to the order's inventory location. A closed or concurrently fully packed order returns 409 sales_order_pack_not_allowed; a line already fully packed at initial validation returns 409 sales_order_line_already_packed.

SalesBinder rechecks all submitted quantities and prevents concurrent requests from overpacking. The packing list, line quantities, and packed percentage are saved together or not at all. Packing does not change on-hand inventory quantity.

Use an optional Idempotency-Key when retrying the same logical packing operation. An identical retry within the short idempotency window returns the original 201 response without packing twice; reusing the key with different request data returns 409 idempotency_key_reused.

Shipping is intentionally separate. This endpoint does not accept a carrier, tracking number, shipped date, label, rate, or provider payload.


Mark a fulfillment as shipped

POST/api/v3/sales-orders/{sales_order_id}/fulfillments/{fulfillment_id}/ship

Required scope: sales_orders:ship

Marks one existing packing fulfillment as manually shipped and returns the updated fulfillment object with 200 OK. This endpoint records an existing shipment; it does not quote rates or purchase a shipping label.

bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/fulfillments/95000000-0000-4000-8000-000000000401/ship" \
  --request POST \
  --header "Authorization: Bearer sb_live_your_api_key" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: ship-order-7002-pl-2" \
  --data '{
    "shipped_date": "2026-07-21",
    "carrier": "Canada Post",
    "tracking_number": "TRACK-7002-2",
    "tracking_url": "https://tracking.example/7002-2",
    "estimated_delivery_date": "2026-07-24"
  }'
FieldTypeRequiredDescription
shipped_datestringNoShipment date in YYYY-MM-DD format. Defaults to the API user's current local date.
carrierstringNoShipping carrier, up to 60 characters. Omission preserves an existing value.
tracking_numberstringNoCarrier tracking number, up to 60 characters. Omission preserves an existing value.
tracking_urlstringNoHTTP or HTTPS tracking URL, up to 250 characters. Omission preserves an existing value.
estimated_delivery_datestringNoEstimated delivery in YYYY-MM-DD format. It cannot be before shipped_date.

The account must have packing lists enabled, and the user must retain sales-order-modify permission, current sales-order visibility, and access to the order's inventory location. The fulfillment must belong to that sales order and account and must not already have a shipped date. Missing or inaccessible parents and fulfillments return 404 resource_missing; an already shipped fulfillment returns 409 sales_order_ship_not_allowed.

SalesBinder rechecks the fulfillment state and saves the shipped date, shipment fields, line-level shipped quantities, and order progress together. When automatic shipping notifications are enabled, SalesBinder sends the customer notification after the shipment is saved. Shipping activity is recorded automatically.

Carrier, tracking number, or tracking URL values already stored by a manual or provider workflow do not mark a fulfillment as shipped by themselves. Only shipped_date performs that transition. Omitted optional fields preserve those existing values.

Use an optional Idempotency-Key for safe retries. An identical retry during the short idempotency window returns the original 200 response even though the fulfillment is now shipped. Reusing the key with different request data returns 409 idempotency_key_reused.


List invoices for a sales order

GET/api/v3/sales-orders/{sales_order_id}/invoices

Required scopes: sales_orders:read and invoices:read

Returns invoices linked to one visible sales order, ordered by invoice number with the newest first. The endpoint uses the same page-based pagination as other API v3 collections.

ParameterTypeRequiredDescription
pageintegerNoPage number. Defaults to 1.
limitintegerNoRecords per page from 1 through 100. Defaults to 20.
bash
curl "https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/invoices?limit=20" \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Accept: application/json"
json
{
  "object": "list",
  "url": "/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/invoices",
  "has_more": false,
  "data": [
    {
      "id": "95000000-0000-4000-8000-000000000701",
      "object": "invoice",
      "invoice_number": 1042,
      "customer_id": "06be9b09-bb9c-4555-aa95-0629285ee050",
      "status_id": 9,
      "status": "Unpaid",
      "total": "52.5000",
      "amount_paid": "0.0000",
      "amount_due": "52.5000"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total_pages": 1,
    "total_records": 1
  }
}

The data array uses the compact invoice object without lines. Retrieve an invoice through GET/api/v3/invoices/{invoice_id} when its current lines are needed.

Both visibility boundaries apply independently. The sales order must be visible through the user's current sales-order permissions, and each returned invoice must be visible through the user's current invoice permissions. An inaccessible sales order returns 404 resource_missing; inaccessible linked invoices are omitted from the collection.


Create an invoice from a sales order

POST/api/v3/sales-orders/{sales_order_id}/invoice

Required scope: sales_orders:invoice

Creates an unpaid invoice from an open sales order. Send an empty JSON object to invoice every remaining quantity:

bash
curl https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/invoice \
  -X POST \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-order-7002-remaining" \
  -d '{}'

To create a partial invoice, provide one or more sales-order line IDs and the positive quantity to invoice now:

bash
curl https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101/invoice \
  -X POST \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-order-7002-partial-1" \
  -d '{
    "lines": [
      {
        "id": "95000000-0000-4000-8000-000000000201",
        "quantity": 0.5
      }
    ]
  }'
FieldTypeRequiredDescription
linesarrayNoOmit to invoice all remaining quantities. When supplied, include from 1 through 100 unique sales-order lines.
lines[].idstringYesID of a non-discount line belonging to this sales order.
lines[].quantitynumberYesPositive quantity to invoice now. It cannot exceed the line's remaining uninvoiced quantity.

The response is the newly created invoice object with lines and HTTP status 201. SalesBinder copies the selected sales-order line details, shipping, customer, notes, payment terms, and applicable order-level discount into the invoice. The sales order's invoiced quantities, percentage, and invoice count are refreshed from its linked invoices.

This action requires the API scope above plus the user's current sales-order-modify and invoice-modify permissions. Account and assigned-user visibility still apply, and creating the invoice follows the account's current record limit.

Use a unique Idempotency-Key for each intended invoice. During the short replay window, an identical retry returns the original 201 response with Idempotent-Replayed: true. Reusing the key with a different body returns 409 Conflict.

The endpoint returns 409 sales_order_invoice_not_allowed for a closed sales order, 409 sales_order_already_invoiced when no invoiceable quantity remains, and 409 sales_order_line_already_invoiced when a selected line has no remaining quantity. Invalid, duplicate, discount, or excessive line quantities return 422 invalid_sales_order_invoice.


Update a sales order

PATCH/api/v3/sales-orders/{sales_order_id}

Required scope: sales_orders:write

Updates supported fields on an open sales order. Omitted fields retain their current values. Header fields remain editable after fulfillment begins; financial and line fields require a completely untouched order.

FieldTypeDescription
namestringSales-order name or reference.
issue_datestringNon-empty date in YYYY-MM-DD format.
expiry_datestring or nullDate in YYYY-MM-DD format. Send an empty string or null to clear it.
purchase_order_numberstringCustomer purchase-order reference.
attentionstringAttention or recipient information.
shipping_addressstringShipping address for the order.
public_notestringCustomer-visible note.
packing_list_notestringNote for packing-list workflows.
payment_termsstringPayment terms.
shippingnumberNon-negative customer shipping charge. Only available before payment or fulfillment begins.
discount_percentnumberOrder-wide discount from 0 through 100. Only available before payment or fulfillment begins.
linesarrayComplete replacement of 1 through 100 active lines. Only available before payment or fulfillment begins.

When lines is supplied, each existing non-discount line may include its id to retain that line identifier. Omitted lines are permanently removed, and new lines omit id. Every supplied line must include the complete inventory or service-line data needed to rebuild it. Discount lines are server-managed and must be changed with discount_percent rather than included in lines.

bash
curl https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101 \
  -X PATCH \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: warehouse-order-header-2026-07-19-001" \
  -d '{
    "purchase_order_number": "CUSTOMER-PO-UPDATED",
    "shipping": 12,
    "discount_percent": 10,
    "lines": [
      {
        "id": "95000000-0000-4000-8000-000000000201",
        "item_id": "3f7cdc78-64e4-4897-b465-e9de6c14cdea",
        "quantity": 3
      },
      {"name": "Updated setup", "quantity": 1, "unit_price": 75}
    ]
  }'

The response is the updated sales order object with lines. All updates preserve the sales-order number, status, customer, salesperson, location, fulfillment quantities, and document associations. Costs, taxes, discounts, weights, and totals are calculated server-side.

Line replacement and total recalculation are completed together. If any line fails to save, the order, its previous lines, and its previous totals remain unchanged. Reserved quantities may update shortly after a successful response; on-hand quantity does not change.

Repeating the same request with the same short-lived Idempotency-Key returns the original response without applying the update twice.


Delete a sales order

DELETE/api/v3/sales-orders/{sales_order_id}

Required scope: sales_orders:delete

Permanently deletes an open sales order and its lines when no related processing has begun.

bash
curl https://yourbusiness.salesbinder.com/api/v3/sales-orders/95000000-0000-4000-8000-000000000101 \
  -X DELETE \
  -H "Authorization: Bearer sb_live_your_api_key" \
  -H "Accept: application/json"
json
{
  "id": "95000000-0000-4000-8000-000000000101",
  "object": "sales_order",
  "deleted": true
}

The endpoint returns 409 Conflict when the sales order is closed or has payments, invoices, purchase orders, packing lists, shipments, drop-shipping activity, or invoiced, packed, or shipped quantities. Deleting a sales order never deletes those related records. Delete access also follows the user's current SalesBinder delete permission and assigned-user visibility.

The sales order and its lines are deleted together. Reserved quantities may update shortly after the response; on-hand inventory quantity does not change.


Unsupported operations

API v3 does not allow changing a sales order's customer, salesperson, location, status, or document associations directly. Financial and line updates are unavailable after related processing begins. Deleting is limited to untouched open sales orders. Packing and manual shipping use dedicated fulfillment endpoints. API v3 does not support closing, reopening, provider-backed label purchases, shipment reversal, or crediting previously invoiced quantities. Unsupported fields and actions are rejected.

Sales orders can also be created from eligible estimates through POST/api/v3/estimates/{estimate_id}/convert-to-sales-order. That dedicated action preserves the source relationship and closes the estimate as part of the same operation.

Sales-order reads and header-only updates do not change reserved inventory or recalculate fulfillment percentages. After creation, estimate conversion, line replacement, or invoicing, related reserved-inventory values may update shortly after the response.