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 becomePATCH 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:GetVersionslists supported versions with their details URLs.GetVersionDetailsreturns the 2.2.1 module list:identifier(credentials,locations,sessions,cdrs,tariffs,tokens, …),role(SENDERorRECEIVER) andurl.
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 carriesAuthorization: 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 carryX-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:
{"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
GETlists of Locations, Sessions, CDRs, Tariffs from a CPO). A second connector with/ocpi/cpo/2.2.1paths would cover that. - OCPP (charger to CPO back office) uses WebSocket, not REST, and is out of scope.
Sources
- OCPI 2.2.1 specification (GitHub, release-2.2.1-bugfixes):
mod_locations,mod_sessions,mod_cdrs,mod_tariffs,mod_tokens,credentials,version_information_endpoint,transport_and_format - EVRoaming Foundation
- Hand-curated machine-readable cache:
openapi-cache/ocpi-2-2-1.json(OCPI does not publish an official OpenAPI file)
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.
