When to use this endpoint

Cancel an order first, then use Delete to remove its active header. This is not a receipt reversal or a stock rollback.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured. API keys use their owner’s permissions.

Requires explicit View on Purchase Order or Purchase Orders, plus Delete on either page. Non-administrators with legacy Purchase Orders visibility disabled (crm_access bit 256) are denied.

Explicit order IDs must identify active, visible records in the authenticated tenant. TeamAccess follows linked Contracts, Customers, Jobs, Quotes and Departments; legacy department filtering follows Customer, Quote-customer and ordinary customer-Job links. Scoped users cannot read unlinked or Warehouse orders through this check.

Parameters

ParameterTypeRequiredDescription
idPositive integer or digit stringYesLocal Purchase Order ID; not po_num. Missing, malformed or inaccessible IDs fail.

Example request

$result = FM_api('PurchaseOrder_delete', ['id'=>'1042']);

Example response

{
  "ok": 1
}

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error": "permission denied"}Page/action rights or the legacy visibility setting deny access.
{"error": "purchase order does not exist"}An explicit parent/header ID is absent, deleted or outside the caller’s scope.
{"error": "Purchase Order not of a valid status for deletion"}The header is not Cancelled.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Requires received status 4 (Cancelled). Despite the older comment about unsent/unfulfilled orders, this handler does not separately check date_sent or receipt quantities once status is Cancelled.
  • Marks the header deleted with a deletion timestamp. It does not delete its line rows, detach requisition links, remove order containers or reverse inventory.
  • Repeated deletion is rejected by the dispatcher’s active-parent check. There is no bulk selector or pagination.

Side effects

  • Updates deleted/ddate, touches the header/cache and records the deletion log. Removes matching global queued accounting-upload links and tenant accounting mappings for this Purchase Order.
  • These operations do not share a route-owned transaction; a later failure can leave the deletion only partly reflected in sync metadata.

See it in Fieldmotion

CRM1

In CRM1 Purchase Orders, delete a cancelled order and inspect PurchaseOrder_delete.

CRM2

In CRM2 Purchase Orders, use the bulk Delete action on cancelled orders. The client calls PurchaseOrder_delete once per selected ID; it is a sequence of separate deletes, not one atomic batch.

Related endpoints