Skip to main content
Technical Preview

Overview

OCPI (Open Charge Point Interface, maintained by the EVRoaming Foundation) is the open protocol EV charging networks use to share charge point data, sessions, billing records and tariffs. A CPO (charge point operator) runs the chargers; an eMSP (e-mobility service provider) owns the driver tokens and apps; a Hub (Gireve, Hubject’s OCPI gateway, e-clearing.net and others) can sit in between. The Ocpi221Peer connector puts a Coreflux broker on the CPO side. Chargers already speak OCPP or publish state over MQTT; LoT actions turn that state into OCPI calls to your roaming partner: EVSE status changes become PATCH on the eMSP’s Locations receiver, a session start becomes PUT /sessions, a finished charge becomes POST /cdrs, and an RFID swipe can be checked in real time with AuthorizeToken. Each event publishes the peer’s reply on <topic>/response. … stands for the module URL prefix, /ocpi/emsp/2.2.1 in the template. 13 events change state on the peer and are marked # WRITE in the .lot file.

Base URL and module URLs

OCPI does not fix URLs: each party publishes them. You get the versions URL and a Token A from your partner offline, then:
  1. GetVersions lists supported versions with their details URLs.
  2. GetVersionDetails returns the 2.2.1 module list: identifier (credentials, locations, sessions, cdrs, tariffs, tokens, …), role (SENDER or RECEIVER) and url.
The template uses the spec’s own example layout: BASE_ADDRESS https://ocpi-peer.example.com, versions at /ocpi/emsp/versions, modules under /ocpi/emsp/2.2.1/<module>. If your partner’s URLs differ, change VERSIONS, DETAILS and PREFIX in gen_route.py and regenerate, or edit the WITH ENDPOINT lines. Use the RECEIVER URLs for locations, sessions, CDRs and tariffs, and the SENDER URL for tokens.

Authentication

Every request carries Authorization: Token <encoded token>. Since OCPI 2.2-d2 the token must be Base64-encoded (UTF-8 bytes, RFC 4648). Many older 2.1.1 / 2.2 peers still expect the raw token, so check with your partner. Keep the current value (Token <base64>) in Hub secret OCPI_AUTHORIZATION. UpdateCredentials rotates tokens; DeleteCredentials unregisters.

Required headers

Every OCPI request must carry X-Request-ID and X-Correlation-ID (use a fresh UUID per request). The connector maps them from the payload fields request_id and correlation_id. The OCPI-to-country-code / OCPI-to-party-id / OCPI-from-* routing headers are only needed when you go through a Hub and are not in the template; add them to the events your Hub requires.

Request payload

Publish JSON on the event’s source topic: Example on energy/ocpi/evse/status:
Replies use the OCPI envelope {"data": …, "status_code": 1000, "status_message": "Success", "timestamp": "…"}. 1000 is success, 2xxx are client errors (2001 invalid parameters, 2003 unknown location, 2004 unknown token) and 3xxx server errors. Unknown objects on receiver GET and on AuthorizeToken return HTTP 404.

Example actions

OcpiChargerStatusToEmsp expects the charger to publish an OCPI-shaped patch such as {"status":"AVAILABLE","last_updated":"…"} on chargers/<evse_uid>/evse/status; map your charger’s own status values to OCPI Status (AVAILABLE, BLOCKED, CHARGING, INOPERATIVE, OUTOFORDER, PLANNED, REMOVED, RESERVED, UNKNOWN) first if they differ.

Writes

RegisterCredentials, UpdateCredentials, DeleteCredentials, PutLocation, PutEvse, PatchLocation, PatchEvseStatus, PatchConnector, PutSession, PatchSession, PostCdr, PutTariff and DeleteTariff change your partner’s data and can affect billing. Restrict which MQTT clients may publish to those topics with broker rules. Every PATCH body must include last_updated. Locations cannot be deleted in OCPI: PATCH the status to REMOVED instead.

Not packaged

  • CPO receiver interfaces the partner calls on you: Commands (START_SESSION, STOP_SESSION, RESERVE_NOW, UNLOCK_CONNECTOR, …), ChargingProfiles, Tokens push, and Credentials from the peer. These need REST API server mode.
  • Async callbacks to an arbitrary response_url, and HubClientInfo.
  • eMSP-role pulls (sender GET lists of Locations, Sessions, CDRs, Tariffs from a CPO). A second connector with /ocpi/cpo/2.2.1 paths would cover that.
  • OCPP (charger to CPO back office) uses WebSocket, not REST, and is out of scope.

Sources

Status

Blocked beta. Smoke: static 256/256, mock 26/26, controls 6/6, live 0/0. Unblock with a partner’s versions URL and Token A (eMSP, Hub test environment, or a self-hosted OCPI node), then re-run smoke_ocpi.py with OCPI_BASE_URL and OCPI_AUTHORIZATION (add OCPI_WRITE_TEST=1 for location writes), or complete a broker MQTT round-trip.
Last modified on October 21, 2026