Purchase orders
Change an order reference
/a/PurchaseOrder_setReference
Save a human-readable reference without renumbering the order.
When to use this endpoint
Use when the operator changes the Reference field. Use PurchaseOrder_setNum to change po_num instead.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured.
Requires explicit View on Purchase Order or Purchase Orders. Writes also require the matching Edit permission; clearing invoice details requires Delete. A non-administrator blocked by the legacy Purchase Orders visibility flag (crm_access bit 256) is denied. API keys use their owner’s permissions.
The primary order is checked against the current tenant and Purchase Order record scope. Configured TeamAccess follows permitted linked Contracts, Customers, Jobs, Quotes and Departments; the legacy department filter follows direct Customer/Quote/customer-Job links. An inaccessible or missing order returns purchase order does not exist.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer-compatible | Yes | Positive local Purchase Order ID/digit string; not the displayed po_num. Missing, malformed or inaccessible IDs fail. |
reference | String | Yes | Truthy string, at most 32 bytes by strlen. Blank and "0" are rejected; surrounding whitespace is not trimmed. |
Example request
$result = FM_api('PurchaseOrder_setReference', [
'id'=>'1042',
'reference'=>'PO-NORTH-318',
]);
Example response
{
"ok": 1
}
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
{"error": "no purchase order ID provided"} | id is absent/null; zero is not rejected by this presence check. |
{"error": "missing parameter: reference"} | reference is absent or falsy. |
{"error": "reference too long. max length 32"} | Byte length exceeds 32. |
{"error": "permission denied"} | The required page/action or legacy visibility setting denies access. |
{"error": "purchase order does not exist"} | The primary order is missing or outside the caller’s permitted scope. |
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 a positive ID and a truthy string reference of at most 32 bytes. Blank and "0" remain rejected; whitespace is not trimmed.
- No uniqueness policy is imposed. The displayed order number and line items are unchanged. Identical text is an idempotent no-op.
Side effects
- Header writes lock the existing order and tenant owner, check persistence and record history in the same transaction. Errors roll back the header and audit; a true no-op returns {ok:1,warning:"no change needed"} without a new event/history entry. Cache invalidation and edit-event follow-ups run after the owning transaction commits; an event exception returns saved=1 and a no-replay warning.
- A changed header emits PurchaseOrder_edit after commit; configured account listeners may perform integration work. No order email/PDF is sent directly by this route.
See it in Fieldmotion
CRM1
In CRM1 Purchase Order details, change Reference and blur the field. The page applies its own 32-character check and calls PurchaseOrder_setReference.
CRM2
No direct caller was found in CRM2 source. Its Purchase Order screen uses mapped reads and generic field saves rather than this legacy endpoint.
Related endpoints
PurchaseOrder_getReference— Read the saved reference.PurchaseOrder_setNum— Change the displayed number.