> ## Documentation Index
> Fetch the complete documentation index at: https://docs.passentry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pass Lifecycle

> Understand pass statuses and what happens in Apple Wallet and Google Wallet when a pass is deactivated, expires, or is reactivated.

A pass moves through several statuses during its life. This page explains what each status means, how to transition between them via the API, and how each transition is reflected in the user's wallet.

For permanent, irreversible data removal, see [Pass Nullification](/documentation/passes/nullification/guide).

## Pass statuses

| Status        | Meaning                                                                                                                   |
| ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `issued`      | The pass has been created but has not yet been added to a wallet.                                                         |
| `active`      | The pass is currently installed in a wallet.                                                                              |
| `removed`     | The user has removed the pass from their wallet. The record remains in PassEntry.                                         |
| `deactivated` | The pass has been deactivated. It appears in the expired section of the user's wallet.                                    |
| `expired`     | The pass has been expired via a scheduled `expiresAt`.                                                                    |
| `nullified`   | The pass has been [nullified](/documentation/passes/nullification/guide). All dynamic data has been irreversibly removed. |

## Deactivating a pass

You can deactivate a pass either immediately or on a schedule, from the Dashboard or via the API.

### From the Dashboard

<Tabs>
  <Tab title="Deactivate immediately">
    1. Go to **Passes** and select the pass you want to deactivate.
    2. In the **Pass management** section, click **Deactivate pass**.
    3. Confirm in the dialog. The pass status changes to `deactivated` and the deactivation timestamp is recorded.
  </Tab>

  <Tab title="Schedule deactivation">
    1. Go to **Passes** and click the edit icon on the pass you want to schedule.
    2. In the **Pass expiry** section, set the expiry date, time, and timezone.
    3. Save your changes. The pass is deactivated automatically when the expiry time is reached.
  </Tab>

  <Tab title="Bulk update via CSV">
    Use [Batch Pass Update](/documentation/bulk-operations/batch-pass-update/guide) to deactivate many passes at once.

    1. Go to **Bulk Operations** and click **Update via CSV**.
    2. Create a new batch, optionally name it, and select the pass template.
    3. Download the sample CSV, then for each pass set:
       * `pass_id` — the pass UUID or external ID.
       * `pass_action` — `deactivate` to deactivate immediately, or `reactivate` to reactivate.
       * `expires_at` — an ISO 8601 UTC timestamp to schedule deactivation instead.
    4. Upload the CSV and submit the batch. Track progress and resolve row-level errors from the batch detail view.

    See the [Batch Pass Update guide](/documentation/bulk-operations/batch-pass-update/guide) for the full column reference and error handling.
  </Tab>
</Tabs>

<Info>
  Reactivating a pass from the Dashboard is only supported through Bulk Update via CSV (`pass_action=reactivate`). For a single pass, use the [API](#via-the-api).
</Info>

### Via the API

Use the [Update Pass](/api-reference/v1/passes/update-pass) endpoint to deactivate a pass, either immediately or on a schedule.

To deactivate, set `passAction` to `deactivate`:

```json theme={null}
{
  "passAction": "deactivate"
}
```

To deactivate at a future time, set `expiresAt` to an ISO 8601 timestamp in UTC:

```json theme={null}
{
  "pass": {
    "expiresAt": "2026-12-31T23:59:59Z"
  }
}
```

`expiresAt` must be in the future. If your organisation is on a trial, it must also be earlier than your trial expiry. Scheduled deactivation is processed hourly, so the status change can lag the timestamp by up to an hour.

### What deactivation does

* The pass status is set to `deactivated` and `deactivatedAt` is recorded.
* The pass **cannot be added to a wallet**. Download and install requests are rejected.
* When using PassEntry Validation, Scans and NFC taps are **refused**, with a refusal reason of `deactivated_pass`. The pass no longer works at entry points.
* Wallet notifications are **not delivered**, on either platform.
* The pass can still receive data updates through the API, and those updates are written to the wallet object.
* The pass is **not** removed from the user's wallet. It moves to the expired or archived section.
* The pass data and content **is unchanged** by default, if you wish to remove scanning data (Barcode/NFC) or remove pass content, this can be done in the same [Update Pass](/api-reference/v1/passes/update-pass) request that deactivates the pass.

<Info>
  On Google Wallet, deactivation can take up to 24 hours to propagate to the user's device. The wallet object is updated immediately; the delay is in Google's device sync.
</Info>

### Wallet behaviour

<Tabs>
  <Tab title="Apple Wallet">
    The pass is marked as voided and moves to the **expired passes** section of the wallet. It is not deleted; the user can still find it under expired passes.
  </Tab>

  <Tab title="Google Wallet">
    The pass state is set to `INACTIVE` and it moves to the inactive or archived section. It is **not** removed and remains accessible to the user.
  </Tab>
</Tabs>

## Reactivating a pass

To reactivate a single pass, call [Update Pass](/api-reference/v1/passes/update-pass) with `passAction` set to `reactivate`. To reactivate many passes at once, use [Batch Pass Update](/documentation/bulk-operations/batch-pass-update/guide) with `pass_action=reactivate` in the CSV.

```json theme={null}
{
  "passAction": "reactivate"
}
```

The resulting status depends on where the pass was in its lifecycle:

| State before reactivation                       | Resulting status                               |
| ----------------------------------------------- | ---------------------------------------------- |
| `deactivated`, and still in the holder's wallet | `active`                                       |
| `deactivated`, but never added to a wallet      | `issued`                                       |
| `removed`                                       | Unchanged. The holder must add the pass again. |

<Tabs>
  <Tab title="Apple Wallet">
    The pass remains in the **expired passes** section after reactivation. To move it back to the main passes view, the user must manually select **Unhide** on the pass in Apple Wallet.
  </Tab>

  <Tab title="Google Wallet">
    The pass state is set back to `ACTIVE` and returned to the main Wallet section. <br />Changes can take up to 24 hours to reach the user's device.
  </Tab>
</Tabs>

## Lifecycle timestamps

The pass record exposes the following timestamps, which are useful when reconciling state:

* `expiresAt` - when the pass is scheduled to be deactivated.
* `deactivatedAt` - when the pass was deactivated via an active request.
* `removedAt` - when the user removed the pass from their wallet.
* `nullifiedAt` - when the pass was nullified.

## Deactivation vs. nullification

|                        | Deactivation                | Nullification                                                   |
| ---------------------- | --------------------------- | --------------------------------------------------------------- |
| Reversible             | Yes (via `reactivate`)      | **No**                                                          |
| Pass data preserved    | Yes                         | No. Dynamic fields, images, barcode, and NFC are cleared        |
| Appears in wallet      | Yes, in the expired section | Yes, in the expired section with a generic "Deactivated" design |
| `extId` reusable       | No                          | Yes                                                             |
| Counts towards billing | Yes                         | Yes                                                             |

If you need to permanently remove passholder data (for example, for GDPR requests) or free up an `extId`, use [Pass Nullification](/documentation/passes/nullification/guide) instead.


## Related topics

- [Pass Binding](/documentation/passes/pass-binding/guide.md)
