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

# Plans

> Run one device under a managed tariff with a plan, then follow the OEM's confirmation and the timeline.

A plan runs one device under a [managed tariff](/docs/fleet-api/guides/programs.md). You supply the energy and decide when the device charges and discharges, and every interval is binding on the OEM.

Plans work only for a device with an `ACTIVE` enrollment in one of your managed programs; any other device returns `422` `plan_not_allowed`. To commit devices to a market activation, use a [VPP event](/docs/fleet-api/guides/dispatch/vpp-events.md).

1. Submit the plan.
2. Flatpeak bounds it to the device's limits and the customer's settings. Where a VPP event commitment overlaps, the commitment takes its place.
3. The OEM fetches the instructions, applies them and confirms the power the device will deliver.
4. `device.instructions.confirm` fires with the `device_id` and the `confirmation_id`.
5. Read the timeline, and verify delivery with meter records.

## Submit a plan

```json Request body theme={"system"}
{
  "reference_id": "PLAN-2026-07-13-0001",
  "intervals": [
    { "start_time": "2026-07-13T20:14:00Z", "end_time": "2026-07-13T22:00:00Z", "power_kw": -4.3 },
    { "start_time": "2026-07-14T02:00:00Z", "end_time": "2026-07-14T06:00:00Z", "power_kw": 7.4 }
  ]
}
```

[Submit a dispatch plan](/docs/fleet-api/reference/plans/submit.md) with one or more `intervals`, the same shape a VPP event uses. `power_kw` is signed: positive to import, negative to export. A plan replaces any earlier plan over the same time. Pass `reference_id` to make a retry safe: resubmitting the same value returns the stored plan. The response carries a `pln_` ID.

## Limits

| Limit | Detail |
| :- | :- |
| Submissions | 12 per device per hour, then `429` `plan_rate_limited` with `retry_after` in seconds |
| Power | `max_import_power_kw` and `max_export_power_kw` in `dispatch_limits`. A plan above them fails at submission |
| Backup reserve | Energy under the customer's `backup_reserve_percent` is not dispatched |
| Export rule | A battery with `export_rule` `PV_ONLY` or `NEVER` is not asked to export |
| Charge from grid | A battery with `charge_from_grid_enabled` `false` is not asked to pre-charge |
| Device condition | A device that is islanded or holding charge for a storm sits out, and its state shows `available` `false` |

Intervals cut by the customer's [settings](/docs/fleet-api/guides/devices.md#settings) or by device condition are recorded as declined and do not count against fulfillment.

## Confirmation

Subscribe to `device.instructions.confirm` in [Console](https://console.flatpeak.com) > **Webhooks**, so you do not need to poll. A confirmed power below your plan is a deviation: the plan stands and the shortfall is recorded.

## Timeline

[Retrieve a dispatch timeline](/docs/fleet-api/reference/plans/retrieve-timeline.md) returns the device's net flows at its connection point. The window covers up to 90 days, past or future, with no gaps.

| Field | Meaning |
| :- | :- |
| `origin` | `OPERATOR`: a VPP event share or your plan. `OEM`: the OEM's own operation of the device |
| `time_fetched`, `time_confirmed` | When the OEM fetched and confirmed the instruction |
| `energy_source` | `GRID`, `BATTERY` or `PV` |

A confirmed interval shows what the OEM intends, while delivery is measured from [meter records](/docs/fleet-api/guides/devices.md#meter-records) only.


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