---
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
title: Approval request lifecycle
canonical: 'https://docs.nullplatform.com/docs/approvals/approval-requests'
---
# 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`, or because a checklist run resolved as `approve`. A checklist approved through an override or a manual review lands `approved` instead. |
| `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 or checklist 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. If it's still `executing` after 60 seconds, whatever was running it stopped: you can start the action again or cancel the request. |
| `success` | The action executed successfully. |
| `failed` | Execution encountered an error. You can start the action again. |
| `expired` | The execution window closed before the action was triggered. |

In checklist mode, whether the action starts on its own once the request is approved is up to the spec's `execution_trigger`, covered in [Choose what starts the approved action](/docs/approvals/checklist-specs#choose-what-starts-the-approved-action). When it doesn't, someone starts it: **Start deployment**, **Create scope**, or **Apply changes** in the UI, or a `POST` request to `/approval/{id}/execute`. In either mode, starting a request that's already `success`, or `executing` for less than 60 seconds, does nothing: the call answers `200` with the request as it is, and the action isn't sent twice.

## 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):

**status-cli**

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

**status-curl**

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

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.
