— Developer Tools

Free OCPP Message Validator

Paste OCPP-J frames or a whole charger log to check every CALL, CALLRESULT and CALLERROR against OCPP 1.6 or 2.0.1.

— Samples
Frames 5Problems 0Valid
Live

What is an OCPP Message Validator?

OCPP, the Open Charge Point Protocol, is how EV chargers talk to the systems that run them. Over WebSockets, every message is a small JSON array: a CALL, a CALLRESULT or a CALLERROR. This validator checks those frames against OCPP 1.6 or 2.0.1, the two versions most chargers and central systems in service today speak over their WebSocket connection.

It reads single frames or whole logs with timestamps, matches each result to its call by message ID, and checks payloads of the core messages against schemas written from the OCPP JSON schema files. Missing fields, unknown properties, wrong types, values outside the allowed lists, overlong strings and bad timestamps are reported by path. Frames for actions without a schema here still have their structure, message ID and error codes checked, so a whole log can be pasted without filtering it first.

Key Features

Frames Checked

CALL, CALLRESULT and CALLERROR structure, message ID length and CALLERROR codes per version.

Core Messages

BootNotification, Heartbeat, Authorize, transactions, status, meter values and DataTransfer.

Results Matched

Each CALLRESULT is checked against the response schema of the CALL with the same ID.

Problems by Path

Every problem names the field, such as chargingStation.model, and what’s wrong.

Logs Stay Local

Charger logs, including ID tags, are checked in your browser and never uploaded.

Perfect for everyone

  • Charger firmware engineers
  • CSMS developers
  • EV charging network operators
  • Roaming platform teams
  • Installers commissioning new sites and certification testers

How to Use the OCPP Message Validator

Pick the protocol version, then paste. The version matters because the same action name has a different payload in 1.6 and 2.0.1, so checking against the wrong one reports problems that aren’t there.

1

Choose the Version

OCPP 1.6 and 2.0.1 have different message shapes, so pick the one the charger speaks.

2

Paste Frames or a Log

One frame per line. Timestamps and arrows before the frame are ignored.

3

Read the Results

Each frame says whether its payload is valid, and lists any problems by path.

4

Check the Table

The table counts problems per frame, which helps in long logs.

Worked Examples

OCPP Frames, Checked

Each row is OCPP-J traffic as a central system logs it, and each answer is this validator’s output for the version on the chip. The charger and its vendor are fictional. Some rows are valid and some carry the mistakes integrators run into most, so you can see how each problem is reported.

REF_001A 1.6 central system log

“2026-10-28T09:00:00Z <- [2,"19223201","BootNotification",{"chargePointVendor":"VoltWorks","chargePointModel":"VW-22","firmwareVersion":"3.4.1"}] 2026-10-28T09:00:00Z -> [3,"19223201",{"status":"Accepted","currentTime":"2026-10-28T09:00:00Z","interval":300}] 2026-10-28T09:12:40Z <- [2,"19223202","StartTransaction",{"connectorId":1,"idTag":"04A3B2C1","meterStart":15200,"timestamp":"2026-10-28T09:12:40Z"}] 2026-10-28T09:12:40Z -> [3,"19223202",{"idTagInfo":{"status":"Accepted"},"transactionId":4471}] 2026-10-28T10:05:11Z <- [2,"19223203","StatusNotification",{"connectorId":1,"errorCode":"GroundFailure","status":"Faulted","timestamp":"2026-10-28T10:05:11Z"}]”

REF_002A valid 2.0.1 boot

“[2,"a1b2c3","BootNotification",{"chargingStation":{"model":"VW-22","vendorName":"VoltWorks"},"reason":"PowerUp"}]”

REF_003A 2.0.1 boot with two mistakes

“[2,"a1b2c3","BootNotification",{"chargingStation":{"vendorName":"VoltWorks"},"reason":"Startup"}]”

REF_004An undeclared property

“[2,"1","Heartbeat",{"now":true}]”

REF_005Wrong type, length and date

“[2,"1","StartTransaction",{"connectorId":"1","idTag":"012345678901234567890","meterStart":0,"timestamp":"yesterday"}]”

REF_006A CALLERROR

“[4,"19223204","NotImplemented","Requested Action is not known by receiver",{}]”

REF_007A 2.0.1 transaction start

“[2,"tx-1","TransactionEvent",{"eventType":"Started","timestamp":"2026-10-28T09:12:40Z","triggerReason":"Authorized","seqNo":0,"transactionInfo":{"transactionId":"f2c1e8","chargingState":"Charging"},"idToken":{"idToken":"04A3B2C1","type":"ISO14443"},"evse":{"id":1,"connectorId":1}}]”

REF_008An action without a schema here

“[2,"7","GetDiagnostics",{"location":"ftp://logs.example.com/"}]”

REF_009A result without its call

“[3,"999",{"currentTime":"2026-10-28T09:00:00Z"}]”

REF_010Cut-off JSON

“[2,"19223201","BootNotification",{"chargePointVendor":"VoltWorks"”

Core Messages

Messages You Will See Most

A charger’s day is a handful of messages repeated: it boots, sends heartbeats, authorises drivers, reports sessions and meter readings, and flags faults. These ten cover most logs.

01 / BOOTNOTIFICATION

BootNotification

The charger introduces itself after starting, with vendor and model.

“What must the response say for the charger to carry on?”

02 / HEARTBEAT

Heartbeat

A periodic ping that also returns the central system’s clock.

“Who sets the interval?”

03 / AUTHORIZE

Authorize

Asks whether an RFID card or other ID token may charge.

“What is the 1.6 field called?”

04 / STARTTRANSACTION

StartTransaction

OCPP 1.6: a session started, with connector, ID tag and meter start.

“What does the response assign?”

05 / STOPTRANSACTION

StopTransaction

OCPP 1.6: a session ended, with meter stop and a reason.

“Is a reason required?”

06 / TRANSACTIONEVENT

TransactionEvent

OCPP 2.0.1: one message for start, updates and end, with a sequence number.

“What are its event types?”

07 / STATUSNOTIFICATION

StatusNotification

A connector changed state, such as Available, Charging or Faulted.

“Which 1.6 field holds the fault?”

08 / METERVALUES

MeterValues

Readings such as energy, power and current, with timestamps.

“Is value a number in 1.6?”

09 / DATATRANSFER

DataTransfer

Vendor-specific data that the standard doesn’t cover.

“Which field is required?”

10 / CALLERROR

CALLERROR

The reply when a CALL can’t be processed, with a code and description.

“What does NotImplemented mean?”

How OCPP-J Frames Work

OCPP-J wraps every message in a JSON array sent over a WebSocket. The array’s shape tells the receiver what kind of message it is, which ID ties replies to requests, and where the payload sits. Every version of OCPP over JSON uses the same three shapes, so these rules hold for 1.6, 2.0.1 and 2.1 alike.

Message Type

The first item is 2 for a CALL, 3 for a CALLRESULT and 4 for a CALLERROR.

Message ID

A unique string up to 36 characters. The reply repeats it so the caller can match them.

Action

Only a CALL names its action. The reply’s schema follows from the call it answers.

Payload

A JSON object whose shape is fixed by the action and the OCPP version.

One Call at a Time

Each side may have only one CALL waiting for a reply, which keeps logs easy to follow.

Subprotocol

The WebSocket subprotocol, ocpp1.6 or ocpp2.0.1, decides which schemas apply.

OCPP 1.6 Versus 2.0.1

Both versions share the framing but differ in their messages. These are the changes that most often trip up a system being upgraded or one that speaks both versions. 2.0.1 isn’t backwards compatible, so a central system has to know which version each charger negotiated.

Tip 01

Transactions

1.6 uses StartTransaction and StopTransaction. 2.0.1 uses TransactionEvent for both and more.

Tip 02

Charging Station Model

2.0.1 nests vendor and model under chargingStation and requires a boot reason.

Tip 03

ID Tokens

1.6 has a plain idTag string. 2.0.1 has an idToken object with a type.

Tip 04

Connectors and EVSEs

2.0.1 addresses an EVSE and its connector, where 1.6 uses connectorId alone.

Tip 05

Status Values

2.0.1 replaces Preparing, Charging and Finishing with Occupied on the connector.

Tip 06

Meter Values

1.6 sends values as strings, 2.0.1 as numbers.

A Charging Session’s Status Changes

In OCPP 1.6 a connector reports its state with StatusNotification as a session goes on. Reading these in order is the quickest way to see where a session stalled, and the timestamps between them show how long each step took.

Available

The connector is free and ready. Sessions start and end here.

Preparing

A cable was plugged in or a card was presented, and the charger waits for the other.

Charging

Energy is flowing to the vehicle under an active transaction.

SuspendedEV and SuspendedEVSE

The car, or the charger, has paused charging, often because the battery is full or power is limited.

Finishing

The transaction stopped but the cable is still plugged in.

Faulted

Something is wrong. errorCode, info and vendorErrorCode say what.

Reading CALLERROR Codes

When a receiver can’t process a CALL, it answers with a CALLERROR. The code says which layer rejected the message, and the description and details usually say exactly why. Codes differ slightly between versions, which this validator checks for the version you pick.

Tip 01

NotImplemented

The receiver doesn’t know the action at all.

Tip 02

NotSupported

The action is known but this receiver doesn’t support it.

Tip 03

FormationViolation

The 1.6 code for a payload that doesn’t match the schema. 2.0.1 uses FormatViolation.

Tip 04

PropertyConstraintViolation

A field has a value outside what the schema allows, such as an unknown status.

Tip 05

TypeConstraintViolation

A field has the wrong type, such as a string where an integer belongs.

Tip 06

InternalError and GenericError

Something failed on the receiver’s side, so retrying later may work.

When to Validate OCPP

Whenever a charger and a central system disagree, the frames themselves are the evidence. Checking them against the schema settles which side broke the protocol.

Charger Integration

Find the field a new charger model sends wrongly before it reaches production.

Debugging Rejections

See why a central system answered with a FormationViolation or ignored a message.

Firmware Testing

Check every message after a firmware update against the protocol.

Migrating to 2.0.1

Compare frames from both versions while moving a fleet.

Learning OCPP

See what a valid message of each type looks like.

OCPP Pitfalls

Mistakes that break OCPP sessions, most of which a strict central system rejects with a CALLERROR while a lenient one silently ignores the bad field.

Tip 01

Numbers as Strings

connectorId must be an integer. "1" in quotes fails validation in strict systems.

Tip 02

Timestamps Without Zones

Use ISO 8601 with a zone, such as 2026-10-28T09:00:00Z.

Tip 03

Over-Long ID Tags

1.6 idTag allows 20 characters, which long UIDs can exceed.

Tip 04

Spelling in 1.6

The 1.6 error code is OccurenceConstraintViolation, misspelled in the standard itself.

Tip 05

Extra Properties

The schemas don’t allow undeclared fields. Vendor data belongs in DataTransfer.

Tip 06

Mixed Versions

Validating 1.6 frames as 2.0.1, or the reverse, reports problems that aren’t real.

Frequently Asked Questions