> ## Documentation Index
> Fetch the complete documentation index at: https://dynamo-csms.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# OCPI 2.2.1 Roaming API — Locations, Sessions, CDRs

> Connect your charging network to EV roaming networks using OCPI 2.2.1. Manage credentials, locations, sessions, tariffs, and driver tokens.

Dynamo CSMS implements the [Open Charge Point Interface (OCPI) 2.2.1](https://evroaming.org/ocpi-background/) 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.

<Info>
  OCPI endpoints use a different authentication scheme from the rest of the Dynamo API. See [OCPI authentication](#authentication) below.
</Info>

***

## Authentication

### Standard API endpoints

All `/api/v1/...` endpoints use your standard API key:

```bash theme={null}
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:

```bash theme={null}
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.

```bash theme={null}
curl https://api.dynamo-csms.com/ocpi/versions \
  -H "Authorization: Token YOUR_OCPI_TOKEN"
```

```json theme={null}
{
  "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.

<ParamField path="version" type="string" required>
  The OCPI version string, e.g., `"2.2.1"`.
</ParamField>

```bash theme={null}
curl https://api.dynamo-csms.com/ocpi/versions/2.2.1 \
  -H "Authorization: Token YOUR_OCPI_TOKEN"
```

```json theme={null}
{
  "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.

```bash theme={null}
curl https://api.dynamo-csms.com/ocpi/cpo/2.2.1/credentials \
  -H "Authorization: Token YOUR_OCPI_TOKEN"
```

```json theme={null}
{
  "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.

<ParamField body="token" type="string" required>
  The token the eMSP provided to you.
</ParamField>

<ParamField body="url" type="string" required>
  The eMSP's OCPI versions URL.
</ParamField>

<ParamField body="business_details" type="object" required>
  Details about the eMSP: `name`, `website`, and optional `logo`.
</ParamField>

<ParamField body="party_id" type="string" required>
  The eMSP's 3-character party identifier.
</ParamField>

<ParamField body="country_code" type="string" required>
  ISO 3166-1 alpha-2 country code for the eMSP.
</ParamField>

<ParamField body="roles" type="object[]" required>
  Array of role objects describing the eMSP's OCPI roles.
</ParamField>

```bash theme={null}
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.

<ParamField query="offset" type="number" default="0">
  Pagination offset.
</ParamField>

<ParamField query="limit" type="number" default="25">
  Number of locations to return per page (max 100).
</ParamField>

<ParamField query="date_from" type="string">
  Return only locations last updated after this ISO 8601 timestamp. Use for incremental sync.
</ParamField>

```bash theme={null}
curl "https://api.dynamo-csms.com/ocpi/cpo/2.2.1/locations?limit=10" \
  -H "Authorization: Token YOUR_OCPI_TOKEN"
```

```json theme={null}
{
  "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}`

<ParamField path="location_id" type="string" required>
  The location ID.
</ParamField>

### Get an EVSE

`GET /ocpi/cpo/2.2.1/locations/{location_id}/{evse_uid}`

<ParamField path="location_id" type="string" required>
  The location ID.
</ParamField>

<ParamField path="evse_uid" type="string" required>
  The EVSE UID.
</ParamField>

### Get a connector

`GET /ocpi/cpo/2.2.1/locations/{location_id}/{evse_uid}/{connector_id}`

<ParamField path="location_id" type="string" required>
  The location ID.
</ParamField>

<ParamField path="evse_uid" type="string" required>
  The EVSE UID.
</ParamField>

<ParamField path="connector_id" type="string" required>
  The connector ID.
</ParamField>

***

## 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.

<ParamField query="date_from" type="string">
  Return sessions started after this timestamp.
</ParamField>

<ParamField query="date_to" type="string">
  Return sessions started before this timestamp.
</ParamField>

<ParamField query="offset" type="number" default="0">
  Pagination offset.
</ParamField>

```bash theme={null}
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"
```

```json theme={null}
{
  "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.

<ParamField query="date_from" type="string">
  Return CDRs for sessions ending after this timestamp.
</ParamField>

<ParamField query="date_to" type="string">
  Return CDRs for sessions ending before this timestamp.
</ParamField>

```bash theme={null}
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"
```

```json theme={null}
{
  "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.

```bash theme={null}
curl https://api.dynamo-csms.com/ocpi/cpo/2.2.1/tariffs \
  -H "Authorization: Token YOUR_OCPI_TOKEN"
```

```json theme={null}
{
  "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}`

<ParamField path="command" type="string" required>
  The command to execute. One of: `START_SESSION`, `STOP_SESSION`, `RESERVE_NOW`, `UNLOCK_CONNECTOR`.
</ParamField>

```bash theme={null}
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"
  }'
```

```json theme={null}
{
  "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}`

<ParamField path="country_code" type="string" required>
  The eMSP's ISO 3166-1 alpha-2 country code.
</ParamField>

<ParamField path="party_id" type="string" required>
  The eMSP's 3-character party ID.
</ParamField>

<ParamField path="token_uid" type="string" required>
  The token UID (e.g., RFID card number).
</ParamField>

### 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.

```bash theme={null}
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.

```bash theme={null}
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.

<ParamField path="token_uid" type="string" required>
  The token UID to authorise.
</ParamField>

<ParamField query="type" type="string">
  Token type: `RFID`, `APP_USER`, `OTHER`, `AD_HOC_USER`. Defaults to `RFID`.
</ParamField>

```bash theme={null}
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"
```

```json theme={null}
{
  "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.

<ParamField body="charge_point_id" type="string" required>
  The charge point to start a guest session on.
</ParamField>

<ParamField body="connector_id" type="number" required>
  The connector number to start charging on.
</ParamField>

<ParamField body="payment_method_id" type="string" required>
  A tokenised payment method ID from your payment processor.
</ParamField>

```bash theme={null}
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"
  }'
```

```json theme={null}
{
  "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`

<ParamField path="session_token" type="string" required>
  The guest session token returned from the authorize call.
</ParamField>

```bash theme={null}
curl https://api.dynamo-csms.com/api/v1/sessions/guest/guest_tok_01HXJ2K1L0M9N8O7/status \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "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`

<ParamField path="session_token" type="string" required>
  The guest session token.
</ParamField>

Sends a `RemoteStopTransaction` command to the charge point and finalises the payment.

```bash theme={null}
curl -X POST https://api.dynamo-csms.com/api/v1/sessions/guest/guest_tok_01HXJ2K1L0M9N8O7/stop \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "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`.

<ParamField path="session_token" type="string" required>
  The guest session token.
</ParamField>

***

## 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`

<ParamField body="integration_type" type="string" required>
  Type of integration requested: `emsp`, `roaming_hub`, `payment`, `other`.
</ParamField>

<ParamField body="partner_name" type="string" required>
  Name of the partner or platform you want to connect.
</ParamField>

<ParamField body="description" type="string">
  Additional context about the use case and urgency.
</ParamField>

```bash theme={null}
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."
  }'
```

```json theme={null}
{
  "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.

```bash theme={null}
curl https://api.dynamo-csms.com/api/v1/integration-requests \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "data": [
    {
      "id": "ireq_01HXK3L2M1N0O9P8",
      "integration_type": "roaming_hub",
      "partner_name": "Hubject",
      "status": "in_review",
      "created_at": "2024-01-20T14:00:00Z"
    }
  ],
  "total": 1
}
```
