# Introduction A Session represents a single charging visit — from the moment the system anticipates a plug-in to the moment the vehicle leaves. Sessions are the primary way to understand what happened (or is happening) during a charge, and to surface that information to end users. ## Session lifecycle Every session progresses through three phases: ```text UPCOMING ──plug in──▶ ACTIVE:* ──plug out──▶ SETTLED ``` | State | Meaning | | --- | --- | | `UPCOMING` | Waiting for the vehicle to be plugged in. Created shortly after the previous session settles. Blocks and statistics are empty. | | `ACTIVE:BATTERY_RESERVE` | Vehicle is plugged in and charging to maintain the battery reserve floor before anything else. | | `ACTIVE:REGULAR` | Vehicle is plugged in and smart charging according to the optimized schedule. | | `ACTIVE:IMMEDIATE_START` | Vehicle is plugged in and charging immediately — no flexibility until the target is reached. | | `SETTLED` | Vehicle has been unplugged. All data is final. Blocks and statistics reflect what actually happened. | The `ACTIVE:*` sub-state reflects what the system is currently doing, not the overall session type. A session might transition through `ACTIVE:BATTERY_RESERVE` → `ACTIVE:REGULAR` as the reserve is filled. ## Managed vs. unmanaged sessions Sessions fall into two categories: **Managed sessions** (`policyId` is non-null) are tied to a policy and a location. The system actively controls charging — scheduling blocks, optimizing against energy prices, and tracking progress toward a target. Managed sessions go through the full lifecycle (`UPCOMING` → `ACTIVE:*` → `SETTLED`). **Unmanaged sessions** (`policyId` is null) represent charging that the system observed but did not control. This includes a vehicle charging away from home (e.g. at a public charger), or a vehicle at a location that doesn't have a policy. Unmanaged sessions are always `SETTLED` — there is no `UPCOMING` or `ACTIVE` state because the system isn't managing the charge. They have statistics (energy delivered, battery levels, timeseries) but no blocks, no target, and no outcome. Get Active Session is scoped to a policy and always returns a managed session. If the vehicle is away from home charging at a public charger, the policy's current session remains `UPCOMING` — it's still waiting for the vehicle to arrive at the policy's location. Get Settled Session and List Settled Sessions return both managed and unmanaged sessions. In List Settled Sessions, when filtering by `vehicleId` or `locationId`, each real-world charging event appears once — the managed session is returned if one exists, otherwise the unmanaged session. Filter by `policyId` to see only managed sessions. See [Example 7](https://flex.developers.enode.com/docs/sessions/examples#7-settled-unmanaged-session-public-charging) for what an unmanaged session looks like. ## Endpoints ### Get Active Session Get the current active or upcoming session for a policy. The response provides real-time visibility into what the system is charging towards (target), whether it will succeed (outcome), the actual charge windows (blocks), and energy delivery data (statistics). ```text GET /flex/vehicle-policies/{policyId}/session ``` ```bash {% title="Get the active session for a policy" %} GET /flex/vehicle-policies/f47ac10b-58cc-4372-a567-0e02b2c3d479/session ``` ### Get Settled Session Retrieve a single settled session by its ID. Returns both managed and unmanaged sessions. ```text GET /flex/vehicle-policies/{policyId}/sessions/{sessionId} ``` ```bash {% title="Get a specific settled session" %} GET /flex/vehicle-policies/f47ac10b-58cc-4372-a567-0e02b2c3d479/sessions/c3d4e5f6-a7b8-4012-9def-012345678902 ``` ### List Settled Sessions Retrieve a paginated list of settled sessions, optionally filtered. ```text GET /flex/vehicle-policies/sessions ``` | Parameter | Type | Description | | --- | --- | --- | | `from` | `datetime` | Return sessions with a `pluggedInAt` at or after this time. | | `to` | `datetime` | Return sessions with a `pluggedOutAt` at or before this time. | | `policyId` | `uuid` | Filter by policy. | | `locationId` | `uuid` | Filter by location. | | `vehicleId` | `uuid` | Filter by vehicle. Each real-world charging event appears once — the managed session is returned if one exists, otherwise the unmanaged session. | | `after` | `cursor` | Opaque cursor for fetching the next page. Cannot be set together with `before`. | | `before` | `cursor` | Opaque cursor for fetching the previous page. Cannot be set together with `after`. | | `pageSize` | `integer` | Number of records to return per page. | ```bash {% title="Get settled sessions for a policy" %} GET /flex/vehicle-policies/sessions?policyId=f47ac10b-58cc-4372-a567-0e02b2c3d479&from=2025-06-01T00:00:00Z&to=2025-06-30T23:59:59Z ``` ```json {% title="Response" %} { "data": [ { "id": "c3d4e5f6-...", "state": "SETTLED", "..." : "..." }, { "id": "a8b9c0d1-...", "state": "SETTLED", "..." : "..." } ], "pagination": { "after": "cursor_abc123", "before": null } } ``` ## Webhooks ### `flex:session:updated` Fired whenever a session changes — state transitions, new blocks, updated statistics, target changes, outcome updates, and error state changes all trigger this event. The payload wraps the full Session object. ```json {% title="Webhook payload" %} { "event": "flex:session:updated", "userId": "...", "createdAt": "2025-06-11T02:30:00Z", "session": { // Full Session object — same shape as the Get Session response } } ``` Frequent events during active charging: Because `flex:session:updated` fires on every change, sessions that are actively charging can generate frequent events. Subscribe to this webhook to drive real-time UI — for example, updating the charge rate graph or progress indicator as `statistics.timeseries` grows, or surfacing an error alert when `error.latest` becomes non-null.