Skip to main content
Purchase Order Update API
curl --request PATCH \
  --url https://api.pazy.io/v1.0/procurement/purchase-order/:poId

Authentication

All requests require an API key in the request headers. Headers:
Authorization: Api-Key YOUR_API_KEY
Content-Type: application/json

Request

Content-Type: application/json

Path Parameters

ParameterTypeRequiredDescription
poIdstringYesThe unique slug identifier of the purchase order to update (returned from the PO creation or search API)

Body Parameters

All body fields are optional. Only the fields you provide will be updated.
ParameterTypeRequiredDescription
poNumberstringNoPurchase order number (minimum 1 character)
lineItemsarrayNoList of line items. Replaces all existing line items if provided (minimum 1 item)
poTypestringNoPurchase order type. Valid values: GOODS, SERVICES
matchingTypestringNoMatching type. Valid values: TWO_WAY, THREE_WAY
poDatestringNoPurchase order date in ISO-8601 format (YYYY-MM-DD)
vendorIdstringNoSlug identifier of the vendor to link to the PO
descriptionstringNoShort description for the purchase order (1-255 characters)
currencystringNoISO 4217 currency code (3 characters, e.g., INR)
paymentTermsstringNoFree form outline of the agreed payment terms
deliveryDatestringNoRequested delivery date in ISO-8601 format (YYYY-MM-DD)
termsAndConditionsstringNoTerms and conditions for the purchase order
additionalNotesstringNoAdditional notes for delivery or special requirements
statestringNoTarget state: DRAFTED or ACTIVE. When ACTIVE is requested the API validates required fields (merging body with what is already on the PO). If all required fields are present the PO is activated; otherwise it stays in DRAFTED and the response includes submitWarnings.

Line Items Object

Each item in the lineItems array must contain:
ParameterTypeRequiredDescription
quantitynumberYesQuantity requested for the line item
ratenumberYesUnit rate to be applied to the line item
identifierstringYesFree-text label for the line item (minimum 1 character)
skuCodestringRequired for THREE_WAYItem code of an existing SKU in your inventory. Takes priority over skuName
skuNamestringRequired for THREE_WAYName of an existing SKU in your inventory (used when skuCode is not provided)
SKU matching (THREE_WAY): When the PO uses THREE_WAY matching and lineItems are included in the update, every line item must provide skuCode or skuName, and it must resolve to an existing SKU. If any line item is missing both fields or cannot be matched, the request is rejected with a 400 error and the PO is not updated.

Editable States

A purchase order can only be updated when it is in one of the following states:
StateDescription
DRAFTEDPO is in draft — editable
DECLINEDPO was declined and returned for revision — editable
Attempting to update a PO in any other state (PENDING, APPROVED, CLOSED, ARCHIVED) will return a 400 error.

Code Examples

curl -X PATCH https://api.pazy.io/v1.0/procurement/purchase-order/po_slug_identifier \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Updated office supplies order",
    "deliveryDate": "2024-03-01",
    "paymentTerms": "Net 45 days",
    "lineItems": [
      {
        "identifier": "SKU-001",
        "quantity": 120,
        "rate": 50.00
      }
    ]
  }'

Success Response

HTTP Status: 200 OK Response Fields:
FieldTypeDescription
okbooleanIndicates whether the request was successful
dataobjectContains the update response data
data.poIdstringUnique slug identifier of the updated purchase order
data.statestringPresent when state was requested. ACTIVE if activation succeeded, DRAFTED if it fell back
data.skuMatchWarningsarrayPresent when one or more line items could not be matched to a SKU
data.submitWarningsobjectPresent when state: ACTIVE was requested but required fields were missing

submitWarnings Object

FieldTypeDescription
poarray of stringsPO-level fields that were missing (e.g. "vendorId", "paymentTerms")
lineItemsobjectMap of line item identifier to missing fields (e.g. "quantity", "rate")

Response Example — update only (no state change)

{
  "ok": true,
  "data": {
    "poId": "po_slug_identifier"
  }
}

Response Example — activated (state: "ACTIVE", all fields present)

{
  "ok": true,
  "data": {
    "poId": "po_slug_identifier",
    "state": "ACTIVE"
  }
}

Response Example — fell back to draft (state: "ACTIVE", fields missing)

{
  "ok": true,
  "data": {
    "poId": "po_slug_identifier",
    "state": "DRAFTED",
    "submitWarnings": {
      "po": ["paymentTerms"],
      "lineItems": {}
    }
  }
}

Error Responses

SKU Required (THREE_WAY match)

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "SKU_REQUIRED",
    "message": "skuCode or skuName is required for each line item in a THREE_WAY purchase order. Missing on: \"SKU-001\""
  }
}

SKU Not Found (THREE_WAY match)

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "SKU_NOT_FOUND",
    "message": "SKU with item code \"UNKNOWN-CODE\" not found in your inventory"
  }
}

Purchase Order Not Found

HTTP Status: 404 Not Found
{
  "ok": false,
  "error": {
    "code": "PURCHASE_ORDER_NOT_FOUND",
    "message": "Purchase order not found"
  }
}

Invalid State

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "INVALID_STATE",
    "message": "Purchase order cannot be updated in APPROVED state"
  }
}

Invalid Procurement Type

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "INVALID_PROCUREMENT_TYPE",
    "message": "Invalid procurement type"
  }
}

Invalid Matching Type

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "INVALID_MATCHING_TYPE",
    "message": "Invalid matching type"
  }
}

Invalid Date

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "INVALID_DATE",
    "message": "Invalid date"
  }
}

Invalid Currency

HTTP Status: 400 Bad Request
{
  "ok": false,
  "error": {
    "code": "INVALID_CURRENCY",
    "message": "Invalid currency Only INR is supported at the moment"
  }
}

Vendor Not Found

HTTP Status: 404 Not Found
{
  "ok": false,
  "error": {
    "code": "VENDOR_NOT_FOUND",
    "message": "Vendor not found"
  }
}

Authentication Errors

HTTP Status: 401 Unauthorized
{
  "ok": false,
  "error": {
    "code": "MISSING_CREDENTIALS",
    "message": "Missing Credentials"
  }
}
{
  "ok": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API Key"
  }
}

Permission Errors

HTTP Status: 403 Forbidden
{
  "ok": false,
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Permission check failed - PERMISSION_CHECK_FAILED"
  }
}

Internal Error

HTTP Status: 500 Internal Server Error
{
  "ok": false,
  "error": {
    "code": "PROCUREMENT_CREATION_FAILED",
    "message": "Error creating procurement"
  }
}

Best Practices

  • Only POs in DRAFTED or DECLINED state can be updated. Check the PO state first using the Purchase Order Details API
  • All body fields are optional — send only the fields you want to change
  • If you provide lineItems, the entire list of line items will be replaced; ensure you include all intended line items in the request
  • Use the poId returned from the Purchase Order Creation API or Purchase Order Search API to obtain the identifier
  • Use ISO 8601 date format (YYYY-MM-DD) for all date fields
  • Pass state: "ACTIVE" to activate a draft PO in the same request as your field updates. Validation merges the body with what is already stored, so you only need to send the fields that are changing — already-set fields on the PO count toward the activation check
  • Check submitWarnings in the response when state: "ACTIVE" is sent — it identifies any remaining missing fields that prevented activation