A charging session in OCPP 1.6 uses two messages: StartTransaction (sent when energy flow begins) carries the connectorId, idTag, meterStart (Wh), and timestamp. The CSMS responds with a transactionId. StopTransaction ends the session with transactionId, meterStop, and timestamp. The energy consumed is meterStop − meterStart.
Transaction lifecycle
A standard OCPP 1.6 charging session follows this sequence (Open Charge Alliance, 2015, §4.8):
The Authorize step is optional if the Charge Point uses a local authorization list or an authorization cache hit. In that case, the Charge Point may send StartTransaction directly.
StartTransaction fields
| Field | Required | Type / max | Description |
|---|---|---|---|
| connectorId | Yes | integer | Connector where the session is starting. Must be ≥ 1 (connector 0 is not valid for transactions). |
| idTag | Yes | string / 20 | The authorization token that started the session (RFID UID, app token, etc.). Max 20 characters. |
| meterStart | Yes | integer (Wh) | Energy meter register reading at session start, in watt-hours. This is the absolute meter reading, not relative to the session. |
| timestamp | Yes | date-time | UTC time when energy flow began. |
| reservationId | No | integer | If this session fulfills a reservation, include the reservation ID from the original ReserveNow command. |
StartTransaction response
The CSMS responds with two required fields: transactionId (an integer the Charge Point must store and use in all subsequent messages for this session) and idTagInfo (the authorization result).
| idTagInfo.status | Meaning & required Charge Point action |
|---|---|
| Accepted | Authorization confirmed. Continue the session normally. |
| Blocked | Token is blocked. Stop transaction immediately with reason DeAuthorized. |
| Expired | Token has expired. Stop transaction with reason DeAuthorized. |
| Invalid | Token not recognized. Stop transaction with reason DeAuthorized. |
| ConcurrentTx | Token already has an active transaction on another connector. Behavior is CSMS-specific — some allow it, some don't. |
StopTransaction fields
| Field | Required | Type / max | Description |
|---|---|---|---|
| transactionId | Yes | integer | The ID received in the StartTransaction response. Links the stop to the correct session. |
| meterStop | Yes | integer (Wh) | Energy meter register reading at session end, in watt-hours. Energy delivered = meterStop − meterStart. |
| timestamp | Yes | date-time | UTC time when the session ended. |
| idTag | No | string / 20 | Token used to stop the session (for Local stops). Omit for Remote or timeout-triggered stops. |
| reason | No | enum | Why the session was stopped. See the reason table below. Defaults to Local if omitted. |
| transactionData | No | MeterValue[] | Meter readings from the session (same structure as MeterValues). Include energy readings for billing accuracy. |
Stop reason values
| reason | When to use |
|---|---|
| Local | Driver stopped the session by tapping RFID card or pressing the stop button. |
| EVDisconnected | The EV cable was physically unplugged without a formal stop — the Charge Point detected a disconnect. |
| Remote | CSMS sent a RemoteStopTransaction command. |
| DeAuthorized | The CSMS revoked authorization mid-session (idTagInfo.status was not Accepted in StartTransaction response). |
| EmergencyStop | Emergency stop button was pressed. |
| HardReset | The Charge Point was hard-reset (power cycle) by the CSMS. |
| SoftReset | The Charge Point was soft-reset by the CSMS. |
| Reboot | The Charge Point rebooted for any reason (firmware update, watchdog, etc.). |
| PowerLoss | The Charge Point lost AC power unexpectedly. Sent on reconnection after the outage. |
| UnlockCommand | The CSMS sent an UnlockConnector command. |
| Other | Any other reason not covered above. |
Edge cases & resilience
- No StartTransaction response received: The Charge Point should retransmit after a timeout. The CSMS must be idempotent — a duplicate StartTransaction with the same connector + timestamp should return the same transactionId, not create a second session.
- Power outage during session: On reconnect, send BootNotification, then send StopTransaction for any sessions that ended during the outage (reason:
PowerLoss). If the session is still physically active, resume it — sending a new StartTransaction is not required. - CSMS returns Blocked/Invalid in StartTransaction response: The Charge Point must stop energy flow and send StopTransaction with reason
DeAuthorized. Do not allow the session to continue even if the EV is drawing power. - Offline queuing: If the Charge Point loses connectivity mid-session, it should queue StartTransaction and MeterValues locally and retransmit in order after reconnecting. StopTransaction must always be delivered — it is the billing record.
OCPP 2.0.1: TransactionEvent
In OCPP 2.0.1, StartTransaction and StopTransaction are replaced by a single TransactionEvent message with an eventType field:
Started— equivalent to StartTransactionUpdated— periodic update (meter values, state change)Ended— equivalent to StopTransaction
TransactionEvent also introduces a seqNo (sequence number) that must increment for every event in a transaction, enabling the CSMS to detect and request missing events.
Common errors
meterStart and meterStop are in kWh instead of Wh
The schema defines meterStart and meterStop as integers in Wh. Sending 45.23 (kWh as a float) is both the wrong unit and the wrong type. Send 45230 (integer Wh).
Reusing a transactionId from a previous session
The transactionId comes from the CSMS, not the Charge Point. Never self-assign or reuse IDs. If the CSMS response is lost, retransmit StartTransaction — the CSMS handles deduplication.
Not sending StopTransaction after a reboot that ends a session
If the Charge Point reboots while a session is active and the EV disconnects during the outage, a StopTransaction must still be sent after reconnecting. The CSMS needs it to close the billing record.
Omitting reason from StopTransaction
Reason is optional but strongly recommended. Without it, the CSMS cannot distinguish a normal Local stop from an emergency stop or a remote command — this affects reporting, chargebacks, and network analytics.
Rodolfo Carrillo
OCPP integration engineer and creator of OCPP Tools. All articles are verified against the official OCA specification and tested using the on-site tools.
Build a frame in seconds
Form-driven payload builder — pick fields, get a valid frame, copy to clipboard.
Frequently asked questions
What should a Charge Point do if the CSMS responds with idTagInfo.status = Invalid?
What is transactionId and who generates it?
Is idTag required in StopTransaction?
What happens if the Charge Point reboots mid-transaction?
What is meterStart / meterStop and what unit should it use?
Can a Charge Point send StartTransaction without an Authorize first?
Sources & further reading
- · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, §4.8 — StartTransaction. https://openchargealliance.org/my-oca/ocpp/
- · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, §4.9 — StopTransaction. https://openchargealliance.org/my-oca/ocpp/
- · Open Charge Alliance. (2020). Open Charge Point Protocol 2.0.1, §5 — TransactionEvent. https://openchargealliance.org/my-oca/ocpp/