Skip to content

Create Purchase Order

Creates a new purchase order with one or more line items.


Request

POST /api/purchase-order

Required privilege: Procurement / Edit Content-Type: application/json CSRF header required: X-XSRF-TOKEN


Request Body

{
  "PO List Number": "PO-2024-100",
  "PO List Document Status": "Open",
  "PO List Order Date": "2024-03-15",
  "Supplier Number": "SUP-007",
  "Purchase Order Id": null,
  "details": [
    {
      "id": null,
      "PO Details Id": null,
      "Item Number": "ITEM-A",
      "Sub Item Number": null,
      "Warehouse Number": "WH-01",
      "Ship From Number": "SF-01",
      "PO Details Price": 12.50,
      "PO Details Quantity": 200,
      "PO Details Document Status": "Open",
      "PO Details Tracking": null,
      "PO Details Order Date": "2024-03-15",
      "PO Details Ship Date": "2024-03-22",
      "PO Details ETA Date": "2024-03-28",
      "PO Details First Promise Date": null,
      "PO Details Request Date": null,
      "PO Details Actual Ship Date": null,
      "PO Details Actual Delivery Date": null,
      "PO Details Unique Id": "ERP-LINE-001",
      "PO Details Local": null
    }
  ]
}

Request Fields

Top-level (PO Header)

Field Type Required Description
PO List Number string Yes Unique PO document number
PO List Document Status string Yes Initial status (Open, Suggested, etc.)
PO List Order Date string | null No Order date in ISO 8601 format (YYYY-MM-DD)
Supplier Number string Yes Supplier reference code - must exist in Supplier Master
Purchase Order Id integer | null No Set to null for new POs; used for linking during update flows

details Array Items (Line Items)

Field Type Required Description
id integer | null No Set to null for new line items
PO Details Id integer | null No Set to null for new line items
Item Number string Yes Item reference code - must exist in Item Master
Sub Item Number string | null No Sub-item reference code (must exist if provided)
Warehouse Number string Yes Destination warehouse - must exist in Warehouse Master; all lines must use the same warehouse
Ship From Number string Yes Ship-from location - must exist in Ship From Master
PO Details Price number | null No Unit price
PO Details Quantity number Yes Ordered quantity
PO Details Document Status string Yes Line item status
PO Details Tracking string | null No Bill of Lading / tracking reference
PO Details Order Date string | null No Line-level order date (YYYY-MM-DD)
PO Details Ship Date string | null No Expected ship date (YYYY-MM-DD) - must be ≥ Order Date
PO Details ETA Date string | null No Estimated arrival date (YYYY-MM-DD) - must be ≥ Ship Date
PO Details First Promise Date string | null No Supplier's first promise date
PO Details Request Date string | null No Internally requested delivery date
PO Details Actual Ship Date string | null No Actual ship date (populated post-shipment)
PO Details Actual Delivery Date string | null No Actual delivery date (populated post-delivery)
PO Details Unique Id string | null No External unique identifier from source system
PO Details Local string | null No Locale or local reference code

Validation Rules

Rule Error Code
details must not be empty OrderList.NoItems
All line items must use the same Warehouse Number OrderList.MultipleWarehouses
Item Number + Sub Item Number must be unique within the PO OrderDetails.DuplicateRows
Order Date ≤ Ship Date ≤ ETA Date PurchaseOrderDetails.OrderDateAfterShip
Supplier Number must exist in Supplier Master SupplierMaster.NotFound
Item Number must exist in Item Master ItemMaster.NotFound
Warehouse Number must exist in Warehouse Master WarehouseMaster.NotFound
Ship From Number must exist in Ship From Master ShipFromMaster.NotFound

Response

Success - Immediate Execution

HTTP/1.1 200 OK
Content-Type: application/json

{
  "message": "Purchase order created successfully.",
  "notification_type": "Success"
}

Success - Queued (Tables Locked)

When procurement tables are locked during an integration run, the operation is queued:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "message": "Changes will be visible after the integration is done.",
  "notification_type": "Warning"
}

Error

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "Message": "Item ITEM-XYZ not found in Item Master.",
  "Code": "ItemMaster.NotFound"
}

Code Examples

curl

CSRF=$(grep csrf_access_token cookies.txt | awk '{print $NF}')

curl -b cookies.txt -X POST https://acme.knosc.com/api/purchase-order \
  -H "Content-Type: application/json" \
  -H "X-XSRF-TOKEN: $CSRF" \
  -d '{
    "PO List Number": "PO-2024-100",
    "PO List Document Status": "Open",
    "PO List Order Date": "2024-03-15",
    "Supplier Number": "SUP-007",
    "Purchase Order Id": null,
    "details": [
      {
        "id": null,
        "Item Number": "ITEM-A",
        "Sub Item Number": null,
        "Warehouse Number": "WH-01",
        "Ship From Number": "SF-01",
        "PO Details Quantity": 200,
        "PO Details Document Status": "Open",
        "PO Details Order Date": "2024-03-15",
        "PO Details Ship Date": "2024-03-22",
        "PO Details ETA Date": "2024-03-28"
      }
    ]
  }'

Python

csrf_token = session.cookies.get("csrf_access_token")

payload = {
    "PO List Number": "PO-2024-100",
    "PO List Document Status": "Open",
    "PO List Order Date": "2024-03-15",
    "Supplier Number": "SUP-007",
    "Purchase Order Id": None,
    "details": [
        {
            "id": None,
            "PO Details Id": None,
            "Item Number": "ITEM-A",
            "Sub Item Number": None,
            "Warehouse Number": "WH-01",
            "Ship From Number": "SF-01",
            "PO Details Price": 12.50,
            "PO Details Quantity": 200,
            "PO Details Document Status": "Open",
            "PO Details Tracking": None,
            "PO Details Order Date": "2024-03-15",
            "PO Details Ship Date": "2024-03-22",
            "PO Details ETA Date": "2024-03-28",
        }
    ],
}

response = session.post(
    "https://acme.knosc.com/api/purchase-order",
    headers={"X-XSRF-TOKEN": csrf_token},
    json=payload,
)

result = response.json()
if result.get("notification_type") == "Warning":
    print("PO queued - tables are locked during integration.")
else:
    print("PO created:", result["message"])