# Examples Annotated JSON examples walking through the session lifecycle, starting with the simplest case and layering in complexity. ## 1. Upcoming session The simplest session. The vehicle hasn't been plugged in yet — the system is just waiting, with a target inherited from the policy's weekly schedule. ```json {% title="Upcoming session" %} { "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "UPCOMING", "pluggedInAt": null, "pluggedOutAt": null, "blocks": [], "statistics": { "aggregated": null, "timeseries": [] }, "target": { "latest": { "id": 1, "type": "REGULAR", "source": "POLICY", "batteryReserve": 20, "minimumChargeTarget": 50, "readyBy": "2025-06-11T07:00:00Z" } }, "outcome": { "latest": null }, "error": { "latest": null } } ``` While `UPCOMING`, `blocks` is always `[]` and `statistics.aggregated` is always `null` — there is no charge plan or data yet. `outcome.latest` is `null` because the system doesn't know when the vehicle will plug in. The `target.latest` here is a `REGULAR` target with `source: "POLICY"` (inherited from the weekly schedule). ## 2. Active session — regular charging The core happy path. The vehicle plugged in at 22:15 with 35% battery. The system scheduled a battery reserve block first (charges to the reserve floor), then a regular block optimized against energy prices. It is currently 02:30 AM. ```json {% title="Active session with regular charging" %} { "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "ACTIVE:REGULAR", "pluggedInAt": "2025-06-10T22:15:00Z", "pluggedOutAt": null, "blocks": [ { "type": "BATTERY_RESERVE", "kwhSum": 3.2, "startAt": "2025-06-11T00:00:00Z", "endAt": "2025-06-11T00:30:00Z" }, { "type": "REGULAR", "kwhSum": 9.2, "startAt": "2025-06-11T01:00:00Z", "endAt": "2025-06-11T02:30:00Z" }, { "type": "REGULAR", "kwhSum": 7.4, "startAt": "2025-06-11T03:30:00Z", "endAt": "2025-06-11T04:30:00Z" } ], "statistics": { "aggregated": { "kwhSum": 12.4, "batteryFrom": 35, "batteryTo": 52 }, "timeseries": [ { "startAt": "2025-06-10T22:15:00Z", "kwh": 0 }, { "startAt": "2025-06-10T23:45:00Z", "kwh": 0 }, { "startAt": "2025-06-11T00:00:00Z", "kwh": 6.8 }, { "startAt": "2025-06-11T00:15:00Z", "kwh": 6.5 }, { "startAt": "2025-06-11T00:30:00Z", "kwh": 0 }, { "startAt": "2025-06-11T00:45:00Z", "kwh": 0 }, { "startAt": "2025-06-11T01:00:00Z", "kwh": 7.2 }, { "startAt": "2025-06-11T02:15:00Z", "kwh": 6.7 } ] }, "target": { "latest": { "id": 1, "type": "REGULAR", "source": "POLICY", "batteryReserve": 20, "minimumChargeTarget": 50, "readyBy": "2025-06-11T07:00:00Z" } }, "outcome": { "latest": { "type": "REGULAR", "targetId": 1, "state": "ON_TARGET", "batteryLevelAtReadyBy": null, "minimumChargeTargetReachedAt": null } }, "error": { "latest": null } } ``` The `blocks` array shows three charging windows: a completed `BATTERY_RESERVE` block, an in-progress `REGULAR` block, and a future tentative `REGULAR` block. `kwhSum` on each block reflects its state: actual energy delivered for completed and in-progress blocks, and the system's estimate for future blocks. The gap between block 1 and block 2 (00:30–01:00) appears as `kwh: 0` entries in the timeseries. The timeseries starts at `pluggedInAt` with zeros and only covers elapsed intervals — future block intervals are not included. `statistics.aggregated.kwhSum` (12.4) reflects actual delivered energy and does not include the estimated future block. `outcome.latest` is a `REGULAR` `ON_TARGET` outcome. `state: "ON_TARGET"` means the system estimates it will reach 50% by the 07:00 deadline — `batteryLevelAtReadyBy` and `minimumChargeTargetReachedAt` are `null` because projections are unnecessary when the target will be met. ## 3. Settled session A completed session. The vehicle charged overnight using the flexible schedule, then the user triggered an immediate start override mid-session (the `IMMEDIATE_START` block at 03:45), before the system resumed flexible charging. The vehicle was unplugged at 07:20. Once `SETTLED`, blocks and timeseries are final — they represent what actually happened, not a plan. ```json {% title="Settled session" %} { "id": "c3d4e5f6-a7b8-4012-9def-012345678902", "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "SETTLED", "pluggedInAt": "2025-06-09T21:45:00Z", "pluggedOutAt": "2025-06-10T07:20:00Z", "blocks": [ { "type": "REGULAR", "kwhSum": 18.5, "startAt": "2025-06-10T00:00:00Z", "endAt": "2025-06-10T03:45:00Z" }, { "type": "IMMEDIATE_START", "kwhSum": 5.5, "startAt": "2025-06-10T03:45:00Z", "endAt": "2025-06-10T04:15:00Z" }, { "type": "REGULAR", "kwhSum": 9.2, "startAt": "2025-06-10T05:00:00Z", "endAt": "2025-06-10T06:30:00Z" } ], "statistics": { "aggregated": { "kwhSum": 33.2, "batteryFrom": 22, "batteryTo": 85 }, "timeseries": [ { "startAt": "2025-06-09T21:45:00Z", "kwh": 0 }, { "startAt": "2025-06-10T00:00:00Z", "kwh": 7.4 }, { "startAt": "2025-06-10T03:30:00Z", "kwh": 4.8 }, { "startAt": "2025-06-10T03:45:00Z", "kwh": 11.0 }, { "startAt": "2025-06-10T04:00:00Z", "kwh": 11.0 }, { "startAt": "2025-06-10T04:15:00Z", "kwh": 0 }, { "startAt": "2025-06-10T04:45:00Z", "kwh": 0 }, { "startAt": "2025-06-10T05:00:00Z", "kwh": 6.0 }, { "startAt": "2025-06-10T06:15:00Z", "kwh": 4.5 }, { "startAt": "2025-06-10T06:30:00Z", "kwh": 0 } ] }, "target": { "latest": { "id": 2, "type": "IMMEDIATE_START", "minimumChargeTarget": 50 } }, "outcome": { "latest": { "type": "IMMEDIATE_START", "targetId": 2, "minimumChargeTargetReachedAt": "2025-06-10T06:10:00Z" } }, "error": { "latest": null } } ``` The timeseries tells the full story from plug-in (21:45) to plug-out (07:20): idle zeros → flexible charging at ~7 kW → the immediate start spike at 11 kW (03:45–04:15) → an idle gap (04:15–05:00) → more flexible charging → trailing zeros until unplug. Three blocks appear, two types. The `IMMEDIATE_START` block in the middle is where the user triggered an override — the charge rate jumped to 11 kW (full power). Each block's `kwhSum` tracks the energy delivered during that window. `target.latest` shows `IMMEDIATE_START` because the immediate start override was still active when the session settled. Once an immediate start override completes (the target is reached), the system reverts to the regular schedule target. In this case the vehicle was unplugged before that happened, so the override is what's captured. ## 4. Upcoming session with immediate start override The user triggered an "immediate start" override while the vehicle is still unplugged. Once plugged in, it will charge immediately to 70% with no flexibility. ```json {% title="Upcoming with immediate start" %} { "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "UPCOMING", "pluggedInAt": null, "pluggedOutAt": null, "blocks": [], "statistics": { "aggregated": null, "timeseries": [] }, "target": { "latest": { "id": 2, "type": "IMMEDIATE_START", "minimumChargeTarget": 70 } }, "outcome": { "latest": null }, "error": { "latest": null } } ``` Compare with Example 1 — the structure is identical except for `target.latest`, which is `IMMEDIATE_START` instead of `REGULAR`. ## 5. Upcoming session with schedule override The user adjusted the target for the upcoming session — raising the charge target to 90% and pushing the deadline to 08:00. The session is still `UPCOMING` but the target now reflects the user's custom settings instead of the policy defaults. ```json {% title="Upcoming with schedule override" %} { "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "UPCOMING", "pluggedInAt": null, "pluggedOutAt": null, "blocks": [], "statistics": { "aggregated": null, "timeseries": [] }, "target": { "latest": { "id": 2, "type": "REGULAR", "source": "USER_OVERRIDE", "batteryReserve": 20, "minimumChargeTarget": 90, "readyBy": "2025-06-11T08:00:00Z" } }, "outcome": { "latest": null }, "error": { "latest": null } } ``` The difference from Example 1 is inside `target.latest`: `source` is `"USER_OVERRIDE"` instead of `"POLICY"`, and `minimumChargeTarget` and `readyBy` reflect the user's custom values. The `batteryReserve` stays at 20% — it's a policy-level setting, not something the user adjusts per-session. Schedule overrides are temporary and expire after the session settles, at which point the next session reverts to `"POLICY"`. ## 6. Active session with error The vehicle is plugged in and a charge block is scheduled, but the system failed to start charging. No energy has been delivered. ```json {% title="Active session with START_FAIL error" %} { "policyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "state": "ACTIVE:REGULAR", "pluggedInAt": "2025-06-10T22:15:00Z", "pluggedOutAt": null, "blocks": [ { "type": "REGULAR", "kwhSum": 0, "startAt": "2025-06-11T01:00:00Z", "endAt": "2025-06-11T04:30:00Z" } ], "statistics": { "aggregated": { "kwhSum": 0, "batteryFrom": 35, "batteryTo": 35 }, "timeseries": [ { "startAt": "2025-06-10T22:15:00Z", "kwh": 0 }, { "startAt": "2025-06-11T01:15:00Z", "kwh": 0 } ] }, "target": { "latest": { "id": 1, "type": "REGULAR", "source": "POLICY", "batteryReserve": 20, "minimumChargeTarget": 50, "readyBy": "2025-06-11T07:00:00Z" } }, "outcome": { "latest": { "type": "REGULAR", "targetId": 1, "state": "OFF_TARGET", "batteryLevelAtReadyBy": 35, "minimumChargeTargetReachedAt": "2025-06-11T09:30:00Z" } }, "error": { "latest": { "type": "START_FAIL" } } } ``` `error.latest` is non-null — `START_FAIL` means the system tried to start charging but the vehicle didn't respond. The impact is visible everywhere: `kwhSum` is `0`, `batteryTo` equals `batteryFrom` (35%), the timeseries is entirely zeros, and the outcome is `OFF_TARGET` with `batteryLevelAtReadyBy` showing the estimated battery at the deadline. ## 7. Settled unmanaged session (public charging) The vehicle charged at a public charger away from home. The system observed the session but did not control it — there are no blocks, no target, and no outcome. Unmanaged sessions appear in both Get Settled Session and List Settled Sessions. While this session was happening, the policy's current session remained `UPCOMING` — still waiting for the vehicle to return to the policy's location. ```json {% title="Unmanaged session" %} { "id": "d1e2f3a4-b5c6-7890-abcd-ef0123456789", "policyId": null, "state": "SETTLED", "pluggedInAt": "2025-06-10T14:30:00Z", "pluggedOutAt": "2025-06-10T15:45:00Z", "blocks": [], "statistics": { "aggregated": { "kwhSum": 18.5, "batteryFrom": 30, "batteryTo": 62 }, "timeseries": [ { "startAt": "2025-06-10T14:30:00Z", "kwh": 45.2 }, { "startAt": "2025-06-10T15:30:00Z", "kwh": 12.1 } ] }, "target": { "latest": null }, "outcome": { "latest": null }, "error": { "latest": null } } ``` `policyId` is `null` — this session is not associated with any policy. `blocks` is empty because the system wasn't controlling the charge. `target.latest` and `outcome.latest` are both `null` — there was no goal to track against. Statistics are still available: `aggregated` shows total energy and battery progression, and the `timeseries` captures the charge rate. Note the higher kW values typical of DC fast charging compared to the home AC charging in the managed examples.