# Charging sessions

> How a charge is recorded on the platform, the two sides of a session, whether it is valid and billable, and how it becomes a CDR.

A **session** is the platform's record of a single charge. It ties together the pieces from the earlier pages: a token authorised at a connector on an EVSE Controller, owned by an Account, priced by a tariff, and turned into a billable record.

For the end-to-end flow across the protocols (plug in, authorise, meter, stop), see [anatomy of a charging session](/docs/emobility/anatomy-of-a-charging-session) in the primer. This page is about the session as a record.

## Two sides of one charge

A single charge is recorded twice, once from each side:

- a **CPO session**, the operator's record of a charge on its station, and
- an **MSP session**, the driver's provider's record of the same charge.

The two are separate records that hold different data: the CPO session carries the operator and OCPP side of the charge, the MSP session the driver and payment side. They are kept apart because the two sides are usually different companies. The **CPO session is the source**: when a charge finishes the operator turns it into a CDR, the billable record, and for a roaming charge pushes that CDR to the driver's network. The **MSP session is built from a received CDR**. The CDR is what connects the two. For how the CPO and eMSP sides fit together, see [the platform model](/docs/platform/introduction/overview).

The rest of this page describes the CPO session, the record an operator works with.

## What a session references

A session does not stand alone. It links back to:

- the **token** that authorised it,
- the **EVSE Controller**, **Connector** and **Location** it ran on,
- the **tariff** that priced it, and the resulting **cost** and **energy** delivered.

The token resolves to an **Account** and a driver only when it belongs to the platform. A roaming token belongs to another network, so the CPO session records it but the driver sits off-platform, and there is no matching MSP session on our side.

The cost is kept broken down, energy, time, a session fee and idle, alongside the total, in the session's currency and with VAT recorded against the rule that applied.

## Lifecycle

A session is not driven by a single status field. It opens when a token is authorised and a transaction starts on the station; it runs as meter values stream in over OCPP and cost is tracked against the tariff; it ends when the charge stops and the final energy and duration are known; and it is then settled into its billable figures. Whether a session is live, finished or settled is read from its timestamps and its billing state, not from one label.

## Valid, and billable

Two separate questions decide what becomes of a finished session, and the platform records each.

**Is it valid?** A session is marked invalid when its data cannot be trusted: implausible energy for the duration, an authorisation that was not accepted, a start or end time that makes no sense, or missing meter values.

**Is it reimbursed?** A perfectly valid session can still be left out of billing and reimbursement: a free, non-billable card, a session paid through an external solution, or one still waiting on an external funder to confirm before it can be included. That last case is left undecided on purpose until the funder answers.

Keeping the two apart matters for reconciliation, because a session that will not be billed is not necessarily a broken one. Either outcome is recorded with a reason, set automatically by the platform's integrity and billing checks or applied by hand.

### Reason codes

When a session is excluded, the reason is one of the following. A session can be excluded automatically or manually.

| Reason                                          | Description                                                                                                                           |
| :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
| `HISTORICAL_END`                                | The session started or ended on a past date that is no longer eligible for processing or billing.                                     |
| `MAINTENANCE_TOKEN`                             | The session was started using a maintenance token.                                                                                    |
| `HIGH_ENERGY_USAGE`                             | The session consumed too much energy (kWh) for the given duration, likely incorrect meter data or a reporting error from the station. |
| `LOW_ENERGY_USAGE`                              | The session consumed too little energy for the given duration.                                                                        |
| `LOW_DURATION`                                  | The session duration is too short.                                                                                                    |
| `IMPROBABLE_ENERGY_USAGE`                       | The calculated energy per minute is implausibly high for the given duration.                                                          |
| `NO_COST`                                       | The session has no associated cost.                                                                                                   |
| `AUTHORIZED_NON_BILLABLE_RFID`                  | The session was authorised by a non-billable card (an access-group member set to charge for free), so there is nothing to bill.       |
| `EXTERNAL_PAYMENT_SOLUTION`                     | The session was started with an external payment solution.                                                                            |
| `NON_ACCEPTED_AUTH`                             | The session began with an authorisation that was not accepted.                                                                        |
| `MISSING_OR_INVALID_SESSION`                    | The session is missing or invalid. This can happen when we respond `Invalid` to an authorisation but the station charges anyway.      |
| `MANUAL_EXCLUSION`                              | The session has been manually excluded.                                                                                               |
| `MANUAL_CANCELLATION`                           | The session was forcibly cancelled (for example, a `hard` cancellation).                                                              |
| `REPLACED_WITH_CORRECTED_SESSION`               | The session was considered invalid and replaced with a corrected session (for example, cost recalculated).                            |
| `INVALID_START_TIME`                            | The start time of the session is invalid.                                                                                             |
| `INVALID_END_TIME`                              | The session's end time is invalid.                                                                                                    |
| `UNKNOWN_METER_VALUES`                          | The meter values are unknown.                                                                                                         |
| `TEMPORARILY_EXCLUDED_WAITING_FOR_MISSING_DATA` | The session is held out while it waits for missing data.                                                                              |
| `NO_AUTO_REIMBURSEMENT`                         | The session cannot be reimbursed automatically because of insufficient payment information.                                           |
| `EXTERNAL_PAYMENT_FAILED`                       | The session is not eligible for reimbursement because an external payment failed.                                                     |
| `EXTERNAL_REIMBURSEMENT`                        | The session is reimbursed through an external arrangement rather than by the platform.                                                |
| `FAILED_TO_START`                               | The session failed to start. These are aborted sessions that never began properly.                                                    |
| `DUPLICATED`                                    | The session is a duplicate of another valid session.                                                                                  |
| `UNSPECIFIED`                                   | No specific reason was recorded.                                                                                                      |

## From session to CDR

A settled session's authoritative billable form is a **Charge Detail Record (CDR)**: the final statement of what was delivered and what it cost. Billing runs on the CDR, not on the live session, and where a charge crosses networks the CDR is also what the operators exchange to settle with each other, the roaming side covered in the [roaming](/docs/emobility/ocpi) section.

A CDR can be repriced while it is still being processed, but once it has been billed its price is fixed, and a later change is made as a credit rather than an edit. This is why a session from months ago still shows the price that was in force when it ran.
