When to use this endpoint

Use the CRM2 generic order widget’s grouped creation flow. This route delegates to the same checked creator as PurchaseOrder_createFromJob.

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 identity.

Requires Purchase Order View and Add on the singular/plural page; nested line creation also requires Edit. Supplier/form/target references and target record visibility are checked before saving.

Parameters

ParameterTypeRequiredDescription
suppliersNative array of objectsYesGroups {id:supplierID,formID:formID,purchaseOrderEntry:[mappedLine,...]}. Not decoded from a JSON string. Empty array creates nothing and returns an empty id list; duplicate supplier groups create separate headers.
referenceTextNoDefaults to blank. Maximum 32 Unicode characters; validated before persistence.
containerNative value/objectLegacy ignored inputNot used by the creator. It is not required for target linking and does not allocate stock.
targetNative {type,id} pickerNoApplied directly without a container gate. Validates type/ID, target View and scope. No Link and Warehouse use type 0/7 with ID zero. No specialized resource merge or allocation occurs.
suppliers[].purchaseOrderEntryNative mapped line arrayNoEach row is passed to PurchaseOrderEntry_createData with poID replaced by the new header ID. Supply stock, quantity, cost and explicit line totals as needed.

Example request

$result = FM_api('PurchaseOrders_createData', [
	'suppliers'=>[[
		'id'=>'42','formID'=>'5',
		'purchaseOrderEntry'=>[[
			'stock'=>['id'=>'0','type'=>'2','text'=>'Packing materials'],
			'amt'=>'2','costNet'=>'10','totalNet'=>'20','totalTax'=>'4',
		]],
	]],
	'reference'=>'Materials order',
]);

Example response

{
  "ok": 1,
  "id": [
    1042
  ]
}

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": "missing or invalid parameter: suppliers"}suppliers is missing or is not a native list. Malformed groups/lines, unavailable suppliers/forms, inaccessible targets and invalid line values return errors.
{"error":"permission denied"}The required page permission is missing. Hidden/deleted records are omitted from collections; explicit parent readers reject an inaccessible parent.

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

Behaviour and edge cases

  • Returns header IDs in supplier-group order. Empty suppliers returns an empty ID list; repeated supplier groups create separate orders.
  • All groups and lines use one tenant-owner transaction, checked reference validation, reserved displayed numbering, initial availability, totals and creation/line history. A later child error rolls back all earlier groups.
  • Supplied target is applied whether or not container is present. Destination allocation remains a separate OrderContainer_setAllocate call in CRM2.
  • Does not send header creation notifications because the grouped creator disables that notification; successful child behavior is shared with PurchaseOrderEntry_createData. Deferred events/effects run after the owning commit.

Side effects

  • Creates headers/lines, history, line totals and initial stock availability atomically. Does not email suppliers or allocate stock to a destination. A committed follow-up warning requires checking saved state before retrying.

See it in Fieldmotion

CRM1

No direct CRM1 literal caller was found in the searched client source. CRM1 uses PurchaseOrder_new and the legacy line editor.

CRM2

In CRM2’s generic stock/order widget, select materials and suppliers and create Purchase Orders; inspect PurchaseOrders_createData. The widget then issues separate OrderContainer_setAllocate calls for its destination.

Related endpoints