---
title: "List pending approvals (MAP plane)"
method: GET
path: "/api/v1/plans/approvals/pending"
tags: ["MAP", "Workflow Control Plane"]
---

# List pending approvals (MAP plane)

`GET /api/v1/plans/approvals/pending`

## Request

- Base URL: `https://orchestrator.getaxonflow.com`
- URL: `https://orchestrator.getaxonflow.com/api/v1/plans/approvals/pending`
- Auth: none declared
- TypeScript: <https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/docs/api/v1/plans/approvals/pending/get.ts> (a function with typed inputs; its response is checked against the schema)

List steps currently awaiting human approval for MAP-backed workflows —
workflows whose metadata carries a `plan_id` (MAP confirm / step mode).
Every returned entry has `plan_id` populated; this is the intentional
asymmetry with the WCP-plane listing at
`/api/v1/workflows/approvals/pending`, mirroring the approve/reject
asymmetry established in Issue #1677 / ADR-046.

Reviewer integrators that need to render plan context can read
`plan_id` directly without a second lookup; clients that want a
plane-neutral view can use `/api/v1/hitl/queue` instead.

Reachable on Evaluation and above, the same resolve gate as the MAP
`/steps/{step_id}/approve` and `/steps/{step_id}/reject` endpoints.
Creating new approval entries requires Professional or above.

## Query parameters

- `plan_id` string
- `limit` integer

## Response `200`

List of pending plan approvals

- PendingApprovalsResponse: List of pending approvals across workflows for the caller's tenant.
  - `pending_approvals` PendingApproval[]
    - `workflow_id` string: WCP workflow identifier.
    - `workflow_name` string: Human-readable workflow name.
    - `plan_id` string: MAP plan identifier. Populated on the MAP-plane listing (`/api/v1/plans/approvals/pending`); omitted (omitempty) on the WCP-plane listing.
    - `step_id` string: Step awaiting approval.
    - `step_index` integer: Zero-based index of the step within the workflow.
    - `step_name` string: Human-readable step name.
    - `step_type` 'llm_call' | 'tool_call' | 'connector_call' | 'human_task' | 'synthesis' | 'action' | 'gate': Type of step operation.
    - `decision` 'allow' | 'block' | 'require_approval': Gate decision that paused the step — always `require_approval` for pending entries.
    - `decision_reason` string: Why approval is required.
    - `policies_matched` object[]: Policies that triggered the approval requirement.
    - `step_input` object: Step input payload (may be redacted by PII rules).
    - `approval_status` 'pending' | 'approved' | 'rejected': Current approval state — `pending` for listed entries.
    - `created_at` string, date-time: Time of the first /gate call that paused the step.
  - `count` integer: Total number of pending approvals matching the scope.

## Other responses

- `401`: Missing tenant or org identity. BOTH `X-Org-ID` and `X-Tenant-ID` must be present and neither may be the unowned-row sentinel. Documented as `400` until issue #3948, and the handler really did answer `400`: it read `X-Tenant-ID` raw, never looked at `X-Org-ID`, and accepted the sentinel, while the WCP endpoint this one is documented as the counterpart of demanded both and refused the sentinel. A reviewer UI got `200` from one and `401` from the other for the same request. Both now bind the caller scope and both answer `401`.
- `403`: License tier does not permit approval listing (Community; Evaluation and above may list, approve and reject). Unlike the WCP counterpart, this route is registered unconditionally and the tier gate runs INSIDE the handler, so the refusal really is a `403` here.
- `503`: Workflow control plane unavailable

---

[API](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api.md) - [All operations](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/revisions/f408ef3ec9dd?raw)
