— Developer Tools

Free OCPI Message Viewer

Paste an OCPI object or API response to read it as plain lines and check it against OCPI 2.2.1.

— Samples
Objects 1Problems 0Valid
Live

What is an OCPI Message Viewer?

OCPI, the Open Charge Point Interface, is how charge point operators and eMobility providers share chargers, sessions, prices and billing for EV roaming. Its objects are JSON, but large and nested. This viewer turns them into readable lines and checks them.

It reads Locations, Sessions, CDRs, Tariffs and Tokens on their own or inside an API response, recognises each type from its fields, and checks it against schemas written from OCPI 2.2.1. Connector power, tariff prices and CDR durations are worked out, and locations are drawn on a map.

Key Features

Five Object Types

Locations, Sessions, CDRs, Tariffs and Tokens, recognised automatically.

Readable Summaries

Addresses, EVSE statuses, connector power in kW, energy, costs and prices per unit.

Schema Checks

Required fields, allowed values, string lengths and date-times from OCPI 2.2.1.

CDR Duration Check

total_time compared with the hours between start and end.

Locations on a Map

Coordinates are drawn on a map, and your JSON never leaves the browser.

Perfect for everyone

  • CPO and eMSP developers
  • Roaming hub integrators
  • EV charging operations teams and billing analysts

How to Use the OCPI Message Viewer

Paste an object or a response from an OCPI endpoint.

1

Copy the JSON

From a GET to a module endpoint, a push from a partner, or a log.

2

Paste or Open

Single objects, lists or full responses with status_code all work.

3

Read the Summary

Each object is described in plain lines, then checked against the schema.

4

See Every Field

Fields lists every path and value, useful for mapping to your own data.

Worked Examples

OCPI Objects, Read

Each row is OCPI JSON as an operator’s API returns it, and each answer is this viewer’s output in the mode on the chip. The operator and its site are fictional.

REF_001A two-charger location

“{ "country_code": "NL", "party_id": "VWK", "id": "LOC-0042", "publish": true, "name": "Prinsengracht Hub", "address": "Prinsengracht 263", "city": "Amsterdam", "postal_code": "1016 GV", "country": "NLD", "coordinates": { "latitude": "52.375270", "longitude": "4.883950" }, "time_zone": "Europe/Amsterdam", "evses": [ { "uid": "EVSE-1", "evse_id": "NL*VWK*E0042*1", "status": "CHARGING", "connectors": [ { "id": "1", "standard": "IEC_62196_T2", "format": "SOCKET", "power_type": "AC_3_PHASE", "max_voltage": 230, "max_amperage": 32, "last_updated": "2026-10-28T09:12:40Z" } ], "last_updated": "2026-10-28T09:12:40Z" }, { "uid": "EVSE-2", "evse_id": "NL*VWK*E0042*2", "status": "AVAILABLE", "connectors": [ { "id": "1", "standard": "IEC_62196_T2_COMBO", "format": "CABLE", "power_type": "DC", "max_voltage": 920, "max_amperage": 200, "max_electric_power": 150000, "last_updated": "2026-10-28T08:00:00Z" } ], "last_updated": "2026-10-28T08:00:00Z" } ], "last_updated": "2026-10-28T09:12:40Z" }”

REF_002A session in a response envelope

“{ "data": { "country_code": "NL", "party_id": "VWK", "id": "SES-7781", "start_date_time": "2026-10-28T09:12:40Z", "kwh": 11.42, "cdr_token": { "uid": "04A3B2C1", "type": "RFID", "contract_id": "NL-ACM-C12345678-X" }, "auth_method": "WHITELIST", "location_id": "LOC-0042", "evse_uid": "EVSE-1", "connector_id": "1", "currency": "EUR", "total_cost": { "excl_vat": 3.43, "incl_vat": 4.15 }, "status": "ACTIVE", "last_updated": "2026-10-28T09:42:40Z" }, "status_code": 1000, "status_message": "Success", "timestamp": "2026-10-28T09:42:41Z" }”

REF_003A charge detail record

“{ "country_code": "NL", "party_id": "VWK", "id": "CDR-7781", "start_date_time": "2026-10-28T09:12:40Z", "end_date_time": "2026-10-28T10:42:40Z", "cdr_token": { "uid": "04A3B2C1", "type": "RFID", "contract_id": "NL-ACM-C12345678-X" }, "auth_method": "WHITELIST", "cdr_location": { "id": "LOC-0042", "address": "Prinsengracht 263", "city": "Amsterdam", "country": "NLD", "evse_uid": "EVSE-1", "evse_id": "NL*VWK*E0042*1", "connector_id": "1", "connector_standard": "IEC_62196_T2", "connector_format": "SOCKET", "connector_power_type": "AC_3_PHASE" }, "currency": "EUR", "charging_periods": [ { "start_date_time": "2026-10-28T09:12:40Z", "dimensions": [ { "type": "ENERGY", "volume": 18.2 } ] } ], "total_cost": { "excl_vat": 5.46, "incl_vat": 6.61 }, "total_energy": 18.2, "total_time": 1.5, "last_updated": "2026-10-28T10:45:00Z" }”

REF_004A tariff with energy and parking prices

“{ "country_code": "NL", "party_id": "VWK", "id": "TAR-AC", "currency": "EUR", "elements": [ { "price_components": [ { "type": "ENERGY", "price": 0.3, "vat": 21, "step_size": 1 }, { "type": "PARKING_TIME", "price": 2, "vat": 21, "step_size": 300 } ] } ], "last_updated": "2026-10-01T00:00:00Z" }”

REF_005A CDR with two mistakes

“{ "country_code": "NLD", "party_id": "VWK", "id": "CDR-7781", "start_date_time": "2026-10-28T09:12:40Z", "end_date_time": "2026-10-28T10:42:40Z", "cdr_token": { "uid": "04A3B2C1", "type": "RFID", "contract_id": "NL-ACM-C12345678-X" }, "auth_method": "RFID", "cdr_location": { "id": "LOC-0042", "address": "Prinsengracht 263", "city": "Amsterdam", "country": "NLD", "evse_uid": "EVSE-1", "evse_id": "NL*VWK*E0042*1", "connector_id": "1", "connector_standard": "IEC_62196_T2", "connector_format": "SOCKET", "connector_power_type": "AC_3_PHASE" }, "currency": "EUR", "charging_periods": [ { "start_date_time": "2026-10-28T09:12:40Z", "dimensions": [ { "type": "ENERGY", "volume": 18.2 } ] } ], "total_cost": { "excl_vat": 5.46, "incl_vat": 6.61 }, "total_energy": 18.2, "total_time": 1.5, "last_updated": "2026-10-28T10:45:00Z" }”

REF_006The tariff as field paths

“{ "country_code": "NL", "party_id": "VWK", "id": "TAR-AC", "currency": "EUR", "elements": [ { "price_components": [ { "type": "ENERGY", "price": 0.3, "vat": 21, "step_size": 1 }, { "type": "PARKING_TIME", "price": 2, "vat": 21, "step_size": 300 } ] } ], "last_updated": "2026-10-01T00:00:00Z" }”

REF_007Two tokens in one response

“{ "data": [ { "country_code": "NL", "party_id": "ACM", "uid": "04A3B2C1", "type": "RFID", "contract_id": "NL-ACM-C12345678-X", "issuer": "Acme Mobility", "valid": true, "whitelist": "ALLOWED", "last_updated": "2026-10-01T00:00:00Z" }, { "country_code": "NL", "party_id": "ACM", "uid": "APP-99812", "type": "APP_USER", "contract_id": "NL-ACM-C87654321-Y", "issuer": "Acme Mobility", "valid": false, "whitelist": "NEVER", "last_updated": "2026-10-20T12:00:00Z" } ], "status_code": 1000, "status_message": "Success", "timestamp": "2026-10-28T09:00:00Z" }”

REF_008A CDR whose total_time is off

“{ "country_code": "NL", "party_id": "VWK", "id": "CDR-7781", "start_date_time": "2026-10-28T09:12:40Z", "end_date_time": "2026-10-28T10:42:40Z", "cdr_token": { "uid": "04A3B2C1", "type": "RFID", "contract_id": "NL-ACM-C12345678-X" }, "auth_method": "WHITELIST", "cdr_location": { "id": "LOC-0042", "address": "Prinsengracht 263", "city": "Amsterdam", "country": "NLD", "evse_uid": "EVSE-1", "evse_id": "NL*VWK*E0042*1", "connector_id": "1", "connector_standard": "IEC_62196_T2", "connector_format": "SOCKET", "connector_power_type": "AC_3_PHASE" }, "currency": "EUR", "charging_periods": [ { "start_date_time": "2026-10-28T09:12:40Z", "dimensions": [ { "type": "ENERGY", "volume": 18.2 } ] } ], "total_cost": { "excl_vat": 5.46, "incl_vat": 6.61 }, "total_energy": 18.2, "total_time": 2, "last_updated": "2026-10-28T10:45:00Z" }”

REF_009An object OCPI doesn’t define

“{ "id": "X-1", "colour": "green" }”

REF_010Cut-off JSON

“{"id": "LOC-1", "evses": [”

OCPI Modules

The Objects OCPI Exchanges

OCPI splits roaming into modules, each with its own object. These ten facts cover the ones this viewer reads.

01 / LOCATION

Location

A charging site with its address, coordinates, EVSEs and connectors.

“Which party publishes locations?”

02 / EVSE

EVSE

One charging point inside a location, with a status and connectors.

“Can an EVSE have several connectors?”

03 / CONNECTOR

Connector

A socket or cable with its standard, power type, voltage and amperage.

“What is IEC_62196_T2?”

04 / SESSION

Session

A charging session in progress, with energy and running cost.

“Which status means charging now?”

05 / CDR

CDR

The charge detail record sent when a session ends, used for billing.

“Can a CDR be changed?”

06 / TARIFF

Tariff

Prices for energy, time, parking or a flat fee, with step sizes.

“What is the energy step size unit?”

07 / TOKEN

Token

A driver’s RFID card or app account, issued by an eMSP.

“Which party issues tokens?”

08 / PARTY

Party IDs

country_code and party_id identify the company, as in NL*VWK.

“How long is party_id?”

09 / LASTUPDATED

last_updated

Every object carries the time it last changed, for incremental syncing.

“Which format is used?”

10 / RESPONSE

Response Envelope

Every API response wraps data with status_code, message and timestamp.

“Which status_code means success?”

Working Out Connector Power

OCPI gives voltage and amperage rather than kilowatts, so power has to be worked out. These rules are what the summary uses, and they explain figures on charge maps.

Single-Phase AC

Power is voltage times amperage: 230 V × 32 A is 7.4 kW.

Three-Phase AC

Voltage is line to neutral, so multiply by three: 230 V × 32 A × 3 is 22.1 kW.

DC

Power is voltage times amperage, often capped by max_electric_power.

max_electric_power

When given, this watt figure is the real limit and is used directly.

What the Car Takes

The car’s own limits decide the actual rate, often well below the connector’s.

Reading an OCPI Tariff

Tariffs are the part of OCPI that causes the most billing disputes. These points explain how price components and step sizes add up to what a driver pays.

Tip 01

Price Components

Each element lists components of type ENERGY, TIME, PARKING_TIME or FLAT.

Tip 02

Prices Exclude VAT

Component prices are excluding VAT, with vat giving the percentage.

Tip 03

Energy Step Size

Step size for ENERGY is in Wh, so 1 means billing to the watt-hour.

Tip 04

Time Step Size

Step size for TIME and PARKING_TIME is in seconds, so 300 means 5-minute blocks.

Tip 05

Restrictions

An element can apply only at certain times, days or energy levels.

Tip 06

Order Matters

The first element whose restrictions match applies to each part of the session.

When to Read OCPI

Whenever roaming data needs checking by eye.

Roaming Onboarding

Check a new partner’s objects against OCPI 2.2.1 before going live.

Billing Disputes

Read a CDR and its tariff side by side to explain a driver’s bill.

Location Data Quality

Find missing coordinates, bad statuses and connector power on a site.

Debugging Pushes

See why a partner rejected a session or CDR you pushed.

Learning OCPI

See how locations, sessions, CDRs and tariffs fit together.

OCPI Pitfalls

Mistakes that break roaming integrations.

Tip 01

Coordinates as Numbers

Latitude and longitude are strings with five to seven decimals, not numbers.

Tip 02

Three-Letter Party Codes

country_code is two letters and party_id three. NLD belongs in country, not country_code.

Tip 03

Times Without a Zone

Use UTC with a Z, as in 2026-10-28T09:12:40Z.

Tip 04

Changing CDRs

CDRs are final. Correct one by sending a credit CDR, not by updating it.

Tip 05

Version Mix-Ups

2.1.1 and 2.2.1 objects differ, so check the version endpoint.

Tip 06

Tariff Step Sizes

Mixing up Wh and seconds in step_size changes the bill by a large factor.

Frequently Asked Questions