# List approval requests

> The approvals.list operation: GET /api/v1/approvals in the REST API and the approvals_list tool in the MCP server.

Lists 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) and `starting_after`
- **Authentication:** API key with the `approvals:read` scope
- **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

```http
GET /api/v1/approvals?status=pending
Authorization: Bearer or_test_…
```

Response (`200`):

```json
{
  "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

```http
GET /api/v1/approvals?status=executed&status=rejected&status=stale&limit=2
Authorization: Bearer or_test_…
```

Response (`200`):

```json
{
  "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`](https://ownrecord.io/docs/reference/errors.md#validation_failed) | 400         | A filter or pagination value is invalid. | Fix the fields listed in `details.issues` and send the request again.           |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#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](https://ownrecord.io/docs/reference.md#common-errors): [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found), [`dry_run_not_supported`](https://ownrecord.io/docs/reference/errors.md#dry_run_not_supported), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
