API reference

Purchase orders

Orders a buyer places with a supplier: their lines, amounts, status and approval.

More about this resource

A purchase order commits a buyer to one or more line items with a supplier. Creating one starts an approval chain; once approved it can be flipped into an invoice. Every amount is in the region currency - a workspace's currency is its region's, set on the company profile - and Pleaxy doesn't convert currencies.

List purchase orders

Lists the purchase orders in the workspace, optionally within a date range.

GET/v1/workspaces/{regionId}/purchase-orders

Parameters

  • fromstring

    ISO 8601 date/timestamp - only items created on or after this are returned.

  • tostring

    ISO 8601 date/timestamp - only items created on or before this are returned.

Returns

200 OK with the object shown in the response.

More details

Lists every purchase order in the workspace, in no particular order. Optionally scoped to a createdAt range via from/to - pass a calendar month's bounds to get a per-month view. A Supplier caller gets a reduced view of each PO (see GetPurchaseOrder) - buyer-internal bookkeeping and the full approval workflow are withheld.

Errors

  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
GET /v1/workspaces/{regionId}/purchase-orders
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
[
   {
      "id": "string",
      "buyerOrgId": "string",
      "supplierOrgId": "string",
      "supplier": "string",
      "amount": number,
      "currency": "string",
      "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
      "invoiceId": "string",
      "provider": "aws" | "gcp" | "azure" | "oci",
      "payerAccounts": [
         { "id": "string", "label": "string", "detail": "string" }
      ],
      "billToParty": {
         "source": "company_profile" | "custom",
         "companyName": "string",
         "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
         "addressText": "string",
         "taxId": "string"
      },
      "costCenter": "string",
      "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
      "budgetOwner": "string",
      "buyerName": "string",
      "supplierSite": "string",
      "notes": "string",
      "requestId": "string",
      "lineItems": [
         {
         "lineNo": number,
         "scopeType": "sku" | "service" | "account" | "custom",
         "scopeId": "string" | null,
         "name": "string",
         "ruleType": "quantity" | "amount",
         "unit": "string",
         "unitPrice": number,
         "qty": number,
         "nteAmount": number,
         "lineType": "goods" | "service",
         "currency": "string",
         "paymentTerms": "string",
         "validFrom": "string",
         "validUntil": "string",
         "consumed": number,
         "customerLineNo": "string",
         "supplierSku": "string",
         "priceSource": "contract" | "list" | "manual"
       }
      ],
      "approval": {
         "requester": "string",
         "requesterEmployeeKey": "string",
         "groups": [
           {
             "id": "string",
             "mode": "sequential" | "parallel",
             "label": "string",
             "status": "pending" | "approved" | "rejected",
             "stages": [
               { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
             ]
           }
         ],
         "groupIndex": number,
         "status": "pending" | "approved" | "rejected",
         "history": [
           { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
         ],
         "autonomy": boolean,
         "selfApproved": boolean
       },
      "supplierEmail": { "to": "string", "at": "string" },
      "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
      "createdAt": "string"
   }
]

Get purchase order

Retrieves one purchase order.

GET/v1/workspaces/{regionId}/purchase-orders/{poId}

Parameters

  • poIdstringRequired

    The purchase order identifier.

  • buyerstring

    Supplier callers only, and only needed after a 409 *_ID_AMBIGUOUS: the buyer's Workspace ID (ending in .buyer) or region id, from the 409's buyers list. Only that buyer's document is considered; none there is a 404. A .supplier Workspace ID is 400 BUYER_QUALIFIER_INVALID ("The buyer parameter must be one buyer's Workspace ID (ending in .buyer), from the buyers list in the 409 response."). Ignored for a Buyer caller.

Returns

200 OK with the object shown in the response.

More details

Fetches a single purchase order by id. For a Buyer caller, regionId is the PO's own workspace. For a Supplier caller, regionId is the supplier's own workspace and the PO is looked up among the org's incoming purchase orders regardless of which buyer workspace issued it.

Response fields

  • priorInvoicedobject

    Only on a PO created by a list import that carried an amount the buyer's previous system had already invoiced. amount (in the PO's currency) counts toward the PO's invoiced total, so its remaining balance is right. basis says whether the file gave the amount invoiced or the remaining balance it was worked out from, and sourceSystem which export the list was read as. importId, fileName and importedBy are returned to the buyer only.

  • billToPartyobject

    Who the supplier invoices: companyName, the address as separate fields (address) or, for a one-line address, addressText, and taxId. A copy, not a link: source "company_profile" is the buyer's company profile billing details as they were when the order was created, so the order keeps the address it was issued with when the profile changes later; "custom" was entered on the order. An invoice against the order takes its buyer details from here. Absent on orders created before it existed, which have the free-text billTo instead.

  • supplierEmailobject

    When the issued order was emailed to the supplier as a PDF, and to which address. Set once; absent when it wasn't emailed (no contact email, a cloud provider, or the order isn't issued yet).

  • costCenterChangesArray

    Buyer only. Every change to costCenter made after the order was finished, oldest first: from (absent when it had none), to, reason, who (by, byName) and when. See ChangeFinishedPurchaseOrderCostCenter.

Errors

  • 404 Not Found - No PO with this id exists in the caller's workspace.
  • 409 Conflict - Supplier callers only. Code PO_ID_AMBIGUOUS: more than one of your buyers has issued a purchase order with this id (ids are unique only within a buyer), so Pleaxy won't guess which one you mean. Nothing is read or changed. The body's buyers lists each buyer's Workspace ID and name: repeat the call with ?buyer=<that Workspace ID>.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
GET /v1/workspaces/{regionId}/purchase-orders/{poId}
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Get purchase order PDF

Downloads a purchase order as a PDF.

GET/v1/workspaces/{regionId}/purchase-orders/{poId}/pdf

Parameters

  • poIdstringRequired

    The purchase order identifier.

  • buyerstring

    Supplier callers only, and only needed after a 409 *_ID_AMBIGUOUS: the buyer's Workspace ID (ending in .buyer) or region id, from the 409's buyers list. Only that buyer's document is considered; none there is a 404. A .supplier Workspace ID is 400 BUYER_QUALIFIER_INVALID ("The buyer parameter must be one buyer's Workspace ID (ending in .buyer), from the buyers list in the 409 response."). Ignored for a Buyer caller.

Returns

200 OK with the object shown in the response.

More details

The purchase order as a PDF, to download, print or forward: your logo, the bill-to (billToParty, with its address and tax id), the supplier, order date, currency, payment terms, the supplier's quote number, the lines and the total, and how to invoice it. It is the supplier's copy whoever asks - no cost center, budget owner, notes or approvals - and a draft, pending, rejected or canceled order says plainly that it isn't one to fulfil. The same PDF is attached to the email the supplier gets when the order is issued. Send Accept: application/pdf, or the body comes back base64-encoded.

Errors

  • 404 Not Found - No PO with this id exists in the caller's workspace.
  • 409 Conflict - Supplier callers only. Code PO_ID_AMBIGUOUS: more than one of your buyers has issued a purchase order with this id (ids are unique only within a buyer), so Pleaxy won't guess which one you mean. Nothing is read or changed. The body's buyers lists each buyer's Workspace ID and name: repeat the call with ?buyer=<that Workspace ID>.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
GET /v1/workspaces/{regionId}/purchase-orders/{poId}/pdf
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/pdf" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
application/pdf

Create purchase order

Creates a purchase order, or saves it as a draft.

POST/v1/workspaces/{regionId}/purchase-orders

Body

  • poNumberstring

    Your own PO number to use as this PO's id instead of a generated one, e.g. PO-2026-0042. Letters, numbers, '.', '_' and '-', up to 40 characters, unique within the region.

  • supplierstringRequired

    Supplier / counterparty display name.

  • supplierRegionIdstring

    regionId of the onboarded supplier org this PO is issued to, if known. You must have an approved supplier connection to it; any other region is refused. Links the PO to that org's real supplier workspace instead of just a free-text name.

  • currencystring

    ISO 4217: the currency the order is priced in. To a supplier on Pleaxy (supplierRegionId), one its region prices in, its main currency by default (400 PO_CURRENCY_NOT_OFFERED otherwise). To a cloud provider or a supplier not on Pleaxy, any code; by default the "Bills in" currency you set for that supplier (SetSupplierCurrencies), else your workspace's. Every line is in it. An order in another currency than your workspace's goes through every approval step and is never auto-approved, because approval limits are in your workspace's currency.

  • supplierContactEmailstring

    Only for a supplier not on Pleaxy (no supplierRegionId or provider): their contact email. When the PO is sent, now or when a draft is submitted, Pleaxy invites them, or links the supplier this workspace already has.

  • provider"aws" | "gcp" | "azure" | "oci"

    Cloud provider this PO covers, if any.

  • payerAccountsArray<{ id, label, detail }>

    Only with provider: this region's cloud connections of that provider the PO applies to, by id. A connection still being set up is refused. The PO stores each connection's own label and detail; the ones you send are ignored but must be strings.

  • billToParty{ companyName?, address, taxId? }

    Who the supplier invoices, when it isn't your company profile's billing details. companyName (up to 200 characters) defaults to your company name; address takes the same fields and per-country rules as UpdateOrgProfile's billingAddressParts; taxId is up to 64 characters. Left out, the order copies your company profile's name, billing address and tax id as they are now.

  • billTostring

    Deprecated: use billToParty. A one-line bill-to address for your company, up to 500 characters, kept as typed. Ignored when billToParty is sent.

  • costCenterstring

    Internal cost center code.

  • budgetOwnerstring

    Name of the budget owner.

  • buyerNamestring

    Buyer contact name; also used as the approval chain's requester if set.

  • supplierSitestring

    Supplier site or location identifier.

  • notesstring

    Free-text notes.

  • contractIdstring

    Your active contract with this supplier that the order falls under. Lines without paymentTerms take its default payment terms, and invoices against the order are checked against it.

  • draftboolean

    Save as a draft instead of submitting for approval. Submit it later with SubmitPurchaseOrderDraft.

  • lineItemsArray<LineItem>Required

    At least one line item. Each item: scopeType ("sku" | "service" | "account" | "custom"), scopeId, name, ruleType ("quantity" | "amount"), unit, unitPrice, qty, nteAmount, currency (optional), paymentTerms (optional, up to 40 characters: left out, the line takes the default payment terms of the contract it was priced from or the order names in contractId, else the catalog item's, else "Net 30"), validFrom, validUntil, customerLineNo (optional: your own number for the line, up to 40 characters, shown alongside the server's lineNo), lineType (optional: "goods", shipped and received on a goods receipt, or "service", work such as support or training, confirmed on a service entry sheet and never shipped; left out, the line takes its catalog item's type, else it is a service when its unit is a time unit such as hr, day or month, and goods otherwise). Every line is in the region currency, which the server writes - omit currency, or send the region currency (any case). Pleaxy doesn't convert currencies, so any other currency is refused.

  • lineItems[].ai{ invoicer, vendor, model, meter, region? }

    An AI line (AI spend controls): who bills it, the model's vendor, the model id as billed, the meter (input_tokens, output_tokens, cached_input_tokens, batch_input_tokens, gpu_hours, ..., or prepaid_credit for a prepaid credit purchase) and the region where it's priced by region. A quantity line in the meter's unit (millions of tokens, hours). An invoice's AI lines are matched to these by scope, never by description. SuggestAiPoLines prefills them.

Returns

201 Created with the object shown in the response.

More details

Creates a purchase order from one or more line items, or saves it as a draft. The total amount is the sum of each line's amount (qty × unitPrice for a quantity-rule line, or nteAmount for an amount-rule line). Unless it is a draft, its approval chain is built immediately from the region's purchase order approval flow, autonomy settings, automation rules and spend limits. If it auto-approves, the PO is created directly in awaiting_fulfillment status instead of pending_approval. Once a PO is issued (awaiting_fulfillment, now or on its final approval), the supplier is notified and, unless it is a cloud provider, emailed the order as a PDF (see GetPurchaseOrderPdf) - to supplierContactEmail, else the contact on your supplier record - with the requester as Reply-To. Sent once per order and recorded as supplierEmail; a failed email never fails the order.

Response fields

  • idstring

    PO identifier, e.g. "PO-AB12CD34".

  • statusstring

    "pending_approval" or "awaiting_fulfillment" if the amount auto-approved.

  • amountnumber

    Sum of all line item amounts.

  • currencystring

    ISO 4217 code the PO and every line are in - the region currency, set by the server.

  • approvalApprovalChain

    The approval chain built for this PO.

  • lineItemsArray<LineItem>

    Each line item as stored, plus lineNo and consumed (starts at 0).

Errors

  • 400 Bad Request - Validation failed (including a billToParty address missing a part its country requires), a line item's currency isn't the region currency ("Line items must be in this region's currency (EUR). Pleaxy doesn't convert currencies."), or the region's plan has reached its rolling-30-day purchase order limit (Free plan: 10 per rolling 30 days).
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/reg_01k5x8p9j3q7vn2mhb4tzc6rde.buyer/purchase-orders" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "supplier": "Amazon Web Services",
    "provider": "aws",
    "lineItems": [
      {
        "scopeType": "sku",
        "scopeId": "AWS-EC2-M5LG",
        "name": "EC2 m5.large",
        "ruleType": "quantity",
        "unit": "hr",
        "unitPrice": 0.096,
        "qty": 5000,
        "nteAmount": 0,
        "paymentTerms": "Net 30",
        "validFrom": "2026-01-01",
        "validUntil": "2026-12-31"
      }
    ]
  }'
Response · 201 Created
{
  "id": "PO-AB12CD34",
  "buyerOrgId": "org_buyer_us-east-1",
  "supplier": "Amazon Web Services",
  "amount": 480,
  "currency": "USD",
  "status": "pending_approval",
  "provider": "aws",
  "lineItems": [
    {
      "lineNo": 1,
      "scopeType": "sku",
      "scopeId": "AWS-EC2-M5LG",
      "name": "EC2 m5.large",
      "ruleType": "quantity",
      "unit": "hr",
      "unitPrice": 0.096,
      "qty": 5000,
      "nteAmount": 0,
      "currency": "USD",
      "paymentTerms": "Net 30",
      "validFrom": "2026-01-01",
      "validUntil": "2026-12-31",
      "consumed": 0
    }
  ],
  "approval": {
    "requester": "Amazon Web Services",
    "groups": [
      {
        "id": "g1",
        "mode": "sequential",
        "status": "pending",
        "stages": [
          { "id": "cost-owner", "label": "Cost owner", "approverEmployeeKey": "us-east-1a2b3c4d", "approverName": "Jamie Rivera", "status": "pending" }
        ]
      },
      {
        "id": "g2",
        "mode": "sequential",
        "status": "pending",
        "stages": [
          { "id": "finance", "label": "Finance", "approverEmployeeKey": "us-east-1e5f6g7h", "approverName": "Priya Nair", "status": "pending" }
        ]
      }
    ],
    "groupIndex": 0,
    "status": "pending",
    "history": []
  },
  "createdAt": "2026-01-15T18:04:22.000Z"
}

Update purchase order

Updates a purchase order's details or line items.

PATCH/v1/workspaces/{regionId}/purchase-orders/{poId}

Parameters

  • poIdstringRequired

    The purchase order identifier.

Body

  • lineItemsArray<LineItem>

    Replaces every line item, in the same shape as CreatePurchaseOrder. At least one.

  • billToParty{ companyName?, address, taxId? } | null

    Who the supplier invoices, as in CreatePurchaseOrder. null copies your company profile's billing details as they are now. Bookkeeping: never sends the PO back through approval.

  • billTostring

    Deprecated: use billToParty. A one-line bill-to address, up to 500 characters; an empty string copies the company profile's. Ignored when billToParty is sent.

  • costCenterstring

    Internal cost center code.

  • budgetOwnerstring

    Name of the budget owner.

  • buyerNamestring

    Buyer contact name.

  • notesstring

    Free-text notes.

Returns

200 OK with the object shown in the response.

More details

Updates a purchase order's bookkeeping fields, or replaces its line items. Not allowed once it is closed, canceled or paid. Sending lineItems replaces the whole set, recalculates the amount and rebuilds the approval chain from scratch, discarding any sign-offs already collected: a draft stays a draft, otherwise the PO becomes awaiting_fulfillment if the new chain auto-approves, or pending_approval if it needs a person. So growing an approved PO's total can send it back through approval. Spend limits are checked for both the PO's requester and the person editing. To rebook a closed, canceled or paid PO to another cost center, use ChangeFinishedPurchaseOrderCostCenter.

Errors

  • 400 Bad Request - Validation failed; the PO is closed, canceled or paid ("PO '{poId}' can't be edited once it's {status}"); or a line's currency isn't the region currency.
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
PATCH /v1/workspaces/{regionId}/purchase-orders/{poId}
Request
curl -X PATCH "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Submit purchase order draft

Submits a draft purchase order for approval.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/submit

Parameters

  • poIdstringRequired

    The purchase order identifier.

Returns

201 Created with the object shown in the response.

More details

Submits a draft for approval. The approval chain is built now, from the current approval flow, autonomy settings and spend limits, not the ones in force when the draft was saved, and the lines take the region's current currency. Spend limits are checked for both the draft's requester and the person submitting. A supplier not on Pleaxy with a supplierContactEmail is invited now. Takes no body.

Errors

  • 400 Bad Request - The PO isn't a draft ("PO '{poId}' isn't a draft"), or it is over a spend limit that names the person submitting as its approver, which would leave nobody able to sign it off ("Not submitted. This draft is over a spend limit that names you as its approver…").
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/submit
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/submit" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Cancel purchase order

Cancels a purchase order that hasn't been fulfilled.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/cancel

Parameters

  • poIdstringRequired

    The purchase order identifier.

Body

  • reasonstring

    Up to 500 characters. The supplier sees it exactly as written.

Returns

201 Created with the object shown in the response.

More details

Cancels a purchase order that is a draft, pending approval, awaiting fulfillment or expired. This is the buyer stopping the order, not an approver rejecting it. The supplier is told, with your reason if you give one.

Errors

  • 400 Bad Request - The PO is in a status that can't be canceled ("PO '{poId}' can't be canceled once it's {status}"), or reason is over 500 characters.
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/cancel
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/cancel" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "reason": "string"
}
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Close purchase order

Closes a purchase order that has nothing left to invoice.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/close

Parameters

  • poIdstringRequired

    The purchase order identifier.

Returns

201 Created with the object shown in the response.

More details

Closes out a purchase order that is awaiting fulfillment, invoiced, paid or expired, for example one that is fully used with nothing left to invoice. A closed PO can't be edited. Takes no body.

Errors

  • 400 Bad Request - The PO is in a status that can't be closed ("PO '{poId}' can't be closed while it's {status}").
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/close
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/close" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Change finished purchase order cost center

Moves a finished purchase order to another cost center.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/cost-center

Parameters

  • poIdstringRequired

    The purchase order identifier.

Body

  • costCenterstringRequired

    The cost center to book the order to, up to 100 characters. Matched to the workspace's list ignoring case, and stored as the list writes it.

  • reasonstringRequired

    Why it moves, up to 500 characters. Kept on the order.

Returns

201 Created with the object shown in the response.

More details

Rebooks a closed, canceled or paid purchase order to another cost center, with a reason - for example after a reorganisation, or a wrong pick found at month end. Only costCenter changes: the lines, amount and approvals stay as they were approved, and nothing goes back through approval. The change is kept on the order in costCenterChanges, with who made it and when. When the workspace keeps a list of cost centers, the new one must be an active one from it. An open PO changes its cost center with UpdatePurchaseOrder instead.

A workspace administrator only: a signed-in administrator, or an API key minted with the administrator role.

Response fields

  • costCenterChangesArray

    Every change made this way, oldest first: { from?, to, reason, by, byName, at }.

Errors

  • 400 Bad Request - No reason ("Say why the cost center is changing."); the PO is still open ("PO '{poId}' is still open. Change its cost center by editing the order."); the cost center isn't an active one in the workspace's list ("'{costCenter}' isn't an active cost center in this workspace. Pick one from the cost centers list."); it's the one the PO already has; or a field fails validation.
  • 403 Forbidden - The caller isn't an administrator of this buyer workspace ("Only an administrator of this workspace can add or change cost centers.").
  • 404 Not Found - No PO with this id exists in the workspace.
  • 409 Conflict - The PO changed while this was being saved ("PO '{poId}' changed while you were editing it. Refresh and try again.").
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/cost-center
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/cost-center" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "costCenter": "string",
   "reason": "string"
}
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Approve purchase order

Approves a purchase order's current approval step.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/approve

Parameters

  • poIdstringRequired

    The purchase order identifier.

Returns

201 Created with the object shown in the response.

More details

Advances the PO's approval chain by one stage. Only the employee the current step names may call this - no role, permission or administrator rights substitute for being named, and an API key can never be named. Once the final stage approves, the PO's status becomes awaiting_fulfillment, a po_approved notification is sent to the supplier, and the order is emailed to it as a PDF (see CreatePurchaseOrder). It takes no body and acts as the authenticated caller (an API key acts as apikey:<keyId>).

Signed-in session only. Any other caller, including an API key, gets 403 HUMAN_APPROVAL_REQUIRED before anything is read.

Errors

  • 400 Bad Request - The PO's approval chain has no pending stage (already approved or rejected).
  • 403 Forbidden - Code HUMAN_APPROVAL_REQUIRED. The caller is an API key. Approval steps name a specific employee, and a key can never be one, so a key can neither approve nor reject a step. Ask the employee the step names to act on it in Pleaxy.
  • 403 Forbidden - Code APPROVER_NOT_ASSIGNED. The current step has no approver assigned, so nobody can act on it. An administrator must assign one with ReassignPurchaseOrderApprovalStage / ReassignInvoiceApprovalStage first.
  • 403 Forbidden - The caller is not the employee the current step names. Only that employee may approve or reject it - no role or permission substitutes for being named.
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/approve
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/approve" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Reject purchase order

Rejects a purchase order at its current approval step.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/reject

Parameters

  • poIdstringRequired

    The purchase order identifier.

Returns

201 Created with the object shown in the response.

More details

Rejects the PO at its current approval stage. Only the employee the current step names may call this - rejecting is bound by the same rule as approving. Status becomes rejected and a po_rejected notification is sent to the supplier. Terminal - a rejected PO cannot be resubmitted. It takes no body and acts as the authenticated caller (an API key acts as apikey:<keyId>).

Errors

  • 400 Bad Request - The PO's approval chain has no pending stage.
  • 403 Forbidden - Code HUMAN_APPROVAL_REQUIRED. The caller is an API key. Approval steps name a specific employee, and a key can never be one, so a key can neither approve nor reject a step. Ask the employee the step names to act on it in Pleaxy.
  • 403 Forbidden - Code APPROVER_NOT_ASSIGNED. The current step has no approver assigned, so nobody can act on it. An administrator must assign one with ReassignPurchaseOrderApprovalStage / ReassignInvoiceApprovalStage first.
  • 403 Forbidden - The caller is not the employee the current step names. Only that employee may approve or reject it - no role or permission substitutes for being named.
  • 404 Not Found - No PO with this id exists in the workspace.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/reject
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/reject" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

Reassign purchase order approval stage

Assigns a pending approval step to another person.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/approval/reassign

Parameters

  • poIdstringRequired

    The purchase order identifier.

Body

  • stageIdstringRequired

    Id of the pending step to reassign. It may sit in any group of the chain, not only the current one.

  • approverEmployeeKeystringRequired

    Employee key (Cognito sub) of the new approver. Must be a buyer member of this workspace, and not the acting administrator.

  • reasonstring

    Why the step was reassigned, up to 280 characters. Shown in the approval history.

Returns

201 Created with the object shown in the response.

More details

Re-points one pending step of this order's approval chain at a different named employee. Administrator only (approvalSettings:edit), and signed-in sessions only. Because a step is actionable solely by the employee it names, this is the only way to move a step whose approver has left or was never assigned - there is no fallback actor. It changes this document's chain only: the org's configured chain in Settings is untouched, and the change is recorded in the approval history as a reassigned entry.

Errors

  • 400 Bad Request - The chain is already approved or rejected; the step has already been approved or rejected; the new approver isn't an employee of this workspace; the new approver raised the order / entered the invoice, is separation-of-duties excluded, already cleared the spend limit with their own authority, or already holds another seat on the same step; or the step is the spend-limit review, whose approver is a frozen audit fact (change it in Settings › Spend limits).
  • 403 Forbidden - The caller lacks approvalSettings:edit (administrator), or named themselves as the new approver - assigning a live step to yourself makes one person the whole chain with no trace of policy. Code HUMAN_APPROVAL_REQUIRED when the caller is an API key: only a signed-in administrator can reassign an approval step.
  • 404 Not Found - No document with this id exists in the workspace, or the chain has no step with this stageId.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/approval/reassign
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/approval/reassign" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "stageId": "string",
   "approverEmployeeKey": "string",
   "reason": "string"
}
Response · 201 Created
{
   "id": "string",
   "buyerOrgId": "string",
   "supplierOrgId": "string",
   "supplier": "string",
   "amount": number,
   "currency": "string",
   "status": "draft" | "pending_approval" | "rejected" | "awaiting_fulfillment" | "invoiced" | "paid" | "canceled" | "closed" | "expired",
   "invoiceId": "string",
   "provider": "aws" | "gcp" | "azure" | "oci",
   "payerAccounts": [
      { "id": "string", "label": "string", "detail": "string" }
   ],
   "billToParty": {
      "source": "company_profile" | "custom",
      "companyName": "string",
      "address": { "line1": "string", "line2": "string", "city": "string", "region": "string", "postalCode": "string", "country": "string" },
      "addressText": "string",
      "taxId": "string"
   },
   "costCenter": "string",
   "costCenterChanges": [ { "from": "string", "to": "string", "reason": "string", "by": "string", "byName": "string", "at": "string" } ],
   "budgetOwner": "string",
   "buyerName": "string",
   "supplierSite": "string",
   "notes": "string",
   "requestId": "string",
   "lineItems": [
      {
      "lineNo": number,
      "scopeType": "sku" | "service" | "account" | "custom",
      "scopeId": "string" | null,
      "name": "string",
      "ruleType": "quantity" | "amount",
      "unit": "string",
      "unitPrice": number,
      "qty": number,
      "nteAmount": number,
      "lineType": "goods" | "service",
      "currency": "string",
      "paymentTerms": "string",
      "validFrom": "string",
      "validUntil": "string",
      "consumed": number,
      "customerLineNo": "string",
      "supplierSku": "string",
      "priceSource": "contract" | "list" | "manual"
    }
   ],
   "approval": {
      "requester": "string",
      "requesterEmployeeKey": "string",
      "groups": [
        {
          "id": "string",
          "mode": "sequential" | "parallel",
          "label": "string",
          "status": "pending" | "approved" | "rejected",
          "stages": [
            { "id": "string", "label": "string", "approverEmployeeKey": "string", "approverName": "string", "status": "pending" | "approved" | "rejected" }
          ]
        }
      ],
      "groupIndex": number,
      "status": "pending" | "approved" | "rejected",
      "history": [
        { "stage": "string", "by": "string", "at": "string", "action": "approved" | "rejected" | "limit_exceeded" | "reassigned" | "skipped" }
      ],
      "autonomy": boolean,
      "selfApproved": boolean
    },
   "supplierEmail": { "to": "string", "at": "string" },
   "priorInvoiced": { "amount": number, "currency": "string", "basis": "invoiced" | "remaining", "sourceSystem": "sap_ariba" | "coupa" | "oracle", "importId": "string", "fileName": "string", "importedAt": "string", "importedBy": "string" },
   "createdAt": "string"
}

List purchase order comments

Lists the comments on a purchase order.

GET/v1/workspaces/{regionId}/purchase-orders/{poId}/comments

Parameters

  • poIdstringRequired

    The purchase order identifier.

  • buyerstring

    Supplier callers only, and only needed after a 409 *_ID_AMBIGUOUS: the buyer's Workspace ID (ending in .buyer) or region id, from the 409's buyers list. Only that buyer's document is considered; none there is a 404. A .supplier Workspace ID is 400 BUYER_QUALIFIER_INVALID ("The buyer parameter must be one buyer's Workspace ID (ending in .buyer), from the buyers list in the 409 response."). Ignored for a Buyer caller.

Returns

200 OK with the object shown in the response.

More details

The comments on a purchase order, oldest first: your own side's internal ones and every shared one. A comment its author deleted stays in the thread with an empty body, so it still shows that something was said and when. Same lookup as GetPurchaseOrder, so a supplier reaches the POs issued to it.

Response fields

  • visibilitystring

    internal: the author's own side only. shared: both the buyer and the supplier read it.

  • authorKey, mentionsstring, Array

    Only on your own side's comments: who wrote it by employee key, and whom it named. The other side sees authorName and authorOrgName.

  • bodystring

    Plain text with its line breaks. Empty once the author deleted it; deletedAt then says when.

  • viewerIsAuthorboolean

    Whether the caller wrote it, and so may delete it. Always false for an API key.

Errors

  • 404 Not Found - No PO with this id exists in the caller's workspace.
  • 409 Conflict - Supplier callers only. Code PO_ID_AMBIGUOUS: more than one of your buyers has issued a purchase order with this id (ids are unique only within a buyer), so Pleaxy won't guess which one you mean. Nothing is read or changed. The body's buyers lists each buyer's Workspace ID and name: repeat the call with ?buyer=<that Workspace ID>.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
GET /v1/workspaces/{regionId}/purchase-orders/{poId}/comments
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/comments" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "comments": [
      {
         "id": "string",
         "documentKind": "invoice" | "purchase_order",
         "documentId": "string",
         "body": "string",
         "visibility": "internal" | "shared",
         "authorSide": "buyer" | "supplier",
         "authorKey": "string",
         "authorName": "string",
         "authorOrgName": "string",
         "mentions": [ { "employeeKey": "string", "name": "string" } ],
         "createdAt": "string",
         "deletedAt": "string",
         "viewerIsAuthor": boolean
      }
   ]
}

Add purchase order comment

Adds a comment to a purchase order.

POST/v1/workspaces/{regionId}/purchase-orders/{poId}/comments

Parameters

  • poIdstringRequired

    The purchase order identifier.

  • buyerstring

    Supplier callers only, and only needed after a 409 *_ID_AMBIGUOUS: the buyer's Workspace ID (ending in .buyer) or region id, from the 409's buyers list. Only that buyer's document is considered; none there is a 404. A .supplier Workspace ID is 400 BUYER_QUALIFIER_INVALID ("The buyer parameter must be one buyer's Workspace ID (ending in .buyer), from the buyers list in the 409 response."). Ignored for a Buyer caller.

Body

  • bodystringRequired

    Plain text, up to 2,000 characters. Line breaks are kept; control, bidirectional-text and invisible characters are removed.

  • visibility"internal" | "shared"Required

    internal: your own team only. shared: the other side reads and answers it too. A supplier's comments are always shared.

  • mentionsstring[]

    Up to 10 employee keys of people in your own workspace to notify (see ListEmployees). The notification never carries the comment's text.

Returns

201 Created with the object shown in the response.

More details

Comments on a purchase order: internal to your team, or shared with the other side. Comments are never edited. The people you mention, your side's earlier commenters and, on a shared comment, the other side are notified (po_comment); the notification never carries the text.

Signed-in session only. An API key gets 403 HUMAN_SESSION_REQUIRED.

Errors

  • 400 Bad Request - An empty body ("Write something before you post the comment."), more than 2,000 characters, more than 10 mentions, a mention who isn't in your workspace, a visibility other than internal or shared, a supplier's internal comment ("A supplier's comments are always shared with the buyer."), or a shared comment on a document whose supplier isn't on Pleaxy (post it as internal instead).
  • 403 Forbidden - Code HUMAN_SESSION_REQUIRED: the caller is an API key ("Comments are written by people. Sign in to Pleaxy to post one.").
  • 404 Not Found - No PO with this id exists in the caller's workspace.
  • 409 Conflict - Supplier callers only. Code PO_ID_AMBIGUOUS: more than one of your buyers has issued a purchase order with this id (ids are unique only within a buyer), so Pleaxy won't guess which one you mean. Nothing is read or changed. The body's buyers lists each buyer's Workspace ID and name: repeat the call with ?buyer=<that Workspace ID>.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
POST /v1/workspaces/{regionId}/purchase-orders/{poId}/comments
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/comments" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "body": "string",
   "visibility": "internal" | "shared",
   "mentions": [ "string" ]
}
Response · 201 Created
{
   "id": "string",
   "documentKind": "invoice" | "purchase_order",
   "documentId": "string",
   "body": "string",
   "visibility": "internal" | "shared",
   "authorSide": "buyer" | "supplier",
   "authorKey": "string",
   "authorName": "string",
   "authorOrgName": "string",
   "mentions": [ { "employeeKey": "string", "name": "string" } ],
   "createdAt": "string",
   "deletedAt": "string",
   "viewerIsAuthor": boolean
}

Delete purchase order comment

Deletes one of your comments on a purchase order.

DELETE/v1/workspaces/{regionId}/purchase-orders/{poId}/comments/{commentId}

Parameters

  • poIdstringRequired

    The purchase order identifier.

  • commentIdstringRequired

    The comment, e.g. "CMT-1760313600000-3f9a1c2e".

  • buyerstring

    Supplier callers only, and only needed after a 409 *_ID_AMBIGUOUS: the buyer's Workspace ID (ending in .buyer) or region id, from the 409's buyers list. Only that buyer's document is considered; none there is a 404. A .supplier Workspace ID is 400 BUYER_QUALIFIER_INVALID ("The buyer parameter must be one buyer's Workspace ID (ending in .buyer), from the buyers list in the 409 response."). Ignored for a Buyer caller.

Returns

200 OK with the object shown in the response.

More details

Takes back your own comment: its text is removed and the thread keeps that a comment was made. Deleting it again changes nothing.

Signed-in session only. An API key gets 403 HUMAN_SESSION_REQUIRED.

Errors

  • 403 Forbidden - Code HUMAN_SESSION_REQUIRED: the caller is an API key ("Comments are written by people. Sign in to Pleaxy to post one.").
  • 403 Forbidden - The comment isn't yours ("Only the person who wrote a comment can delete it.").
  • 404 Not Found - No comment with this id that you can see on this document ("Comment {commentId} not found."), or no such document.
  • 409 Conflict - Supplier callers only. Code PO_ID_AMBIGUOUS: more than one of your buyers has issued a purchase order with this id (ids are unique only within a buyer), so Pleaxy won't guess which one you mean. Nothing is read or changed. The body's buyers lists each buyer's Workspace ID and name: repeat the call with ?buyer=<that Workspace ID>.
  • 401 Unauthorized - No credential was presented, or the Bearer token / X-Api-Key value is missing, invalid, expired, or revoked.
  • 403 Forbidden - The caller's Bearer token or API key doesn't grant access to this workspace (regionId), or lacks the required role.
DELETE /v1/workspaces/{regionId}/purchase-orders/{poId}/comments/{commentId}
Request
curl -X DELETE "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-orders/{poId}/comments/{commentId}" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "documentKind": "invoice" | "purchase_order",
   "documentId": "string",
   "body": "string",
   "visibility": "internal" | "shared",
   "authorSide": "buyer" | "supplier",
   "authorKey": "string",
   "authorName": "string",
   "authorOrgName": "string",
   "mentions": [ { "employeeKey": "string", "name": "string" } ],
   "createdAt": "string",
   "deletedAt": "string",
   "viewerIsAuthor": boolean
}
Talk to us