API reference

Purchase requests

What people ask to buy, before there is an order: approval, budget check, then an order.

More about this resource

Any member of a buyer workspace can ask for something, whatever their procurement role: a request commits no money, and its approval is the control. A submitted request goes through the workspace's purchase request approval flow (by default the purchase order flow), the requester's spend limit and, when budgets are on, its cost center's budget. Once approved, someone who can raise orders turns it into a purchase order with ConvertPurchaseRequest. The order keeps the request's approval when it stays within what was approved, on the same cost center and GL account. Requests are buyer-only and never shown to suppliers.

List purchase requests

Lists the purchase requests you can see, newest first.

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

Parameters

  • status"draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled"

    Only requests with this status.

  • mineboolean

    true: only the caller's own requests.

  • awaitingMeboolean

    true: only the requests waiting on the caller's approval, as in their approvals queue. status and mine are then ignored.

Returns

200 OK with the object shown in the response.

More details

Lists the caller's own requests; with 'view' access to purchase orders, everyone's except other people's drafts; and any request whose approval chain names the caller. Newest first.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

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-requests
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
[
   {
      "id": "string",
      "title": "string",
      "description": "string",
      "requesterEmployeeKey": "string",
      "requesterName": "string",
      "costCenter": "string",
      "glCode": "string",
      "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
      "lineItems": [
         { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
      ],
      "amount": number,
      "currency": "string",
      "neededBy": "string",
      "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
      "notes": "string",
      "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
      "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
       },
      "approvalVersion": number,
      "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
      "poId": "string",
      "rejectionReason": "string",
      "createdAt": "string",
      "updatedAt": "string",
      "submittedAt": "string",
      "decidedAt": "string",
      "canceledAt": "string",
      "canceledBy": "string"
   }
]

Create purchase request

Asks for something: saves a draft, or submits it for approval.

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

Body

  • titlestringRequired

    What is needed, in a few words. Up to 200 characters.

  • descriptionstring

    Why it is needed: the business reason. Up to 4,000 characters. Required to submit.

  • costCenterstring

    A cost center's code or name, stored as its code. Required to submit when the workspace keeps a cost center list.

  • glCodestring

    The GL account (spend category), when it isn't the cost center's. Up to 40 characters.

  • supplierobject

    A supplier the requester suggests: { name, supplierConnectionId?, supplierRegionId? }. A name alone routes nothing; an approved supplier on the workspace's list is used by supplier-based approval steps.

  • lineItemsArray<{ name, lineType?, qty, unit?, unitPrice }>Required

    What is needed, 1 to 50 lines: name (up to 200 characters), qty (above 0), unit (optional, e.g. each, hour, month), unitPrice (an estimate, 0 or more, in the request's currency) and lineType (optional: goods or service, carried onto the order's line; left out, a time unit makes it a service, anything else goods). One line is fine for an estimate.

  • currencystring

    ISO 4217. The workspace's currency when left out.

  • neededBystring

    When it's needed, YYYY-MM-DD.

  • quoteImportIdstring

    A quote uploaded through the quote import, to attach.

  • notesstring

    Anything procurement should know. Up to 2,000 characters.

  • submitboolean

    true submits it for approval straight away; otherwise it is saved as a draft.

Returns

201 Created with the object shown in the response.

More details

Creates a purchase request as a draft, with the caller as its requester. With submit: true it is submitted straight away, as SubmitPurchaseRequest does, and the response shows it pending_approval, or approved when autonomy or an automation rule covers it.

Any member of the buyer workspace, whatever their procurement role.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - A field is missing or invalid. With submit: true, also when the request has no description, no amount above 0, or no cost center in a workspace that keeps a list.
  • 409 Conflict - Code over_budget. Budgets are enforced (block mode) and the request would take its cost center over budget, or there's no exchange rate to check it. The body's budgetCheck has the figures. Nothing is saved.
  • 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-requests
Request
POST /v1/workspaces/reg_01k5x8p9j3q7vn2mhb4tzc6rde.buyer/purchase-requests
{
   "title": "Monitors for the design team",
   "description": "Two new designers start on November 3.",
   "costCenter": "CC-1000",
   "lineItems": [ { "name": "27-inch monitor", "lineType": "goods", "qty": 2, "unit": "each", "unitPrice": 320 } ],
   "neededBy": "2026-11-03",
   "submit": true
}
Response · 201 Created
{
   "id": "PR-3F9A1C2E",
   "title": "Monitors for the design team",
   "requesterName": "Priya Shah",
   "costCenter": "CC-1000",
   "amount": 640,
   "currency": "USD",
   "status": "pending_approval",
   "approvalVersion": 1,
   ...
}

Get purchase request

Gets one purchase request.

GET/v1/workspaces/{regionId}/purchase-requests/{requestId}

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Returns

200 OK with the object shown in the response.

More details

Returns one purchase request with its approval chain, budget check and, once ordered, the purchase order it became (poId). Visible to the same people as in ListPurchaseRequests.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 404 Not Found - No purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 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-requests/{requestId}
Request
curl "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Update purchase request

Changes a draft, or a request waiting for approval.

PATCH/v1/workspaces/{regionId}/purchase-requests/{requestId}

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Body

  • titlestring

    What is needed, in a few words. Up to 200 characters.

  • descriptionstring

    Why it is needed: the business reason. Up to 4,000 characters. Required to submit.

  • costCenterstring

    A cost center's code or name, stored as its code. Required to submit when the workspace keeps a cost center list.

  • glCodestring

    The GL account (spend category), when it isn't the cost center's. Up to 40 characters.

  • supplierobject

    A supplier the requester suggests: { name, supplierConnectionId?, supplierRegionId? }. A name alone routes nothing; an approved supplier on the workspace's list is used by supplier-based approval steps.

  • lineItemsArray<{ name, lineType?, qty, unit?, unitPrice }>

    What is needed, 1 to 50 lines: name (up to 200 characters), qty (above 0), unit (optional, e.g. each, hour, month), unitPrice (an estimate, 0 or more, in the request's currency) and lineType (optional: goods or service, carried onto the order's line; left out, a time unit makes it a service, anything else goods). One line is fine for an estimate.

  • currencystring

    ISO 4217. The workspace's currency when left out.

  • neededBystring

    When it's needed, YYYY-MM-DD.

  • quoteImportIdstring

    A quote uploaded through the quote import, to attach.

  • notesstring

    Anything procurement should know. Up to 2,000 characters.

Returns

200 OK with the object shown in the response.

More details

The requester changes the fields sent; the rest stay. Sending lineItems replaces every line. A request waiting for approval goes back through approval from the start, because its approvals were for what it said before.

The requester only.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - A field is invalid, or the request is approved, ordered, rejected or canceled and can't be changed.
  • 403 Forbidden - The caller isn't the requester.
  • 404 Not Found - No purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 409 Conflict - Code over_budget. Budgets are enforced (block mode) and the request would take its cost center over budget, or there's no exchange rate to check it. The body's budgetCheck has the figures. Nothing is saved.
  • 409 Conflict - The request changed while this call was writing it. Read it again and retry.
  • 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-requests/{requestId}
Request
curl -X PATCH "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Submit purchase request

Submits a draft for approval.

POST/v1/workspaces/{regionId}/purchase-requests/{requestId}/submit

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Returns

200 OK with the object shown in the response.

More details

Builds the request's approval chain and notifies its first approver. Approval steps are routed by amount, supplier, requester, cost center and GL account. The status becomes pending_approval, or approved straight away when autonomy or an automation rule covers it. A request in another currency than the workspace's is routed at today's exchange rate; with no rate, it always goes to a person. Takes no body.

The requester only.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - The request was already submitted, or it has no description, no amount above 0, or no cost center in a workspace that keeps a list.
  • 403 Forbidden - The caller isn't the requester.
  • 404 Not Found - No purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 409 Conflict - Code over_budget. Budgets are enforced (block mode) and the request would take its cost center over budget, or there's no exchange rate to check it. The body's budgetCheck has the figures. Nothing is saved.
  • 409 Conflict - The request changed while this call was writing it. Read it again and retry.
  • 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-requests/{requestId}/submit
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}/submit" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Approve purchase request

Approves a purchase request's current approval step.

POST/v1/workspaces/{regionId}/purchase-requests/{requestId}/approve

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Body

  • expectedVersionnumber

    The approvalVersion the caller saw. If the request's approval moved since, the call is refused with 409 APPROVAL_VERSION_CHANGED rather than approving something else.

Returns

200 OK with the object shown in the response.

More details

Approves the step that names the caller. On the final step the budget is checked again before the request becomes approved; the requester is told, and so are the people who can raise orders. The same rules as approving a purchase order apply, including whether a requester may approve their own request.

Signed-in session only, with 'edit' access to purchase orders. Any other caller, including an API key, gets 403 HUMAN_APPROVAL_REQUIRED before anything is read.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - The request isn't waiting for approval.
  • 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 purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 409 Conflict - Code APPROVAL_VERSION_CHANGED: expectedVersion no longer matches. Read the request again.
  • 409 Conflict - Code over_budget. Budgets are enforced (block mode) and the request would take its cost center over budget, or there's no exchange rate to check it. The body's budgetCheck has the figures. Nothing is saved.
  • 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-requests/{requestId}/approve
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}/approve" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "expectedVersion": number
}
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Reject purchase request

Rejects a purchase request with a reason.

POST/v1/workspaces/{regionId}/purchase-requests/{requestId}/reject

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Body

  • reasonstringRequired

    Why the request is rejected; the requester sees it. Up to 1,000 characters.

Returns

200 OK with the object shown in the response.

More details

Rejects the request at the step that names the caller. The status becomes rejected, and the requester is told with the reason. Terminal: the requester asks again with a new request.

With 'edit' access to purchase orders. Only the employee the current step names; an API key gets 403 HUMAN_APPROVAL_REQUIRED.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - No reason, or the request isn't waiting for approval.
  • 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 purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 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-requests/{requestId}/reject
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}/reject" \
  -H "X-Api-Key: $PLEAXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json
body.json
{
   "reason": "string"
}
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Cancel purchase request

Withdraws a purchase request until it is ordered.

POST/v1/workspaces/{regionId}/purchase-requests/{requestId}/cancel

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Returns

200 OK with the object shown in the response.

More details

Withdraws a draft, a request waiting for approval, or an approved one not yet ordered. The status becomes canceled. Takes no body.

The requester, or a workspace administrator.

Response fields

  • statusstring

    draft until submitted; pending_approval while its approval chain runs; approved, then ordered once it became a purchase order (poId); or rejected (rejectionReason) or canceled.

  • amountnumber

    The lines' total (qty × unitPrice), in currency.

  • approvalobject

    The approval chain, absent while a draft. Built from the workspace's purchase request approval flow (by default its purchase order flow), the requester's spend limit and the budget check.

  • approvalVersionnumber

    Goes up with every approval change. Send it as expectedVersion when approving.

  • budgetCheckobject

    The cost center's budget check when budgets are on: the last one, from submitting or the final approval. Figures are in the budget's currency.

Errors

  • 400 Bad Request - The request is ordered, rejected or canceled already.
  • 403 Forbidden - The caller is neither the requester nor an administrator.
  • 404 Not Found - No purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 409 Conflict - The request changed while this call was writing it. Read it again and retry.
  • 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-requests/{requestId}/cancel
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}/cancel" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 200 OK
{
   "id": "string",
   "title": "string",
   "description": "string",
   "requesterEmployeeKey": "string",
   "requesterName": "string",
   "costCenter": "string",
   "glCode": "string",
   "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
   "lineItems": [
      { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
   ],
   "amount": number,
   "currency": "string",
   "neededBy": "string",
   "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
   "notes": "string",
   "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
   "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
    },
   "approvalVersion": number,
   "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
   "poId": "string",
   "rejectionReason": "string",
   "createdAt": "string",
   "updatedAt": "string",
   "submittedAt": "string",
   "decidedAt": "string",
   "canceledAt": "string",
   "canceledBy": "string"
}

Convert purchase request

Orders an approved request: creates its purchase order.

POST/v1/workspaces/{regionId}/purchase-requests/{requestId}/convert

Parameters

  • requestIdstringRequired

    The purchase request, e.g. PR-3F9A1C2E.

Body

  • any CreatePurchaseOrder fieldobject

    Every field is optional and defaults to the request's. supplier is needed when the request doesn't name one. Sending lineItems replaces the request's lines.

Returns

201 Created with the object shown in the response.

More details

Creates a purchase order from an approved request, as CreatePurchaseOrder does: the request's lines (one custom quantity line each), supplier, cost center, GL account, quote and notes, each of which the body can override. The order names the request (requestId) and the request becomes ordered, in one step, so a request becomes one order at most. When the order books to the same cost center and GL account and its amount, in the workspace's currency, is no more than what was approved, it keeps the request's approval; otherwise it goes through the purchase order approval flow. The requester is told.

With 'create' access to purchase orders.

Errors

  • 400 Bad Request - The request isn't approved, or neither the request nor the body names a supplier. Any refusal CreatePurchaseOrder makes also applies.
  • 409 Conflict - The request was already ordered.
  • 404 Not Found - No purchase request with this id that the caller can see. Someone who can't see a request learns nothing about whether it exists.
  • 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-requests/{requestId}/convert
Request
curl -X POST "$PLEAXY_API_BASE_URL/v1/workspaces/{regionId}/purchase-requests/{requestId}/convert" \
  -H "X-Api-Key: $PLEAXY_API_KEY"
Response · 201 Created
{
   "request": {
      "id": "string",
      "title": "string",
      "description": "string",
      "requesterEmployeeKey": "string",
      "requesterName": "string",
      "costCenter": "string",
      "glCode": "string",
      "supplier": { "name": "string", "supplierConnectionId": "string", "supplierRegionId": "string" },
      "lineItems": [
         { "name": "string", "lineType": "goods" | "service", "qty": number, "unit": "string", "unitPrice": number }
      ],
      "amount": number,
      "currency": "string",
      "neededBy": "string",
      "quoteDocument": { "importId": "string", "fileName": "string", "contentType": "string", "addedAt": "string", "quoteNumber": "string", "validUntil": "string" },
      "notes": "string",
      "status": "draft" | "pending_approval" | "approved" | "ordered" | "rejected" | "canceled",
      "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
       },
      "approvalVersion": number,
      "budgetCheck": { "outcome": "within" | "over" | "no_budget" | "no_rate" | "off", "mode": "off" | "warn" | "block", "costCenter": "string", "currency": "string", "budget": number, "remaining": number, "amount": number, "overBy": number, "checkedAt": "string" },
      "poId": "string",
      "rejectionReason": "string",
      "createdAt": "string",
      "updatedAt": "string",
      "submittedAt": "string",
      "decidedAt": "string",
      "canceledAt": "string",
      "canceledBy": "string"
   },
   "purchaseOrder": {
      "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"
   }
}
Talk to us