Purchase Orders

Sync purchase orders from your ERP into Ottimate for invoice matching

A purchase order (PO) is a document issued by a buyer to a vendor that specifies the items, quantities, and agreed-upon prices for goods or services. POs serve as the authoritative record of what was ordered and at what cost.

Source of truth: Purchase orders originate in your source system (ERP). Ottimate syncs POs from your ERP and stores them for document matching — your ERP remains the authoritative source for purchase order data.

How purchase orders work in Ottimate

When a PO is created in your source system, you sync it to Ottimate using the Purchase Orders API. Once in Ottimate, POs are used to match against invoices to validate that billed amounts align with what was ordered.

Each PO can be configured for one of two matching workflows:

  • Three-way matching (default) — The PO is matched against both a receipt and an invoice. This ensures that what was ordered, received, and billed all agree before payment is released.
  • Two-way matching — The PO is matched directly against an invoice, skipping the receipt step. Set is_2_way: true when creating the PO. This is common for services or other scenarios where delivery verification is not required.

PO status values

Ottimate tracks the lifecycle of each PO with the following statuses:

StatusDescription
pendingPO has been received but not yet processed
openPO is active and available for matching
receivedAll items on the PO have been received
closedPO has been fully matched and closed
flaggedPO requires attention or review
archivedPO is no longer active
deletedPO has been removed

Key fields

FieldDescription
po_numberPO number from your source system. Required — Ottimate does not auto-generate PO numbers.
external_idYour system’s unique identifier. Used for idempotent operations — if a PO with the same external_id already exists, it will be updated instead of duplicated.
erp_vendor_idVendor identifier from your ERP system
erp_vendor_nameVendor display name from your ERP
ottimate_location_idThe Ottimate location this PO belongs to
is_2_waySet to true for two-way matching (no receipt required)
custom_fieldsCustom fields configured for this company’s purchase orders
itemsArray of line items, each with name, quantity, price, and optional sku, uom, and dimensions

Item-level dimensions

It is common for PO line items to carry dimension mappings (e.g., GL account, department, project) from the source ERP. When an invoice is matched to a PO, Ottimate can inherit these dimensions onto the invoice line items — so coding happens automatically based on what was already set on the purchase order.

Dimensions are passed as key-value pairs on each item, keyed by dimension type (e.g., PROJECT, CLASS). Each value is the erp_dimension_id of the dimension as returned by the GET /dimensions endpoint.

Dimensions must exist in Ottimate before they can be referenced on a PO. Dimensions are typically synced from your ERP via an Ottimate-hosted integration, or created directly using the Dimensions API. If a PO request references a dimension that does not exist in Ottimate, the request will return a 400 error.

When creating or updating a PO, providing dimensions on a line item replaces all existing dimensions on that item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged.

API endpoints

EndpointDescription
GET /purchase-ordersList purchase orders with filters for company, location, vendor, status, and date range
GET /purchase-orders/{id}Get a specific purchase order with all line items
POST /purchase-ordersCreate a single purchase order
PATCH /purchase-orders/{id}Update an existing purchase order
POST /purchase-orders/bulk-upsert/Bulk create or update purchase orders

Bulk operations

The bulk upsert endpoint allows you to create or update multiple POs in a single request. This operation is processed asynchronously.

Rate limits:

  • Maximum 100 purchase orders per request
  • Maximum 1,000 total line items across all POs in a single request

The response returns a batch_id that you can use with the Batch progress and Batch results endpoints to track the status of your bulk operation.

Updating purchase orders

When updating a PO via PATCH, note the following restrictions:

  • You cannot change status, po_number, external_id, erp_vendor_id, or ottimate_location_id
  • To update existing line items, include the item id in the items array
  • To add new line items, omit the id field — Ottimate will create them automatically