Overview
The Logiwa IO Open API lets your own systems create, update and receive purchase orders (POs) without the web screens. This guide lists the PO endpoints, the fields a PO needs, the rules each call applies and the errors it returns, so your integration can send clean data and handle failures.
When to use it
You are building an integration that sends POs to Logiwa IO.
You receive POs from another system, such as a dock or scanning app.
An API call returned an error and you need to know why.
Prerequisites
An Open API token for your Logiwa IO account.
The client, warehouse, vendor, PO type and products the PO uses already exist in Logiwa IO.
Endpoints
Endpoint | What it does | Notes |
| Creates a PO | Returns |
| Updates a PO | The line list you send replaces the PO’s lines |
| Receives a quantity of one SKU on a PO | One SKU per call |
| Reads one PO by identifier or by code | — |
| Lists POs, page by page | — |
| Lists vendors | Filters: ClientIdentifier, Identifier, DisplayName |
| Attaches a document to a PO | — |
| The PO Receiving Report | Filters: Code, Sku, ClientIdentifier, ReceiptDate, WarehouseIdentifier |
| Creates, lists and updates PO types | — |
Create a PO
Send the PO header and its lines in one call. A PO needs these fields:
Field | What it’s for | Example |
| The PO number | PO-1001 |
| The client and warehouse the PO belongs to | — |
| The vendor’s name | Global Supply |
| The PO type, which decides the receiving rules | Purchase Order |
| The PO date. Without it the call fails with “PurchaseOrderDate must be date format” | 2026-11-13T00:00:00Z |
| The lines: | SKU-100, Unit, 5 |
Create and update rules
Rule | What happens | Example |
Unknown SKU |
| This product is not found: 'INVALID-SKU-123' |
Identical lines | Lines with the same SKU, pack type, lot, expiry date and production date become one line with the quantities added up. A different price doesn’t keep them apart | Two lines of SKU-100 (2 and 3, different prices) become one line of 5 |
Lot, expiry or production date on a product that doesn’t track it |
|
|
Date before 1 January 1970 |
|
|
PO without lines |
|
|
Kit-to-Order product on a line |
|
|
Update with a line list | The lines you send replace the PO’s lines. Send every line you want to keep | A PO with one line of 5 is updated with one line of 4. The PO now has one line of 4 |
Size | Up to 2,000 lines per PO | — |
Receive a PO
Each receive call receives a quantity of one SKU into a location (warehouseLocationCode) and, optionally, into an LP (license plate). The first successful receipt moves the PO to Started.
LP rules
Situation | Result | Message |
|
| “This LP does not exist” |
|
| “This LP does not exist” |
New |
| “LP {number} Creation failed. Valid LP Type required” |
|
| “License plate type cannot be found” |
An existing LP number sent with a different LP type |
| “License Plate Type Mismatch: The provided LP Number … does not match the existing …” |
|
| “Entered parent LP does not exist.” |
New |
| — |
💡 The LP type code isn’t case-sensitive: selp1 finds the LP type SeLP1. Note the spelling of the field: licencePlateType.
⚠️ When a receive call fails, nothing is received.
Receiving verification
If the client’s Receiving Verification is set to Prevent, a receive call for a product without the required dimensions, weight or volume returns 400. See Handling Missing Physical Attributes During Receiving.
Status change webhook
The wms/purchaseorder/statuschange webhook is sent when a PO changes status. All its dates, such as PurchaseOrderCreatedDateTime and ActualReceivingDate, are in UTC with three digits of milliseconds, for example 2026-03-25T10:24:08.123Z. Empty dates are sent as null.
Common questions
I sent two lines for the same SKU, but the PO has one line. Why? Identical lines are merged. To keep them apart, they must differ in pack type, lot, expiry date or production date.
My update removed lines from the PO. Why? The update replaces the PO’s lines with the list you send. Send every line you want to keep.
My receive call returns “This LP does not exist”. What should I do? Send an existing LP, or set createLPIsNotExists to true and send an LP type so that the LP is created.
