What this guide covers
The purchase-to-pay (P2P) workflow moves goods and money through four stages:- Purchase order — commit to buying from a vendor
- Goods receipt — receive the goods into inventory
- Vendor bill — record the vendor’s invoice and clear the GRNI accrual
- AP payment — pay the bill and close the liability
Prerequisites
- API key with scopes:
purchasing:write,purchasing:read,accounting:write - An active vendor account (account_type:
vendor) - One or more product IDs to order
- A warehouse location ID
Stage 1: Create the purchase order
POST /v1/orders with document_type: "purchase_order". The order is created in draft status. No GL entry fires at this stage.
po.data.id (the PO UUID). You will reference it in later stages.
Confirm the PO (open it)
Once reviewed, transition toopen status, which makes it eligible for receiving:
Stage 2: Receive goods
POST /v1/orders/{po_id}/receive records the goods arriving at your warehouse.
GL entries that fire at this stage:
| Account | Debit | Credit |
|---|---|---|
| Inventory (Finished Goods) | unit_cost x qty_received | |
| GRNI (Goods Received Not Invoiced) | unit_cost x qty_received |
inventory_updated: true and the GL journal entry ID for the GRNI posting. Inventory on-hand increases immediately.
Partial receipt: you can receive fewer than the ordered quantity. The remaining quantity stays open on the PO. Fire another receive call when the rest arrives.
Stage 3: Enter and post the vendor bill
When the vendor’s invoice arrives, create a vendor bill linked to the PO. Posting the bill clears the GRNI accrual and records the AP liability.Create the draft bill
draft status. No GL entry yet.
Post the bill
| Account | Debit | Credit |
|---|---|---|
| GRNI (Goods Received Not Invoiced) | total bill amount | |
| Accounts Payable | total bill amount |
Stage 4: Pay the vendor bill
POST /v1/ap-payments closes the AP liability and records the outgoing cash.
| Account | Debit | Credit |
|---|---|---|
| Accounts Payable | 612.00 | |
| Bank (Operating Checking) | 612.00 |
paid status.
GL summary: the full P2P transaction trail
| Stage | Event | Debit | Credit |
|---|---|---|---|
| 2 | Receive goods | Inventory FG | GRNI |
| 3 | Post vendor bill | GRNI | Accounts Payable |
| 4 | Pay bill | Accounts Payable | Bank |
Partial payments and multi-bill payments
A single AP payment can apply to multiple bills:open with a reduced balance_due until the remaining balance is paid or written off.
Vendor credits
To apply a vendor credit against a bill payment, includevendor_credit_ids[] in the payment body:
Common errors
| Code | HTTP | Meaning |
|---|---|---|
po_not_found | 404 | PO UUID does not exist for this entity |
po_not_receivable | 422 | PO status is not open or processing |
quantity_exceeds_ordered | 422 | Receipt line quantity exceeds PO line quantity remaining |
bill_already_posted | 409 | Attempted to post a bill that is already in open status |
bill_balance_insufficient | 422 | Payment application amount exceeds bill balance due |
bank_account_not_found | 404 | bank_account_id does not exist for this entity |
insufficient_scope | 403 | API key missing purchasing:write or accounting:write scope |
Idempotency
Every write in this flow acceptsIdempotency-Key. Use a stable key tied to your source record (e.g. po-<source-po-id>, recv-<source-receipt-id>, bill-<vendor-invoice-number>). Keys expire after 24 hours.
Verifying the full chain
After all four stages, run these checks:Next steps
- Journal Entries and Period Close — record adjusting entries and close the accounting period
- Creating Orders — build a sales order on the outbound side
- API Reference: Purchase Orders
- API Reference: Vendor Bills
- API Reference: AP Payments

