Purchase Orders API

List, create, retrieve, cancel, approve, and reject purchase orders via the API.

What this does

The Purchase Orders API lets you manage the full PO lifecycle programmatically: create POs, retrieve them individually or as a list with status filters, cancel pending POs, and run them through the approval workflow.

When to use it

Use this endpoint for B2B users with PO-driven procurement: a bot can raise a PO, route it to the configured approver, and then approve or reject on receipt of a response. Approval thresholds are configured per entity in the PO settings — POs over the threshold start pending_approval; those below auto-flip to approved on creation.

Authentication and scopes

Requests must include Authorization: Bearer rly_your_key_here. Each endpoint requires one of:

  • po:read — list and retrieve purchase orders
  • po:write — create, cancel, approve, and reject purchase orders

Endpoints

List purchase orders

GET /api/v1/po

Returns a paginated list of POs. Supports ?page=1&limit=50&status=pending_approval query parameters. Status values: draft, pending_approval, approved, rejected, cancelled, fulfilled, fulfilled_with_variance.

Create a purchase order

POST /api/v1/po

{
  "supplierName": "B&Q Trade",
  "description": "Materials for Smith House refit",
  "currency": "GBP",
  "items": [
    {
      "description": "Lumber — 4x2",
      "quantity": 50,
      "unitPrice": 8.50,
      "vatRate": 20
    }
  ],
  "expectedDate": "2026-05-10",
  "notes": "Deliver to site, not office"
}

supplierName and at least one items entry are required. description, currency, expectedDate, and notes are optional. Each line item needs description, quantity, unitPrice, vatRate (percentage as a number, e.g. 20 for 20%).

The PO's status is decided automatically against the entity's approval threshold (configured at /dashboard/settings → Purchase Orders): POs over the threshold start pending_approval; those at or below the threshold start approved.

Response (201 Created): the created PO object including id, po_number, status, and totals.

  • 400 po_not_enabled — purchase orders are not enabled for this entity. Enable them in the settings UI first.

Get a single purchase order

GET /api/v1/po/:id

Returns the PO with its items array.

Cancel a purchase order

PATCH /api/v1/po/:id

{ "action": "cancel" }

Cancels a PO that is in pending_approval or approved status. Returns 404 if the PO is in any other status.

Approve a purchase order

POST /api/v1/po/:id/approve

Approves a PO that is in pending_approval status. The authenticated key's owner is recorded as the approver.

  • 404 not_found — PO does not exist
  • 409 conflict — PO is not in pending_approval status

Reject a purchase order

POST /api/v1/po/:id/reject

{ "reason": "Quote too high — re-tender" }

Rejects a PO that is in pending_approval status. reason is required and is recorded against the PO.

  • 400 validation_errorreason missing
  • 404 not_found — PO does not exist
  • 409 conflict — PO is not in pending_approval status

Test mode

Keys flagged as test mode validate request bodies but skip database writes. The response includes "test": true and a stubbed id / po_number so you can exercise the integration safely.