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

# Enrollment states

> The six VPP enrollment states, their steps, the suspension reasons, and the message to show the user for each.

A VPP enrollment has a state in `enrollment_state` and a step in `enrollment_step`. Use the state to decide what your app does, and the step to tell the user what is happening.

Read both with [list VPP enrollments](/docs/energy-api/reference/vpp-enrollments/list.md); [retrieve a VPP enrollment](/docs/energy-api/reference/vpp-enrollments/retrieve.md) adds the timeline. Connect shows the steps on the [Enrollment](/docs/energy-api/reference/connect/vpp/enrollment.md) page.

## States

| `enrollment_state` | Dispatchable | Meaning |
| :- | :- | :- |
| `PENDING` | No | Onboarding |
| `ACTIVE` | Yes | Enrolled. `warnings` lists any non-critical issue |
| `SUSPENDED` | No | Paused until every reason in `suspension_reasons` clears |
| `LEAVING` | Existing commitments only | A request to leave awaits the VPP operator's approval |
| `ENDED` | No | Unenrolled, a terminal state. Records are kept |
| `REJECTED` | No | Ineligible, declined or failed. Also terminal |

```mermaid actions={false} theme={"system"}
stateDiagram-v2
    direction TB
    [*] --> PENDING
    PENDING --> REJECTED : turned down or failed
    PENDING --> Enrolled : approved
    state Enrolled {
        direction LR
        ACTIVE --> SUSPENDED : reason raised
        SUSPENDED --> ACTIVE : reasons cleared
    }
    Enrolled --> LEAVING : asks to leave
    LEAVING --> ENDED : approved, or notice over
    Enrolled --> ENDED : operator unenrolls
```

## Steps

| `enrollment_step` | State | What happens | Message to show |
| :- | :- | :- | :- |
| `REQUESTED` | `PENDING` | Flatpeak checks eligibility | We've received your request to join. |
| `AWAITING_CONSENT` | `PENDING` | Waits for consent. Cleared in Connect | We need your permission to manage your device during events. |
| `AWAITING_TARIFF` | `PENDING` | Waits for a connected tariff. Connect asks for one | Connect your energy tariff so we can work out what your device earns. |
| `AWAITING_TELEMETRY` | `PENDING` | Waits for the first state or meter records the program requires | We're waiting for data from your device. Check it is on and online. |
| `TESTING_DISPATCH` | `PENDING` | A short `TEST` event to fetch, confirm and deliver. Retried up to 3 times over 7 days, then `FAILED` | We're running a short test. Nothing for you to do. |
| `AWAITING_APPROVAL` | `PENDING` | Waits for the VPP operator to approve | We're registering your device with the program. |
| `ACTIVE` | `ACTIVE` | Dispatchable | Your device is taking part in the program. |
| `SUSPENDED` | `SUSPENDED` | Not dispatchable | Your enrollment is paused. |
| `UNENROLLING` | `LEAVING` | The user left in Connect, or you called [unenroll a device](/docs/energy-api/reference/vpp-enrollments/unenroll.md). The request waits for the VPP operator's approval | Your request to leave is with the program operator. It can take up to 30 days. |
| `UNENROLLED` | `ENDED` | Left the program | You've left the program. Your records are kept. |
| `INELIGIBLE` | `REJECTED` | The device fails the program's rules, or the VPP operator turned the request down | Your home or device doesn't qualify. This can change if your setup changes. |
| `FAILED` | `REJECTED` | Onboarding did not complete, for example a failed dispatch test | We couldn't complete your enrollment. You can try again. |

A step that does not apply is `SKIPPED`: a tariff already connected, no telemetry required, `dispatch_test_required` set to `false`, or no approval needed. Timeline entries still `PENDING` carry `time_expected`, so you can show what comes next and when.

A request to leave needs the VPP operator's approval, and the operator cannot refuse it. A request left unanswered ends when the `notice_days` of the enrollment's `terms` have passed, so take the number of days in the `UNENROLLING` message from `terms.notice_days`.

## Suspension reasons

An `ACTIVE` enrollment can carry `warnings`, which do not stop dispatch. A critical reason suspends the enrollment at once, and so does a warning left past its grace period. The enrollment returns to `ACTIVE` when every reason clears.

| Reason | Critical | When | Clears when | Message to show |
| :- | :- | :- | :- | :- |
| `DISPATCH_UNRESPONSIVE` | No | Instructions are not fetched or confirmed in time | A fetch and a confirmation arrive | We can't reach your device. Check it is online. |
| `TELEMETRY_STALLED` | No | A required feed stops | The data returns | We're waiting for data from your device. Check it is on and online. |
| `CONSENT_REVOKED` | Yes | The user withdrew a consent scope the program requires | The user grants it again in Connect | We need your permission to manage your device. Grant it again to resume. |
| `USER_PAUSED` | Yes | The user paused it | The user resumes | Your enrollment is paused at your request. Resume at any time. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.