Dynamo CSMS implements the Open Charge Point Interface (OCPI) 2.2.1 protocol, enabling your network to participate in EV roaming. As a Charge Point Operator (CPO), you can register with eMobility Service Providers (eMSPs), expose your locations and tariffs to roaming partners, and accept guest charging sessions from their drivers.
OCPI endpoints use a different authentication scheme from the rest of the Dynamo API. See OCPI authentication below.
Authentication
Standard API endpoints
All /api/v1/... endpoints use your standard API key:
Authorization: Bearer YOUR_API_KEY
# or
X-API-Key: YOUR_API_KEY
OCPI endpoints
All /ocpi/... endpoints use an OCPI token issued during the credentials handshake:
Authorization: Token <ocpi_token>
Your eMSP partner exchanges credentials with you and receives this token. You use their token when making outbound calls to their OCPI endpoints.
Versions
List supported versions
GET /ocpi/versions
Returns the OCPI versions your Dynamo CSMS instance supports and the URL for each version’s endpoint discovery.
curl https://api.dynamo-csms.com/ocpi/versions \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"status_message": "Success",
"data": [
{
"version": "2.2.1",
"url": "https://api.dynamo-csms.com/ocpi/versions/2.2.1"
}
]
}
Get version endpoints
GET /ocpi/versions/{version}
Returns the list of OCPI modules available for a given version and the URL for each.
The OCPI version string, e.g., "2.2.1".
curl https://api.dynamo-csms.com/ocpi/versions/2.2.1 \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": {
"version": "2.2.1",
"endpoints": [
{ "identifier": "credentials", "role": "SENDER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/credentials" },
{ "identifier": "locations", "role": "SENDER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/locations" },
{ "identifier": "sessions", "role": "SENDER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/sessions" },
{ "identifier": "cdrs", "role": "SENDER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/cdrs" },
{ "identifier": "tariffs", "role": "SENDER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tariffs" },
{ "identifier": "commands", "role": "RECEIVER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/commands" },
{ "identifier": "tokens", "role": "RECEIVER", "url": "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tokens" }
]
}
}
Credentials
The credentials handshake is the first thing you do when connecting to a new eMSP partner. You exchange tokens and platform details so both sides can authenticate future requests.
Get your CPO credentials
GET /ocpi/cpo/2.2.1/credentials
Returns your current CPO credentials. Share these with an eMSP partner to begin the registration process.
curl https://api.dynamo-csms.com/ocpi/cpo/2.2.1/credentials \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": {
"token": "ocpi_tok_abc123xyz",
"url": "https://api.dynamo-csms.com/ocpi/versions",
"business_details": {
"name": "Greenway Charging Ltd",
"website": "https://greenway.example.com",
"logo": { "url": "https://greenway.example.com/logo.png", "category": "OPERATOR", "type": "png" }
},
"party_id": "GWY",
"country_code": "GB",
"roles": [{ "role": "CPO", "business_details": { "name": "Greenway Charging Ltd" }, "party_id": "GWY", "country_code": "GB" }]
}
}
Register with an eMSP
POST /ocpi/cpo/2.2.1/credentials
Send this after an eMSP sends you their credentials. Completes the bilateral token exchange.
The token the eMSP provided to you.
The eMSP’s OCPI versions URL.
Details about the eMSP: name, website, and optional logo.
The eMSP’s 3-character party identifier.
ISO 3166-1 alpha-2 country code for the eMSP.
Array of role objects describing the eMSP’s OCPI roles.
curl -X POST https://api.dynamo-csms.com/ocpi/cpo/2.2.1/credentials \
-H "Authorization: Token YOUR_OCPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"token": "emsp_provided_token_xyz",
"url": "https://emsp-partner.example.com/ocpi/versions",
"business_details": {
"name": "FleetCharge eMSP",
"website": "https://fleetcharge.example.com"
},
"party_id": "FLC",
"country_code": "DE",
"roles": [{ "role": "EMSP", "party_id": "FLC", "country_code": "DE", "business_details": { "name": "FleetCharge eMSP" } }]
}'
Update credentials
PUT /ocpi/cpo/2.2.1/credentials
Update the credentials for an existing eMSP connection. Use the same request body as POST.
Unregister from an eMSP
DELETE /ocpi/cpo/2.2.1/credentials
Terminates the OCPI connection with a partner. Both sides’ tokens are invalidated.
Locations
Locations represent physical sites containing EVSEs and connectors. Roaming partners query these to present accurate availability data to drivers.
List locations
GET /ocpi/cpo/2.2.1/locations
Returns all your locations visible to roaming partners, including EVSE and connector details.
Number of locations to return per page (max 100).
Return only locations last updated after this ISO 8601 timestamp. Use for incremental sync.
curl "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/locations?limit=10" \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": [
{
"country_code": "GB",
"party_id": "GWY",
"id": "loc_001",
"name": "Canary Wharf Car Park",
"address": "1 Canada Square",
"city": "London",
"postal_code": "E14 5AB",
"country": "GBR",
"coordinates": { "latitude": "51.5054", "longitude": "-0.0235" },
"evses": [
{
"uid": "evse_cp001_1",
"evse_id": "GB*GWY*E001*1",
"status": "AVAILABLE",
"connectors": [
{
"id": "1",
"standard": "IEC_62196_T2",
"format": "CABLE",
"power_type": "AC_1_PHASE",
"max_voltage": 230,
"max_amperage": 32,
"max_electric_power": 7400
}
]
}
],
"last_updated": "2024-01-20T12:00:00Z"
}
]
}
Get a location
GET /ocpi/cpo/2.2.1/locations/{location_id}
Get an EVSE
GET /ocpi/cpo/2.2.1/locations/{location_id}/{evse_uid}
Get a connector
GET /ocpi/cpo/2.2.1/locations/{location_id}/{evse_uid}/{connector_id}
Sessions
GET /ocpi/cpo/2.2.1/sessions
Returns all active and recently completed charging sessions visible to the requesting eMSP. Only sessions initiated by drivers belonging to that eMSP are returned.
Return sessions started after this timestamp.
Return sessions started before this timestamp.
curl "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/sessions?date_from=2024-01-20T00:00:00Z" \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": [
{
"country_code": "GB",
"party_id": "GWY",
"id": "sess_ocpi_001",
"start_date_time": "2024-01-20T14:30:00Z",
"kwh": 18.4,
"cdr_token": { "uid": "tok_driver_001", "type": "RFID", "contract_id": "GB-FLC-C12345-6" },
"auth_method": "AUTH_REQUEST",
"location_id": "loc_001",
"evse_uid": "evse_cp001_1",
"connector_id": "1",
"currency": "GBP",
"status": "ACTIVE",
"last_updated": "2024-01-20T15:10:00Z"
}
]
}
Charge detail records (CDRs)
GET /ocpi/cpo/2.2.1/cdrs
Returns Charge Detail Records for completed sessions. CDRs are the authoritative billing records used by eMSPs to invoice their drivers.
Return CDRs for sessions ending after this timestamp.
Return CDRs for sessions ending before this timestamp.
curl "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/cdrs?date_from=2024-01-01T00:00:00Z&date_to=2024-01-31T23:59:59Z" \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": [
{
"country_code": "GB",
"party_id": "GWY",
"id": "cdr_001",
"start_date_time": "2024-01-15T08:30:00Z",
"end_date_time": "2024-01-15T09:45:00Z",
"session_id": "sess_ocpi_001",
"cdr_token": { "uid": "tok_driver_001", "type": "RFID", "contract_id": "GB-FLC-C12345-6" },
"auth_method": "AUTH_REQUEST",
"location_id": "loc_001",
"evse_uid": "evse_cp001_1",
"connector_id": "1",
"currency": "GBP",
"total_cost": { "excl_vat": 6.40, "incl_vat": 7.68 },
"total_energy": 22.4,
"total_time": 1.25,
"last_updated": "2024-01-15T09:46:00Z"
}
]
}
Tariffs
GET /ocpi/cpo/2.2.1/tariffs
Returns the tariffs visible to roaming partners. eMSPs use these to show drivers the cost of charging before they start a session.
curl https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tariffs \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": [
{
"country_code": "GB",
"party_id": "GWY",
"id": "tar_001",
"currency": "GBP",
"elements": [
{
"price_components": [
{ "type": "ENERGY", "price": 0.35, "step_size": 1 }
]
}
],
"last_updated": "2024-01-01T00:00:00Z"
}
]
}
Commands
eMSPs can send commands to your charge points through Dynamo CSMS. Dynamo handles the OCPP translation and returns the result to the eMSP.
POST /ocpi/cpo/2.2.1/commands/{command}
The command to execute. One of: START_SESSION, STOP_SESSION, RESERVE_NOW, UNLOCK_CONNECTOR.
curl -X POST https://api.dynamo-csms.com/ocpi/cpo/2.2.1/commands/START_SESSION \
-H "Authorization: Token YOUR_OCPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"response_url": "https://emsp-partner.example.com/ocpi/commands/result",
"token": { "uid": "tok_driver_001", "type": "RFID", "contract_id": "GB-FLC-C12345-6" },
"location_id": "loc_001",
"evse_uid": "evse_cp001_1",
"connector_id": "1"
}'
{
"status_code": 1000,
"data": {
"result": "ACCEPTED",
"timeout": 30,
"message": []
}
}
The result is sent synchronously for the initial acknowledgement, then asynchronously to response_url once the charge point responds.
Tokens
Tokens represent driver authorisation credentials (RFID cards, app tokens, etc.). eMSPs push their driver tokens to you so you can perform local authorisation without a network round-trip.
Get a token
GET /ocpi/cpo/2.2.1/tokens/{country_code}/{party_id}/{token_uid}
The eMSP’s ISO 3166-1 alpha-2 country code.
The eMSP’s 3-character party ID.
The token UID (e.g., RFID card number).
Create or replace a token
PUT /ocpi/cpo/2.2.1/tokens/{country_code}/{party_id}/{token_uid}
Idempotent — creates the token if it does not exist, replaces it if it does.
curl -X PUT "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tokens/DE/FLC/tok_driver_001" \
-H "Authorization: Token YOUR_OCPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"uid": "tok_driver_001",
"type": "RFID",
"contract_id": "DE-FLC-C98765-4",
"issuer": "FleetCharge eMSP",
"valid": true,
"whitelist": "ALLOWED",
"last_updated": "2024-01-20T00:00:00Z"
}'
Partially update a token
PATCH /ocpi/cpo/2.2.1/tokens/{country_code}/{party_id}/{token_uid}
Update specific fields of an existing token without replacing the whole record. Useful for toggling valid when a card is reported lost.
curl -X PATCH "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tokens/DE/FLC/tok_driver_001" \
-H "Authorization: Token YOUR_OCPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"valid": false}'
Authorize a token
POST /ocpi/cpo/2.2.1/tokens/{token_uid}/authorize
Check whether a token is authorised to charge. Returns an AuthorizationInfo object with the allowed status and any applicable location restrictions.
The token UID to authorise.
Token type: RFID, APP_USER, OTHER, AD_HOC_USER. Defaults to RFID.
curl -X POST "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tokens/tok_driver_001/authorize?type=RFID" \
-H "Authorization: Token YOUR_OCPI_TOKEN"
{
"status_code": 1000,
"data": {
"allowed": "ALLOWED",
"location": {
"id": "loc_001",
"evses": [{ "uid": "evse_cp001_1" }]
}
}
}
Guest sessions
Guest sessions allow drivers without an account or RFID card to charge by paying with a card or digital wallet, without registering.
Authorize a guest session
POST /api/v1/sessions/guest/authorize
Initiates an ad-hoc payment flow and returns a session token the driver can use to track and stop the session.
The charge point to start a guest session on.
The connector number to start charging on.
A tokenised payment method ID from your payment processor.
curl -X POST https://api.dynamo-csms.com/api/v1/sessions/guest/authorize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"charge_point_id": "cp_001",
"connector_id": 1,
"payment_method_id": "pm_1OqXYZABC123"
}'
{
"session_token": "guest_tok_01HXJ2K1L0M9N8O7",
"charge_point_id": "cp_001",
"connector_id": 1,
"status": "authorizing",
"expires_at": "2024-01-20T14:35:00Z"
}
Get guest session status
GET /api/v1/sessions/guest/{session_token}/status
The guest session token returned from the authorize call.
curl https://api.dynamo-csms.com/api/v1/sessions/guest/guest_tok_01HXJ2K1L0M9N8O7/status \
-H "Authorization: Bearer YOUR_API_KEY"
{
"session_token": "guest_tok_01HXJ2K1L0M9N8O7",
"status": "charging",
"energy_kwh": 8.2,
"cost_so_far": 2.87,
"currency": "GBP",
"started_at": "2024-01-20T14:31:00Z"
}
Stop a guest session
POST /api/v1/sessions/guest/{session_token}/stop
Sends a RemoteStopTransaction command to the charge point and finalises the payment.
curl -X POST https://api.dynamo-csms.com/api/v1/sessions/guest/guest_tok_01HXJ2K1L0M9N8O7/stop \
-H "Authorization: Bearer YOUR_API_KEY"
{
"session_token": "guest_tok_01HXJ2K1L0M9N8O7",
"status": "stopped",
"energy_kwh": 21.6,
"final_cost": 7.56,
"currency": "GBP",
"ended_at": "2024-01-20T15:48:00Z"
}
Get guest session receipt
GET /api/v1/sessions/guest/{session_token}/receipt
Returns a PDF receipt for a completed guest session. Response Content-Type is application/pdf.
Integration requests
If you need to connect Dynamo CSMS to an eMSP, roaming hub, or other partner platform not yet available in the integrations catalogue, you can submit an integration request.
Request a new integration
POST /api/v1/integration-requests
Type of integration requested: emsp, roaming_hub, payment, other.
Name of the partner or platform you want to connect.
Additional context about the use case and urgency.
curl -X POST https://api.dynamo-csms.com/api/v1/integration-requests \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"integration_type": "roaming_hub",
"partner_name": "Hubject",
"description": "We need to connect to the Hubject Intercharge network for pan-European roaming coverage."
}'
{
"id": "ireq_01HXK3L2M1N0O9P8",
"status": "submitted",
"partner_name": "Hubject",
"created_at": "2024-01-20T14:00:00Z"
}
List integration requests
GET /api/v1/integration-requests
Returns all integration requests submitted by your organization and their current status.
curl https://api.dynamo-csms.com/api/v1/integration-requests \
-H "Authorization: Bearer YOUR_API_KEY"
{
"data": [
{
"id": "ireq_01HXK3L2M1N0O9P8",
"integration_type": "roaming_hub",
"partner_name": "Hubject",
"status": "in_review",
"created_at": "2024-01-20T14:00:00Z"
}
],
"total": 1
}