A purchase order represents a commercial transaction with a supplier. Every purchase order is scoped to exactly one supplier and moves through a well-defined status lifecycle.
Fields
supplierId(required) — the supplier this order is placed with.orderNumber(required) — your internal / ERP reference.status— one ofDRAFT,CONFIRMED,IN_TRANSIT,DELIVERED,CANCELLED(defaults toDRAFT).orderDate(required) — when the order was placed.expectedDelivery,actualDelivery— estimated and confirmed delivery timestamps.totalAmount,currency— commercial total, amount as a precise decimal string.notes— free-form commentary.
See the full purchase schema in the API reference.
Status lifecycle
DRAFT ──▶ CONFIRMED ──▶ IN_TRANSIT ──▶ DELIVERED│ │ │└───────────┴──────────────┴──▶ CANCELLED
| Status | Meaning |
|---|---|
DRAFT | Created but not yet sent / confirmed with the supplier |
CONFIRMED | Supplier has accepted the order |
IN_TRANSIT | Goods are on their way |
DELIVERED | Goods received — stock can be updated |
CANCELLED | Order cancelled — no further transitions allowed |
Transitioning status
Do not update status with PATCH — use the dedicated transition endpoint instead, which enforces valid transitions and writes an audit log entry:
POST /api/v1/purchases/{id}/transition
{"toStatus": "DELIVERED","reason": "Received at warehouse","actualDelivery": "2026-04-20T14:30:00.000Z"}
toStatusis required and must be a valid successor of the current status.reasonis optional but recommended for traceability.- When transitioning to
DELIVERED, passactualDeliveryto record when the goods were actually received.
Audit log
Every transition is stored in an immutable log you can retrieve at any time:
GET /api/v1/purchases/{id}/logs
Each log entry (PurchaseStatusChangeLogDto) contains fromStatus, toStatus, reason, changedByUserId and changedAt.
Deletion rules
Purchase orders can be deleted, but the API enforces business rules server-side. If you attempt to delete an order in a non-deletable state (for example, one already DELIVERED), the request returns an error. Use CANCELLED as the terminal state for orders that will not be fulfilled instead of deleting them.
Patch vs. transition
| Operation | Use PATCH /purchases/{id} | Use POST /purchases/{id}/transition |
|---|---|---|
Fix a typo in notes | ✅ | ❌ |
Update expectedDelivery | ✅ | ❌ |
Change totalAmount | ✅ | ❌ |
Change status | ❌ | ✅ |