---
sidebar_label: Approval request lifecycle
toc_max_heading_level: 3
doc_id: 3f8c2a1d-7e4b-4d9f-b6a3-c1e5d8f20394
description: >-
  Understand how approval requests progress through statuses, how expiration
  windows work, and how to track the state of a request.
keywords:
  - approval request
  - lifecycle
  - status
  - expiration
  - execution window
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Approval request lifecycle

An **approval request** is created automatically whenever a user triggers an action governed by an approval action.
It records the pending decision and tracks the request through review, approval or denial, and execution.

## Request statuses

| Status | Description |
|---|---|
| `pending` | Awaiting a decision from a human reviewer or policy evaluation. |
| `approved` | Manually approved by a reviewer. |
| `auto_approved` | Automatically approved because a policy passed and `on_policy_success` is set to `approve`. |
| `auto_denied` | Automatically denied because a policy failed and `on_policy_fail` is set to `deny`. |
| `denied` | Manually denied by a reviewer. |
| `cancelled` | Cancelled before a decision was reached. |
| `expired` | No decision was made before the reply window closed. |

```mermaid
flowchart TD
  A([Request created]) --> B[pending]
  B -->|Policy passes — auto| C[auto_approved]
  B -->|Policy fails — auto| D[auto_denied]
  B -->|Manual approval| E[approved]
  B -->|Manual denial| F[denied]
  B -->|Cancelled| G[cancelled]
  B -->|Reply window closes| H[expired]
  C --> I([Execution window opens])
  E --> I
  D --> Z([Done])
  F --> Z
  G --> Z
  H --> Z
```

## Execution statuses

Once a request reaches `approved` or `auto_approved`, an execution window opens. The `execution_status` tracks the state of the underlying action.

| Execution status | Description |
|---|---|
| `pending` | Approved but not yet executed. |
| `executing` | Execution is in progress. |
| `success` | The action executed successfully. |
| `failed` | Execution encountered an error. |
| `expired` | The execution window closed before the action was triggered. |

## Expiration windows

:::note
Expiration windows are currently used when users request access to secret parameter values. If that's your use case, check out [Accessing secret values](/docs/parameters/secret-visibility#ask-for-approval) for a full example.
:::

Two time limits control how long each phase can last. Both are configured on the approval action, not on individual requests.

- **`time_to_reply`**: How long (in milliseconds) approvers have to respond. If the window closes without a decision, the request status moves to `expired`.
- **`allowed_time_to_execute`**: How long (in milliseconds) after approval the action can be executed. If execution doesn't happen within this window, the `execution_status` moves to `expired`.


## Checking request status

To retrieve the current status of an approval request, send a [GET request to the approval endpoint](/docs/api/approval-read):

<Tabs
defaultValue="status-cli"
values={[
{ label: 'CLI', value: 'status-cli' },
{ label: 'cURL', value: 'status-curl' },
]}>

<TabItem value="status-cli">

```bash
np approval read --id 1234
```

</TabItem>
<TabItem value="status-curl">

```bash
curl -L 'https://api.nullplatform.com/approval/1234' \
-H 'Authorization: Bearer <token>'
```

</TabItem>
</Tabs>

The response includes both `status` and `execution_status`, so you can tell at a glance where the request is in its lifecycle.

## What's next

[Create a checklist](/docs/approvals/checklists) to automate approval decisions and reduce the number of requests that require manual review. [Policies](/docs/approvals/policies) still work for the actions that use them, but they'll be deprecated in favor of checklists.
