← Back to Blog2/19/2026

The Developer's Guide to OCPP 1.6J

A practical reference for developers building EV charging infrastructure with OCPP 1.6J (JSON over WebSocket).

Rohit Tiwari

Rohit Tiwari

@rohittiwari-dev
The Developer's Guide to OCPP 1.6J

OCPP 1.6J — Open Charge Point Protocol 1.6 (JSON over WebSocket)

Purpose: This file provides structured context about OCPP 1.6J for AI agents working on EV charging infrastructure. It is not a replacement for the official specification but a practical reference to ground AI-assisted development, integration, and troubleshooting.

Spec covered: OCPP 1.6 Edition 2 (2017-09-28), JSON over WebSocket transport

1. What is OCPP 1.6J?

OCPP 1.6 is the most widely deployed version of the Open Charge Point Protocol. It defines communication between a Charge Point and a Central System for managing EV charging infrastructure.

The "J" suffix denotes the JSON-over-WebSocket transport binding (as opposed to the SOAP/HTTP binding). JSON is the dominant transport for OCPP 1.6 in practice.

Edition 2 (published 2017-09-28) is the current revision. It clarified ambiguities from Edition 1 and is the edition referenced throughout this document.

The specification is maintained by the Open Charge Alliance (OCA).

2. Architecture

2.1 Roles

  • Charge Point (CP): The physical device that charges EVs. Initiates the WebSocket connection.
  • Central System (CS): The backend server that manages Charge Points remotely.

Important terminology note: OCPP 1.6 uses "Charge Point" and "Central System." The terms "Charging Station" and "CSMS" are OCPP 2.0.1 terms and do not apply to 1.6.

2.2 Connector Model

Charge Point → Connector 1 (e.g., Type 2), Connector 2 (e.g., CCS), ...

  • A Charge Point has one or more Connectors, each identified by a connectorId (1-indexed integer).
  • connectorId=0 refers to the Charge Point as a whole (used in messages like ChangeAvailability, StatusNotification, and MeterValues).
  • There is no EVSE concept in 1.6. The EVSE abstraction layer was introduced in OCPP 2.0.1.

2.3 Transport

  • WebSocket (RFC 6455), typically over TLS (wss://)
  • Sub-protocol: ocpp1.6
  • The Charge Point connects to the Central System at a URL like: wss://cs.example.com/ocpp/<charge_point_id>
  • The Charge Point ID is included in the WebSocket URL path.

2.4 Message Frame

OCPP 1.6J uses a JSON-RPC-like message framing. There are three message types:

CALL (Request):

[2, "<messageId>", "<action>", {<payload>}]

CALLRESULT (Response):

[3, "<messageId>", {<payload>}]

CALLERROR (Error Response):

[4, "<messageId>", "<errorCode>", "<errorDescription>", {<errorDetails>}]
  • messageId is a unique string that correlates a CALL with its CALLRESULT or CALLERROR.
  • Only one CALL can be outstanding at a time per direction (CP->CS or CS->CP).
  • Both sides can initiate CALLs independently since the connection is bidirectional.
  • Standard error codes: NotImplemented, NotSupported, InternalError, ProtocolError, SecurityError, FormationViolation, PropertyConstraintViolation, OccurenceConstraintViolation, TypeConstraintViolation, GenericError.

3. Feature Profiles

OCPP 1.6 organizes its 28 messages into 6 Feature Profiles. The Core profile is required; all others are optional. A Charge Point advertises its supported profiles via the SupportedFeatureProfiles configuration key.

ProfileRequiredMessages
CoreYesAuthorize, BootNotification, ChangeAvailability, ChangeConfiguration, ClearCache, DataTransfer, GetConfiguration, Heartbeat, MeterValues, RemoteStartTransaction, RemoteStopTransaction, Reset, StartTransaction, StatusNotification, StopTransaction, UnlockConnector
Firmware ManagementNoGetDiagnostics, DiagnosticsStatusNotification, UpdateFirmware, FirmwareStatusNotification
Local Auth List ManagementNoSendLocalList, GetLocalListVersion
ReservationNoReserveNow, CancelReservation
Smart ChargingNoSetChargingProfile, ClearChargingProfile, GetCompositeSchedule
Remote TriggerNoTriggerMessage

4. All 28 Messages

4.1 Core (16 messages)

MessageDirectionPurpose
AuthorizeCP->CSValidate an idTag before starting a transaction.
BootNotificationCP->CSSent on boot. Contains vendor, model, serial, firmware version. CS responds with Accepted, Pending, or Rejected and a heartbeat interval.
ChangeAvailabilityCS->CPSet a Connector (or entire CP) to Operative or Inoperative.
ChangeConfigurationCS->CPWrite a configuration key on the CP.
ClearCacheCS->CPClear the authorization cache.
DataTransferBothVendor-specific data exchange. Can be sent by either side. Uses vendorId and optional messageId.
GetConfigurationCS->CPRead configuration key(s) from the CP.
HeartbeatCP->CSPeriodic keepalive. CS responds with current time for clock sync.
MeterValuesCP->CSSend meter data for a Connector (outside or during a transaction).
RemoteStartTransactionCS->CPRemotely start a transaction on a Connector.
RemoteStopTransactionCS->CPRemotely stop a transaction by transactionId.
ResetCS->CPRestart the CP. Type: Hard or Soft.
StartTransactionCP->CSNotify CS that a transaction has started. Includes connectorId, idTag, meterStart, timestamp. CS returns transactionId.
StatusNotificationCP->CSReport the status of a Connector (or CP as a whole).
StopTransactionCP->CSNotify CS that a transaction has ended. Includes transactionId, meterStop, timestamp, reason, and optional transaction data (meter values).
UnlockConnectorCS->CPRemotely unlock a Connector.

4.2 Firmware Management (4 messages)

MessageDirectionPurpose
GetDiagnosticsCS->CPRequest CP to upload diagnostics file to a given URL.
DiagnosticsStatusNotificationCP->CSReport diagnostics upload status (Idle, Uploading, Uploaded, UploadFailed).
UpdateFirmwareCS->CPInstruct CP to download and install firmware from a given URL.
FirmwareStatusNotificationCP->CSReport firmware update progress (Downloaded, DownloadFailed, Downloading, Idle, InstallationFailed, Installing, Installed).

4.3 Local Auth List Management (2 messages)

MessageDirectionPurpose
SendLocalListCS->CPPush a local authorization list (full or differential update).
GetLocalListVersionCS->CPQuery the current version number of the local auth list.

4.4 Reservation (2 messages)

MessageDirectionPurpose
ReserveNowCS->CPReserve a Connector for a specific idTag until an expiry time.
CancelReservationCS->CPCancel an existing reservation by reservationId.

4.5 Smart Charging (3 messages)

MessageDirectionPurpose
SetChargingProfileCS->CPSet a charging profile (schedule of power/current limits) on a Connector.
ClearChargingProfileCS->CPRemove charging profiles by id, Connector, purpose, or stack level.
GetCompositeScheduleCS->CPRequest the effective combined charging schedule for a Connector.

4.6 Remote Trigger (1 message)

MessageDirectionPurpose
TriggerMessageCS->CPAsk CP to send a specific message (e.g., BootNotification, StatusNotification, Heartbeat, MeterValues, DiagnosticsStatusNotification, FirmwareStatusNotification).

4.7 Common Patterns

Boot Sequence

  1. CP→CS: [WebSocket connect]
  2. CP→CS: BootNotification.req(chargePointModel, chargePointVendor)
  3. CS→CP: BootNotification.conf(status=Accepted|Pending|Rejected, interval, currentTime)
  4. CP→CS: StatusNotification.req(connectorId=N, status, errorCode) [for each connector]
  5. CP→CS: Heartbeat.req() [every interval seconds]

If BootNotification.conf returns Pending, the CP must retry after the given interval and must not send any messages other than BootNotification until it receives Accepted. If Rejected, the CP should retry at the given interval.

Transaction Lifecycle (typical flow)

  1. User presents RFID -> CP sends Authorize.req with idTag
  2. CS responds Authorize.conf with idTagInfo.status=Accepted
  3. User plugs in cable -> CP sends StatusNotification (Preparing)
  4. CP sends StartTransaction.req (connectorId, idTag, meterStart, timestamp)
  5. CS responds StartTransaction.conf with transactionId and idTagInfo
  6. CP sends StatusNotification (Charging)
  7. During charging -> periodic MeterValues.req (every MeterValueSampleInterval seconds)
  8. User stops -> CP sends StopTransaction.req (transactionId, meterStop, timestamp, reason)
  9. CP sends StatusNotification (Finishing -> Available)

StopTransaction reasons: EmergencyStop, EVDisconnected, HardReset, Local, Other, PowerLoss, Reboot, Remote, SoftReset, UnlockCommand, DeAuthorized.

Smart Charging Profile Structure

{
  "connectorId": 1,
  "csChargingProfiles": {
    "chargingProfileId": 1,
    "stackLevel": 0,
    "chargingProfilePurpose": "TxDefaultProfile",
    "chargingProfileKind": "Recurring",
    "recurrencyKind": "Daily",
    "chargingSchedule": {
      "chargingRateUnit": "A",
      "chargingSchedulePeriod": [
        { "startPeriod": 0, "limit": 32.0 },
        { "startPeriod": 28800, "limit": 16.0 },
        { "startPeriod": 72000, "limit": 32.0 }
      ]
    }
  }
}

Profile purposes (stack priority, highest first):

  • ChargePointMaxProfile — Max power for the entire Charge Point (connectorId=0 only).
  • TxDefaultProfile — Default for transactions on a Connector.
  • TxProfile — Specific to an active transaction.

Profiles at the same purpose level use stackLevel to determine priority (higher wins).

Offline Behavior

When the CP loses connection to the CS:

  • It should queue transaction-related messages (StartTransaction, StopTransaction, MeterValues) and replay them in order upon reconnection.
  • TransactionMessageAttempts and TransactionMessageRetryInterval control retry behavior.
  • It can use the Local Authorization List or Authorization Cache for offline authorization.
  • LocalAuthorizeOffline enables transaction start for locally-known IDs.
  • AllowOfflineTxForUnknownId (when supported) enables transaction start for unknown IDs while offline.

5. Connector Status Model

The status of a Connector is reported via StatusNotification. OCPP 1.6 defines 9 statuses:

StatusDescription
AvailableConnector is available for a new user.
PreparingConnector is occupied but not yet charging (e.g., user authenticated, waiting for cable).
ChargingEV is connected and energy is actively being transferred.
SuspendedEVEV is connected, but the EV has suspended charging (e.g., battery management).
SuspendedEVSEEV is connected, but the EVSE (Charge Point) has suspended charging (e.g., smart charging limit).
FinishingTransaction has stopped, but Connector is not yet available (e.g., cable still plugged in).
ReservedConnector is reserved for a specific idTag.
UnavailableConnector is not available for charging (set via ChangeAvailability to Inoperative).
FaultedConnector is in an error state. A ChargePointErrorCode provides the specific error.

Historical note: OCPP 1.5 used a single Occupied status. In OCPP 1.6, this was split into the five statuses Preparing, Charging, SuspendedEV, SuspendedEVSE, and Finishing to provide more granular visibility into the charging session lifecycle.

Typical Status Flow

  • Normal flow: Available → Preparing → Charging → Finishing → Available
  • Suspend variations: Charging ↔ SuspendedEV, Charging ↔ SuspendedEVSE

A StatusNotification also carries a ChargePointErrorCode field. When the status is not Faulted, this is set to NoError. Error codes include: ConnectorLockFailure, EVCommunicationError, GroundFailure, HighTemperature, InternalError, LocalListConflict, OtherError, OverCurrentFailure, OverVoltage, PowerMeterFailure, PowerSwitchFailure, ReaderFailure, ResetFailure, UnderVoltage, WeakSignal.

6. Configuration Keys Reference

OCPP 1.6 uses a flat key-value configuration model accessed via GetConfiguration and ChangeConfiguration. Keys are grouped by Feature Profile.

6.1 Core Profile

KeyTypeR/RWRequiredDescription
AllowOfflineTxForUnknownIdbooleanRWNoEnable Unknown Offline Authorization.
AuthorizationCacheEnabledbooleanRWNoEnable the authorization cache.
AuthorizeRemoteTxRequestsbooleanR/RWYesWhether RemoteStartTransaction should be authorized first.
BlinkRepeatintegerRWNoNumber of times to blink CP lighting when signalling.
ClockAlignedDataIntervalinteger (s)RWYesInterval for clock-aligned meter data. 0 = disabled.
ConnectionTimeOutinteger (s)RWYesTimeout from Preparing status until transaction is cancelled.
ConnectorPhaseRotationCSLRWYesPhase rotation per connector (e.g., 0.RST, 1.RST, 2.RTS).
ConnectorPhaseRotationMaxLengthintegerRNoMax items in ConnectorPhaseRotation.
GetConfigurationMaxKeysintegerRYesMax keys in a GetConfiguration request.
HeartbeatIntervalinteger (s)RWYesInactivity interval before sending Heartbeat.
LightIntensityinteger (%)RWNoCP lighting intensity percentage.
LocalAuthorizeOfflinebooleanRWYesStart transactions for locally-authorized IDs when offline.
LocalPreAuthorizebooleanRWYesStart transactions for locally-authorized IDs without waiting for CS response.
MaxEnergyOnInvalidIdinteger (Wh)RWNoMax energy delivered after idTag is invalidated mid-transaction.
MeterValuesAlignedDataCSLRWYesClock-aligned measurands for MeterValues.
MeterValuesAlignedDataMaxLengthintegerRNoMax items in MeterValuesAlignedData.
MeterValuesSampledDataCSLRWYesSampled measurands for MeterValues. Default: Energy.Active.Import.Register.
MeterValuesSampledDataMaxLengthintegerRNoMax items in MeterValuesSampledData.
MeterValueSampleIntervalinteger (s)RWYesInterval between sampled meter values. 0 = disabled.
MinimumStatusDurationinteger (s)RWNoMin stable duration before sending StatusNotification.
NumberOfConnectorsintegerRYesNumber of physical connectors on this CP.
ResetRetriesintegerRWYesNumber of times to retry an unsuccessful reset.
StopTransactionOnEVSideDisconnectbooleanRWYesStop transaction when cable is unplugged from EV.
StopTransactionOnInvalidIdbooleanRWYesStop transaction on non-Accepted StartTransaction.conf.
StopTxnAlignedDataCSLRWYesClock-aligned measurands for StopTransaction.req transaction data.
StopTxnAlignedDataMaxLengthintegerRNoMax items in StopTxnAlignedData.
StopTxnSampledDataCSLRWYesSampled measurands for StopTransaction.req transaction data.
StopTxnSampledDataMaxLengthintegerRNoMax items in StopTxnSampledData.
SupportedFeatureProfilesCSLRYesSupported profiles (Core, FirmwareManagement, LocalAuthListManagement, Reservation, SmartCharging, RemoteTrigger).
SupportedFeatureProfilesMaxLengthintegerRNoMax items in SupportedFeatureProfiles.
TransactionMessageAttemptsintegerRWYesRetry count for transaction-related messages.
TransactionMessageRetryIntervalinteger (s)RWYesWait time between retries of transaction-related messages.
UnlockConnectorOnEVSideDisconnectbooleanRWYesUnlock cable on CP side when EV unplugs.
WebSocketPingIntervalinteger (s)RWNoWebSocket ping interval. 0 = disabled (server initiates).

6.2 Local Auth List Management Profile

KeyTypeR/RWRequiredDescription
LocalAuthListEnabledbooleanRWYesWhether the Local Authorization List is enabled.
LocalAuthListMaxLengthintegerRYesMax identifications in the Local Authorization List.
SendLocalListMaxLengthintegerRYesMax identifications in a single SendLocalList.req.

6.3 Reservation Profile

KeyTypeR/RWRequiredDescription
ReserveConnectorZeroSupportedbooleanRNoWhether reservations on connectorId=0 are supported.

6.4 Smart Charging Profile

KeyTypeR/RWRequiredDescription
ChargeProfileMaxStackLevelintegerRYesMax stackLevel of a ChargingProfile.
ChargingScheduleAllowedChargingRateUnitCSLRYesSupported rate units: Current, Power.
ChargingScheduleMaxPeriodsintegerRYesMax periods per ChargingSchedule.
ConnectorSwitch3to1PhaseSupportedbooleanRNoWhether 3-to-1 phase switching during a transaction is supported.
MaxChargingProfilesInstalledintegerRYesMax number of installed charging profiles.

7. Key Differences from OCPP 2.0.1

7.1 Terminology Mapping

OCPP 1.6OCPP 2.0.1
Charge PointCharging Station
Central SystemCSMS (Charging Station Management System)
Connector (connectorId)EVSE + Connector (evseId + connectorId)
connectorId=0 (whole Charge Point)evseId=0 (whole Charging Station)
idTag (CiString20Type, max 20 chars)IdTokenType (object with idToken + type)
StartTransaction / StopTransactionTransactionEvent (eventType: Started/Updated/Ended)
MeterValues (separate message)TransactionEvent (meter values embedded)
Feature ProfileFunctional Block
.req / .conf (message suffixes)Request / Response
GetConfiguration / ChangeConfigurationGetVariables / SetVariables
RemoteStartTransactionRequestStartTransaction
RemoteStopTransactionRequestStopTransaction
GetDiagnosticsGetLog
DiagnosticsStatusNotificationLogStatusNotification

7.2 Structural Differences

AspectOCPP 1.6OCPP 2.0.1
TransportSOAP or WebSocket + JSONWebSocket + JSON only
Device modelFlat (Charge Point -> Connectors)Hierarchical (Station -> EVSE -> Connector)
Transaction modelStartTransaction + MeterValues + StopTransactionUnified TransactionEvent
ConfigurationFlat key-value (GetConfiguration / ChangeConfiguration)Component/Variable model (GetVariables / SetVariables)
Smart Charging3 profile purposes, basic profiles4 purposes (adds external constraints), EV schedules
SecurityBasic Auth only, no certificate managementThree security profiles, certificate management, Plug & Charge
ISO 15118Not supportedPlug & Charge support
Display messagesNot supportedSetDisplayMessage, CostUpdated
Variable monitoringNot supportedSetVariableMonitoring, NotifyEvent
Message count28 messages64 messages