List approval requests
The approvals.list operation: GET /api/v1/approvals in the REST API and the approvals_list tool in the MCP server.
/api/v1/approvalsLists the organization's approval requests in the mode of the request, newest first: the approvals inbox.
Filter by status (one or several of pending, approved, rejected, expired, executed, stale;
a pending request past its expiry counts as expired), operationId, entityId or brandId. Paginate
with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
At a glance
- REST:
GET /api/v1/approvals - MCP tool:
approvals_list - Operation ID:
approvals.list - Scope: Organization
- Permission:
approvals:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Pagination:
limit(at most 100) andstarting_after - Authentication: API key with the
approvals:readscope - Since: M2
Request
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer (1 to 100) | No | |
starting_after | apr_… ID | No | |
status | one of pending, approved, rejected, expired, executed, stale or array of one of pending, approved, rejected, expired, executed, stale | No | |
operationId | string | No | |
entityId | ent_… ID | No | |
brandId | brd_… ID | No |
Response
200 OK with a JSON object, a page of the list (newest first):
| Field | Type | Description |
|---|---|---|
object | "list" | |
data | array of object | |
data[].id | apr_… ID | |
data[].object | "approval_request" | |
data[].status | one of pending, approved, rejected, expired, executed, stale | |
data[].operationId | string | |
data[].summary | string | |
data[].orgId | org_… ID | |
data[].entityId | ent_… ID or null | |
data[].brandId | brd_… ID or null | |
data[].livemode | boolean | |
data[].requestedBy | object | |
data[].requestedBy.type | one of user, api_key, agent, app, system, public, customer | |
data[].requestedBy.id | string | |
data[].requestedBy.via | one of console, api, mcp, assistant, portal, job or null | |
data[].requestedBy.clientId | string or null | |
data[].requestedBy.onBehalfOfUserId | string or null | |
data[].requestedBy.appInstallationId | string or null | |
data[].amount | money or null | |
data[].input | any | |
data[].dryRun | object | |
data[].dryRun.output | any | |
data[].dryRun.events | array of string | |
data[].diff | object or null | |
data[].requiredApprovals | integer (1 to 2) | |
data[].approvals | array of object | |
data[].approvals[].userId | usr_… ID | |
data[].approvals[].at | date-time | |
data[].approvals[].comment | string or null | |
data[].rejection | object or null | |
data[].failure | object or null | |
data[].resultRef | string or null | |
data[].approveUrl | string | |
data[].expiresAt | date-time | |
data[].executedAt | date-time or null | |
data[].createdAt | date-time | |
data[].updatedAt | date-time | |
has_more | boolean | |
next_cursor | apr_… ID or null |
Examples
Requests waiting for a decision
GET /api/v1/approvals?status=pending
Authorization: Bearer or_test_…
Response (200):
{
"object": "list",
"data": [
{
"id": "apr_01m4ttwd3veh9apbewxheq5xh7",
"object": "approval_request",
"status": "pending",
"operationId": "brands.update",
"summary": "Update a brand",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"livemode": true,
"requestedBy": {
"type": "user",
"id": "usr_01m4ttwd3veh9apbewxheq5xh6",
"via": "console",
"clientId": null,
"onBehalfOfUserId": null,
"appInstallationId": null
},
"amount": null,
"input": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"dryRun": {
"output": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"events": ["brand.updated"]
},
"diff": {
"before": {
"statementDescriptor": "ACME"
},
"after": {
"statementDescriptor": "ACME APP"
}
},
"requiredApprovals": 1,
"approvals": [],
"rejection": null,
"failure": null,
"resultRef": null,
"approveUrl": "https://ownrecord.io/console/acme/approvals/apr_01m4ttwd3veh9apbewxheq5xh7?mode=live",
"expiresAt": "2026-10-16T12:00:00.000Z",
"executedAt": null,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
Decided requests, two per page
GET /api/v1/approvals?status=executed&status=rejected&status=stale&limit=2
Authorization: Bearer or_test_…
Response (200):
{
"object": "list",
"data": [
{
"id": "apr_01m4ttwd3veh9apbewxheq5xh8",
"object": "approval_request",
"status": "rejected",
"operationId": "brands.update",
"summary": "Update a brand",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"livemode": true,
"requestedBy": {
"type": "user",
"id": "usr_01m4ttwd3veh9apbewxheq5xh6",
"via": "console",
"clientId": null,
"onBehalfOfUserId": null,
"appInstallationId": null
},
"amount": null,
"input": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"dryRun": {
"output": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"events": ["brand.updated"]
},
"diff": {
"before": {
"statementDescriptor": "ACME"
},
"after": {
"statementDescriptor": "ACME APP"
}
},
"requiredApprovals": 1,
"approvals": [],
"rejection": {
"userId": "usr_01m4ttwd3veh9apbewxheq5xha",
"at": "2026-10-13T14:30:00.000Z",
"reason": "Not this quarter."
},
"failure": null,
"resultRef": null,
"approveUrl": "https://ownrecord.io/console/acme/approvals/apr_01m4ttwd3veh9apbewxheq5xh8?mode=live",
"expiresAt": "2026-10-16T12:00:00.000Z",
"executedAt": null,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "apr_01m4ttwd3veh9apbewxheq5xh7",
"object": "approval_request",
"status": "executed",
"operationId": "brands.update",
"summary": "Update a brand",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"livemode": true,
"requestedBy": {
"type": "user",
"id": "usr_01m4ttwd3veh9apbewxheq5xh6",
"via": "console",
"clientId": null,
"onBehalfOfUserId": null,
"appInstallationId": null
},
"amount": null,
"input": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"dryRun": {
"output": {
"id": "brd_01m4ttwd3veh9apbewxheq5xh5",
"statementDescriptor": "ACME APP"
},
"events": ["brand.updated"]
},
"diff": {
"before": {
"statementDescriptor": "ACME"
},
"after": {
"statementDescriptor": "ACME APP"
}
},
"requiredApprovals": 1,
"approvals": [],
"rejection": null,
"failure": null,
"resultRef": null,
"approveUrl": "https://ownrecord.io/console/acme/approvals/apr_01m4ttwd3veh9apbewxheq5xh7?mode=live",
"expiresAt": "2026-10-16T12:00:00.000Z",
"executedAt": "2026-10-13T14:30:00.000Z",
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": true,
"next_cursor": "apr_01m4ttwd3veh9apbewxheq5xh7"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A filter or pagination value is invalid. | Fix the fields listed in details.issues and send the request again. |
permission_denied | 403 | You can't see approval requests here. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, resource_not_found, dry_run_not_supported, rate_limited, internal_error.