Parts 2 to 6 were mostly about messages the charger sends. This part covers the commands the CSMS sends: starting and stopping sessions from an app, unlocking a stuck cable, rebooting a charger, taking a connector out of service, and reserving one. These are the messages your support team and your driver app will use every day. It is part 7; part 5 covers the transaction messages that follow a remote start.
RemoteStartTransaction
App-based and QR-code charging usually work like this: the driver selects a connector in an app, the app asks the CSMS to start, and the CSMS sends RemoteStartTransaction with an idTag that represents the driver or the payment.
[
2,
"csms-rs-301",
"RemoteStartTransaction",
{
"connectorId": 1,
"idTag": "APP7F3K9Q2"
}
][3, "csms-rs-301", {"status": "Accepted"}]idTag is required; connectorId is optional but, with multi-connector chargers, you almost always want it. Without it the charger picks a connector itself. You can also include a chargingProfile with purpose TxProfile to set a limit for the session from the start; part 9 covers profiles.
Accepted is not started
The response status is Accepted or Rejected, and Accepted only means the charger has accepted the request. The transaction itself starts when the charger sends StartTransaction, which can be seconds or minutes later, after the driver plugs in. The sequence looks like this:
CSMS -> CP RemoteStartTransaction {connectorId: 1, idTag: "APP7F3K9Q2"}
CP -> CSMS RemoteStartTransaction.conf {status: "Accepted"}
CP -> CSMS StatusNotification {connectorId: 1, status: "Preparing"}
(AuthorizeRemoteTxRequests = true only)
CP -> CSMS Authorize {idTag: "APP7F3K9Q2"}
(driver plugs in, cable detected)
CP -> CSMS StartTransaction {connectorId: 1, idTag: "APP7F3K9Q2", meterStart: ...}
CSMS -> CP StartTransaction.conf {transactionId: 880214, ...}
CP -> CSMS StatusNotification {connectorId: 1, status: "Charging"}Your app therefore needs a "waiting for vehicle" state, and the CSMS needs to correlate the incoming StartTransaction with the remote start request. Matching on charger, connector and idTag within a time window is the usual approach, which is why each app session should use a unique idTag. If the driver never plugs in, the charger abandons the request after ConnectionTimeOut seconds and returns to Available, without sending any message that refers to the remote start. Time out the pending request on your side too.
RemoteStopTransaction
[2, "csms-rst-302", "RemoteStopTransaction", {"transactionId": 880214}]
[3, "csms-rst-302", {"status": "Accepted"}]The only field is transactionId. Again, Accepted means the request was accepted; the session ends when StopTransaction arrives with reason Remote. If the charger answers Rejected, the most common causes are an unknown transactionId (the charger rebooted and lost the session, or you are using an ID from a duplicate start) or a charger already in the process of stopping.
UnlockConnector
[2, "csms-ul-303", "UnlockConnector", {"connectorId": 1}]
[3, "csms-ul-303", {"status": "Unlocked"}]The response status is Unlocked, UnlockFailed or NotSupported. This is primarily a support tool for a cable stuck in a socket-outlet charger. If a transaction is in progress on that connector, the charger stops it first (with stop reason UnlockCommand) and then unlocks. Chargers with tethered cables usually return NotSupported, since there is nothing to unlock on the charger side. Be careful about exposing this to drivers: unlocking during a session ends it.
Reset
[2, "csms-rb-304", "Reset", {"type": "Soft"}]
[3, "csms-rb-304", {"status": "Accepted"}]type is Soft or Hard, and the response is Accepted or Rejected. A soft reset asks the charger to stop ongoing transactions gracefully and restart its application software. A hard reset restarts the whole charger and is not required to stop transactions gracefully; where possible, the charger sends StopTransaction for the interrupted sessions after it restarts. Transactions ended by a reset are reported with reasons SoftReset or HardReset, and the charger sends a BootNotification when it comes back.
- Try
Softfirst. It is less disruptive and fixes most software hangs. - Do not retry a timed-out
Resetautomatically. The charger may already be rebooting; a second reset during boot can leave some hardware in a bad state. - The
ResetRetriesconfiguration key sets how many times the charger retries an unsuccessful reset. - A reset that never produces a
BootNotificationis a strong signal for a site visit. Alert on it.
ChangeAvailability
[2, "csms-ca-305", "ChangeAvailability", {"connectorId": 2, "type": "Inoperative"}]
[3, "csms-ca-305", {"status": "Scheduled"}]type is Inoperative or Operative. connectorId 0 applies to the whole charger. The response is Accepted, Rejected or Scheduled. Scheduled means a transaction is in progress, and the change will take effect when it ends. The charger then reports the new state as Unavailable (or back to Available) with a StatusNotification.
The spec requires availability to persist across reboots. Use it to take a broken connector out of service so it stops appearing as available in apps and roaming feeds, and remember to set it back after repair. An "unavailable since" report for your operations team catches the ones that were forgotten.
Reservations
The Reservation profile lets a driver hold a connector for a limited time.
[
2,
"csms-rn-306",
"ReserveNow",
{
"connectorId": 1,
"expiryDate": "2026-10-26T12:30:00Z",
"idTag": "04A2B3C4D5E680",
"reservationId": 5120
}
][3, "csms-rn-306", {"status": "Accepted"}]| ReserveNow status | Meaning |
|---|---|
Accepted | Reservation made; connector goes to Reserved |
Faulted | Connector or charger is faulted |
Occupied | Connector is in use or already reserved |
Rejected | Charger is not configured to accept reservations |
Unavailable | Connector or charger is unavailable |
The optional parentIdTag allows any card in the same group to use the reservation. reservationId is chosen by the CSMS; sending a ReserveNow with an existing reservationId replaces that reservation. When the reserved driver starts charging, the charger includes reservationId in StartTransaction so you can close the reservation. If expiryDate passes without use, the charger cancels the reservation itself and returns the connector to Available; there is no dedicated expiry message, so expire it on your side using the same date.
A reservation on connector 0 reserves the charger rather than a specific connector, and is only allowed when the ReserveConnectorZeroSupported configuration key is true. Cancel with CancelReservation:
[2, "csms-cr-307", "CancelReservation", {"reservationId": 5120}]
[3, "csms-cr-307", {"status": "Accepted"}]The response is Accepted or Rejected (unknown reservation). In practice many operators find reservations less useful in public charging than expected, because drivers who reserve and do not show up block a connector. If you offer them, keep the expiry short and consider a fee. In roaming scenarios, OCPI's RESERVE_NOW command maps onto this message (OCPI commands).
Command handling on the CSMS side
- Send commands through a per-charger queue and respect the one-outstanding-CALL rule from part 1.
- Record every command with who issued it and the response. Support teams need that history.
- Treat timeouts as unknown, not as failure. Check the charger's subsequent messages before telling a driver the start did not work.
- Show drivers and support staff the outcome (session started, cable unlocked) based on the follow-up messages, not just on
Accepted.
Key takeaways
Acceptedfor remote start and stop means the request was taken, not that the session changed. Watch for the follow-upStartTransactionorStopTransaction.- Use a unique
idTagper app session so the eventualStartTransactioncan be correlated. UnlockConnectorstops an active transaction;Resetis not safe to retry blindly.ChangeAvailabilitypersists across reboots and can beScheduled.
Previous: Part 6, MeterValues. Next: Part 8, configuration keys and TriggerMessage.

