OCPI COMMAND · UPDATED 11 AUG 2026

STOP_SESSION: ending a charge remotely

Stopping is harder than starting. A start command either works or does not; a stop command races against a driver who may be unplugging the cable at that exact moment, and against a session that may already have ended on its own.

PART OF THE OCPI 2.2.1 COMPLETE GUIDE · 15 MODULE & COMMAND GUIDES

IN ONE PARAGRAPH

STOP_SESSION ends an in-progress charging session by session ID. It is the simplest command in the module to send and the easiest to get wrong operationally, because the session can end naturally while your command is in flight. Design for that race rather than treating it as an error.

What it does

STOP_SESSION asks the CPO to terminate an active charging session. The CPO translates it into an OCPP RemoteStopTransaction (1.6J) or RequestStopTransaction (2.0.1), the charger stops delivering power, and a CDR follows once the CPO has finalised the numbers.

It is sent by the eMSP, which is the party holding the driver relationship. The driver taps “stop” in an app they got from their mobility provider, and that provider has to reach across into a charging network it does not own.

The one identifier that matters

Unlike START_SESSION, which needs a token, a location and an EVSE, STOP_SESSION takes exactly one meaningful field: session_id.

FieldRequiredNotes
response_urlYesWhere the CommandResult is POSTed
session_idYesThe session to terminate, as issued by the CPO

That simplicity hides a dependency: you can only stop a session whose ID you already know, and that ID came from the CPO through the Sessions module. If your session ingestion is lagging or lossy, you cannot stop sessions you cannot see. Reliability of STOP_SESSION is therefore a function of how well you consume Sessions, not of how well you send commands.

The full exchange

POST /ocpi/2.2.1/commands/STOP_SESSION
Authorization: Token <base64 token>
OCPI-from-country-code: IN
OCPI-from-party-id: EMS
OCPI-to-country-code: IN
OCPI-to-party-id: EFI
X-Request-ID: b41f9a02
X-Correlation-ID: driver-stop-88231

{
  "response_url": "https://emsp.example.com/ocpi/2.2.1/commands/STOP_SESSION/b41f9a02",
  "session_id": "sess-77c1"
}

The synchronous acknowledgement — again, not the outcome:

HTTP/1.1 200 OK

{
  "data": { "result": "ACCEPTED", "timeout": 30 },
  "status_code": 1000,
  "timestamp": "2026-08-11T10:03:12Z"
}

And the asynchronous result once the charger has actually stopped:

POST /ocpi/2.2.1/commands/STOP_SESSION/b41f9a02

{
  "result": "ACCEPTED"
}

If the session ID is not recognised, the failure comes back in the synchronous response rather than the callback, because the CPO can answer that without asking the charger:

HTTP/1.1 200 OK

{
  "data": { "result": "UNKNOWN_SESSION" },
  "status_code": 1000,
  "timestamp": "2026-08-11T10:03:12Z"
}

The race you must design for

Charging sessions end on their own. The driver unplugs, the battery fills, the vehicle stops drawing, a fault trips. Any of these can happen in the seconds between your command leaving and the charger receiving it.

The result is a set of outcomes that look like failures but are not:

What you observeWhat actually happenedCorrect response
UNKNOWN_SESSION on a session you just saw activeThe session ended and the CPO already closed itSuccess from the driver's point of view — show “charging stopped”
REJECTED immediately afterThe charger is already idleTreat as already-stopped, not as an error
TIMEOUT, then a CDR arrivesThe stop worked; the result was lostReconcile against the CDR, not the command
ACCEPTED but the session lingersCharger acknowledged and is ramping downWait — power-down is not instantaneous on DC
Never surface a raw stop failure to a driver. A driver who has already unplugged and walked away does not care that your command returned UNKNOWN_SESSION. The user-facing question is “has charging stopped?”, and the authoritative answer is the Session status or the CDR — not the command result.

Stop is not the same as billing complete

A common product mistake is treating the STOP_SESSION result as the moment to show a final cost. It is not. The sequence is:

  1. Command accepted — the CPO will try.
  2. Charger stops delivering power.
  3. Session object transitions to COMPLETED.
  4. The CPO finalises meter values, applies the tariff, and issues a CDR.

Step 4 can lag by minutes and legitimately by hours if the charger was offline. Presenting a total before the CDR arrives means either showing an estimate you later have to correct, or showing nothing. Both are valid product choices — silently showing an estimate as if final is not.

Production lessons

  • Make your session store the source of truth for stoppability. Only offer a stop button for sessions you can see as active. Offering it for a stale session generates avoidable UNKNOWN_SESSION responses.
  • Debounce driver taps. Frustrated drivers tap repeatedly. Send one command, keep the button in a pending state until you have a result or a session transition.
  • Treat UNKNOWN_SESSION as probable success. Verify against session status before showing an error. The overwhelming majority are races, not faults.
  • Set a hard fallback. If no result and no session transition arrives within a couple of minutes, tell the driver to unplug manually rather than leaving a spinner running.
  • Log the delta between command sent and session COMPLETED. That distribution per CPO is one of the clearest partner quality metrics you can collect.

Frequently asked questions

What does OCPI STOP_SESSION do?

It asks the CPO to terminate an active charging session by session ID. The CPO relays it to the charger as an OCPP RemoteStopTransaction or RequestStopTransaction, and a CDR follows once the CPO has finalised the numbers.

Why does STOP_SESSION return UNKNOWN_SESSION?

Usually because the session already ended on its own — the driver unplugged, or the vehicle finished — and the CPO has closed it. From the driver's perspective this is success, not failure, so verify against session status before showing an error.

Does a successful STOP_SESSION mean the final cost is known?

No. Stopping power delivery and issuing the CDR are separate steps. The CPO must finalise meter values and apply the tariff, which can take minutes or longer if the charger was offline. The CDR is the authoritative total.

What identifier does OCPI STOP_SESSION need?

Only session_id, plus the response_url for the async result. That means you can only stop sessions whose IDs you have already received through the Sessions module.