Purchase orders via API
Create, list, retrieve, and update purchase orders programmatically using the Spend API.
Beta: The Purchase Orders API is in Beta.
The Purchase Orders (PO) API lets you create and manage formal purchase requests to vendors. Each purchase order requires line items with accounting field selections.
Before you begin
- Obtain your access token API by authenticating to Airwallex using your unique Client ID and API key. You can create scoped API keys in Settings > Developer > API keys in the Airwallex web app. Spend resources require Organization-level permissions.
- Set up custom accounting data with external IDs. Line items in purchase orders use
identifier_type: EXTERNAL_IDto reference your Chart of accounts, Tax rates, and custom fields. - Create or identify a vendor to associate with the purchase order.
Prepare line items with accounting field selections
Each purchase order requires a line_items array. Each line item contains accounting_field_selections that map the item to your chart of accounts, tax rates, and custom fields using external IDs.
Only identifier_type: EXTERNAL_ID is supported for accounting field selections. External IDs correspond to the values you configured during custom accounting data setup, and are displayed on your custom accounting data table.
The structure for a line item with accounting field selections:
1{2 "line_items": [3 {4 "description": "Office furniture - standing desks",5 "quantity": 10,6 "unit_price": 450.00,7 "accounting_field_selections": [8 {9 "field_id": "Chart of accounts",10 "field_value_id": "7100-Furniture",11 "identifier_type": "EXTERNAL_ID"12 },13 {14 "field_id": "Tax rates",15 "field_value_id": "GST_10",16 "identifier_type": "EXTERNAL_ID"17 },18 {19 "field_id": "Custom field 1",20 "field_value_id": "engineering",21 "identifier_type": "EXTERNAL_ID"22 }23 ]24 }25 ]26}
Key fields for each accounting field selection:
| Field | Description |
|---|---|
field_id | The external ID of the accounting field (for example, Chart of accounts, Tax rates, or a custom field name). |
field_value_id | The external ID of the specific value within that field (for example, a GL code or tax rate identifier). |
identifier_type | Must be EXTERNAL_ID. |
Create a purchase order
After preparing line items, create the purchase order by calling the Create purchase order API endpoint.
-
Send the create request with the required fields:
Shell1curl -X POST \2 'https://api-demo.airwallex.com/api/v1/spend/purchase_orders/create' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \4 -H 'Content-Type: application/json' \5 -d '{6 "request_id": "unique-request-id-001",7 "external_id": "PO-ERP-001",8 "legal_entity_id": "le_xyz789",9 "vendor_id": "ba46f0ff-8081-4db6-8333-4e011fe9561d",10 "purchase_order_number": "PO-2026-001",11 "billing_currency": "USD",12 "sync_status": "SYNCED",13 "line_items": [14 {15 "description": "Office furniture - standing desks",16 "quantity": 10,17 "unit_price": 450,18 "accounting_field_selections": [19 {20 "field_id": "Chart of accounts",21 "field_value_id": "7100-Furniture",22 "identifier_type": "EXTERNAL_ID"23 }24 ]25 }26 ]27 }' -
The response returns the created purchase order with its unique ID:
JSON1{2 "id": "985461d5-016f-4e1f-a387-5f1380b42d92",3 "external_id": "PO-ERP-001",4 "legal_entity_id": "le_xyz789",5 "vendor_id": "ba46f0ff-8081-4db6-8333-4e011fe9561d",6 "purchase_order_number": "PO-2026-001",7 "billing_currency": "USD",8 "status": "OPEN",9 "sync_status": "SYNCED",10 "line_items": [11 {12 "description": "Office furniture - standing desks",13 "quantity": 10,14 "unit_price": 450.00,15 "accounting_field_selections": [16 {17 "name": "Chart of accounts",18 "type": "GENERAL_LEDGER_ACCOUNT",19 "value": "7100-Furniture",20 "external_id": "7100-Furniture",21 "value_label": "Furniture"22 }23 ]24 }25 ],26 "created_at": "2026-02-01T14:00:00Z"27}
List purchase orders
To retrieve a list of purchase orders, call the List purchase orders API endpoint.
-
Send the request with optional filters:
Shell1curl -G \2 'https://api-demo.airwallex.com/api/v1/spend/purchase_orders' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' -
The response returns a list of purchase orders:
JSON1{2 "items": [3 {4 "id": "985461d5-016f-4e1f-a387-5f1380b42d92",5 "vendor_id": "ba46f0ff-8081-4db6-8333-4e011fe9561d",6 "billing_currency": "USD",7 "status": "OPEN",8 "sync_status": "SYNCED"9 }10 ],11 "page_after": "eyJwYWdlX2JlZm9yZSI6IjIwMjUtMDctMDFUMDA6MDA6MDBaIn0=",12 "page_before": "eyJwYWdlX2JlZm9yZSI6IjIwMjUtMDctMDFUMDA6MDA6MDBaIn0="13}
Key query parameters include:
| Parameter | Description |
|---|---|
status | Filter by purchase order status. Possible values are OPEN, COMPLETED, ARCHIVED, CLOSED. |
sync_status | Filter by sync status (NOT_SYNCED, SYNCED, SYNC_FAILED). |
legal_entity_id | Filter purchase orders by legal entity ID. |
from_created_at | Filter purchase orders created on or after this timestamp (ISO 8601). |
to_created_at | Filter purchase orders created on or before this timestamp (ISO 8601). |
page | A bookmark for use in pagination to retrieve either the next page or the previous page of results. You can fetch the value for this identifier from the response of the previous API call. |
Get purchase order details
To retrieve the full details of a specific purchase order, call the Get purchase order API endpoint.
-
Use the
idfrom the list response:Shell1curl -G \2 'https://api-demo.airwallex.com/api/v1/spend/purchase_orders/{{PO_ID}}' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
Update the sync status of a purchase order
To update the sync status of an existing purchase order, call the Update purchase order sync status API endpoint.
-
Send the update request with the request body:
Shell1curl -X POST \2 'https://api-demo.airwallex.com/api/v1/spend/purchase_orders/{{PO_ID}}/sync' \3 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \4 -H 'Content-Type: application/json' \5 -d '{6 "sync_error_message": "Failed to sync purchase order: this purchase order number already exists.",7 "sync_status": "SYNC_FAILED"8 }' -
The response returns the updated purchase order.
Next steps
Now that you can manage purchase orders via the API, explore these related guides: