Approval Status and Queues
Two read endpoints cover the two questions you ask about an approval in flight: where does this record stand? and what is waiting on this person?
Get Approval Status for a Record
GET /cpq/approval-requestsParameter | Type | Description |
|---|---|---|
recordId | string | The record to read approval status for |
curl -X GET 'https://api.nue.io/cpq/approval-requests?recordId=0Q0Kb000000XyZaKAK' \
-H 'nue-api-key: YOUR_API_KEY'{
"status": "SUCCESS",
"data": {
"requestId": "a0TKb000000VwCdMAK",
"recordId": "0Q0Kb000000XyZaKAK",
"status": "Pending",
"isLocked": true,
"submittedMessage": "Discount approved by regional director on the call",
"rejectionMessage": null,
"steps": [
{
"approvalId": "a0UKb000000WxDeMAK",
"stepId": "a0SKb000000UvBcMAK",
"stepName": "Deal Desk",
"processName": "Standard Discount Approval",
"status": "Approved",
"stepStatus": "Pending",
"approverUserId": "005Kb000000WxYzIAK",
"originalApproverUserId": null,
"reassignedFromApprovalId": null,
"rejectionMessage": null,
"dependsOnStepId": null,
"assignedDate": "2026-09-03T18:22:11.000Z",
"actedDate": "2026-09-03T19:04:52.000Z",
"submitter": "005Kb000000QrStUAK"
}
]
},
"warnings": [],
"errors": []
}status and stepStatus are different fields
A row's status is that individual approval record's own outcome — Assigned, Approved, Rejected, Reassigned, or Revoked. stepStatus is the step-level rollup across every approver on that step.
They routinely disagree, and that is correct. In the response above one approver has already approved (status: "Approved") while the step itself is still open (stepStatus: "Pending") because another approver has not responded. Render the rollup for the step header and the row status per approver.
Reading the Trail
Each row tells you who was asked, what they did, and when:
- assignedDate and actedDate — when the approval landed and when it was answered. actedDate is null while still outstanding.
- rejectionMessage — the reason given, on rejected rows.
- originalApproverUserId and reassignedFromApprovalId — populated only on rows produced by a reassignment, giving you the previous approver and the approval it came from.
- dependsOnStepId — the step that must resolve before this one becomes active, so you can render a sequential path correctly rather than showing every step as pending at once.
List Pending Approvals
Returns an approver's outstanding work.
GET /cpq/approvalsParameter | Type | Description |
|---|---|---|
assignee | string | Salesforce User ID whose queue to read. Defaults to the calling user |
status | string | Filter by approval status, for example Pending |
cursor | string | Cursor from a previous response's nextCursor |
limitSize | integer | Page size. Values above 100 are clamped to 100 |
curl -X GET 'https://api.nue.io/cpq/approvals?status=Pending&limitSize=50' \
-H 'nue-api-key: YOUR_API_KEY'{
"status": "SUCCESS",
"data": {
"assignee": "005Kb000000WxYzIAK",
"approvals": [
{
"approvalId": "a0UKb000000WxDeMAK",
"recordId": "0Q0Kb000000XyZaKAK",
"recordName": "Q-01842",
"processName": "Standard Discount Approval",
"stepName": "Deal Desk",
"stepStatus": "Pending",
"assignedDate": "2026-09-03T18:22:11.000Z",
"submitter": "005Kb000000QrStUAK"
}
],
"nextCursor": "eyJvIjoxMDB9",
"limit": 50
},
"warnings": [],
"errors": []
}recordName is included so you can render a readable queue without a second lookup per row.
Paging
Pass the nextCursor from one response as the cursor of the next. nextCursor is null on the last page:
curl -X GET 'https://api.nue.io/cpq/approvals?status=Pending&limitSize=50&cursor=eyJvIjoxMDB9' \
-H 'nue-api-key: YOUR_API_KEY'limitSize is clamped, not rejected
Asking for more than 100 returns 100 rather than an error, and the limit field in the response tells you the page size actually applied. Read limit rather than assuming you got what you asked for. Only a zero or negative limitSize is treated as invalid.
Building an Approver Queue
Combining the two endpoints gives you a working queue in three calls:
- GET /cpq/approvals?assignee={userId}&status=Pending — the rows to display, with recordName for each.
- GET /cpq/approval-requests?recordId={recordId} — on click, the full path for that record so the approver can see who else is involved and what came before them.
- POST /cpq/approvals:approve or :reject with the approvalId from step 1.