Skip to content

The OCPP 1.6J protocol reference.

What a charger and its back office say to each other: all 28 messages with their fields and an example, the 43 configuration keys, what a charger can measure and what goes wrong in practice.

MessagesConfiguration keysMeasurandsQuestions

What is OCPP 1.6J?

OCPP, the Open Charge Point Protocol, is a free and open standard of the Open Charge Alliance. It sets how a charger talks to the software that manages it: the Central System in the specification, the back office in the market.

In version 1.6J the charger opens a WebSocket to the back office, and both sides send JSON messages over it. The charger reports its status, its meter values and its sessions. The back office starts and stops sessions, changes settings and sets charging limits.

Because the standard is open, a charger that speaks it can also connect to other back offices that do, depending on model, firmware and configuration. That is what lets you mix brands on one site and move a charger to another back office. To run one charger on several back offices at the same time, use the OCPP proxy.

  • An open standardFree to implement, maintained by the Open Charge Alliance.
  • WebSocket and JSONOne connection that stays open, with structured messages.
  • 28 messagesIn six feature profiles, from Core to Remote Trigger.
  • Both directionsThe charger and the back office each start their own messages.

All 28 OCPP 1.6 messages

Every message is a request from one side and a response from the other, matched by a unique message ID.

Core

Required. Fundamental charge point operations: authorization, transactions, status reporting, configuration, and basic remote control.

Requests authorization for an idTag before allowing charging.

Request
FieldTypeUseWhat it holds
idTagstringRequiredThe identifier to authorize. At most 20 characters.
Response
FieldTypeUseWhat it holds
idTagInfoobjectRequiredAuthorization information for the idTag.
statusstringRequiredAuthorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx.
expiryDatestringOptionalDate/time after which the idTag should be considered expired. A date and time.
parentIdTagstringOptionalParent idTag for group authorization. At most 20 characters.
Example
The charger sends
[2, "7f83df9c", "Authorize", {
  "idTag": "04A2B3C4D5E6F7"
}]
The back office answers
[3, "7f83df9c", {
  "idTagInfo": {
    "status": "Accepted"
  }
}]

In OCPP 2.0.1: Authorize

Sent after startup to register with the back office.

Request
FieldTypeUseWhat it holds
chargePointVendorstringRequiredVendor of the charge point. At most 20 characters.
chargePointModelstringRequiredModel of the charge point. At most 20 characters.
chargePointSerialNumberstringOptionalSerial number of the charge point. At most 25 characters.
chargeBoxSerialNumberstringOptionalSerial number of the charge box. At most 25 characters.
firmwareVersionstringOptionalFirmware version of the charge point. At most 50 characters.
iccidstringOptionalICCID of the SIM card. At most 20 characters.
imsistringOptionalIMSI of the SIM card. At most 20 characters.
meterTypestringOptionalType of the energy meter. At most 25 characters.
meterSerialNumberstringOptionalSerial number of the energy meter. At most 25 characters.
Response
FieldTypeUseWhat it holds
statusstringRequiredRegistration status. One of Accepted, Pending, Rejected.
currentTimestringRequiredCurrent time of the Central System. A date and time.
intervalintegerRequiredHeartbeat interval in seconds.
Example
The charger sends
[2, "392b5b40", "BootNotification", {
  "chargePointVendor": "ExampleVendor",
  "chargePointModel": "ExampleModel",
  "firmwareVersion": "1.4.2"
}]
The back office answers
[3, "392b5b40", {
  "status": "Accepted",
  "currentTime": "2026-10-06T09:30:00Z",
  "interval": 300
}]

In OCPP 2.0.1: BootNotification

Changes availability of a connector.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredID of the connector (0 = entire charge point).
typestringRequiredRequested availability change. One of Inoperative, Operative.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the availability change request. One of Accepted, Rejected, Scheduled.
Example
The back office sends
[2, "be3dcf2e", "ChangeAvailability", {
  "connectorId": 1,
  "type": "Operative"
}]
The charger answers
[3, "be3dcf2e", {
  "status": "Accepted"
}]

In OCPP 2.0.1: ChangeAvailability

Changes a configuration key on the charger.

Request
FieldTypeUseWhat it holds
keystringRequiredConfiguration key to change. At most 50 characters.
valuestringRequiredNew value for the configuration key. At most 500 characters.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the configuration change. One of Accepted, Rejected, RebootRequired, NotSupported.
Example
The back office sends
[2, "6fdf2255", "ChangeConfiguration", {
  "key": "MeterValueSampleInterval",
  "value": "60"
}]
The charger answers
[3, "6fdf2255", {
  "status": "Accepted"
}]

In OCPP 2.0.1: SetVariables

Clears the authorization cache on the charger.

Request

No fields: the request is empty.

Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the cache clear request. One of Accepted, Rejected.
Example
The back office sends
[2, "e993e844", "ClearCache", {}]
The charger answers
[3, "e993e844", {
  "status": "Accepted"
}]

In OCPP 2.0.1: ClearCache

Vendor-specific data exchange.

Request
FieldTypeUseWhat it holds
vendorIdstringRequiredIdentifies the vendor. At most 255 characters.
messageIdstringOptionalAdditional identification of the message. At most 50 characters.
datastringOptionalVendor-specific data.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the data transfer. One of Accepted, Rejected, UnknownMessageId, UnknownVendorId.
datastringOptionalVendor-specific response data.
Example
One side sends
[2, "e1a403d5", "DataTransfer", {
  "vendorId": "com.example"
}]
The other side answers
[3, "e1a403d5", {
  "status": "Accepted"
}]

In OCPP 2.0.1: DataTransfer

Retrieves configuration keys from the charger.

Request
FieldTypeUseWhat it holds
keyarrayOptionalList of configuration keys to retrieve. items At most 50 characters.
Response
FieldTypeUseWhat it holds
configurationKeyarrayOptionalList of known configuration keys.
keystringRequiredConfiguration key name. At most 50 characters.
readonlybooleanRequiredWhether the key is read-only.
valuestringOptionalCurrent value of the key. At most 500 characters.
unknownKeyarrayOptionalList of requested keys that are unknown. items At most 50 characters.
Example
The back office sends
[2, "02bd00f5", "GetConfiguration", {
  "key": [
    "MeterValueSampleInterval"
  ]
}]
The charger answers
[3, "02bd00f5", {
  "configurationKey": [
    {
      "key": "MeterValueSampleInterval",
      "readonly": false,
      "value": "60"
    }
  ]
}]

In OCPP 2.0.1: GetBaseReport and GetVariables

Periodic keep-alive to let the back office know the charger is online.

Request

No fields: the request is empty.

Response
FieldTypeUseWhat it holds
currentTimestringRequiredCurrent time of the Central System. A date and time.
Example
The charger sends
[2, "83622997", "Heartbeat", {}]
The back office answers
[3, "83622997", {
  "currentTime": "2026-10-06T09:30:00Z"
}]

In OCPP 2.0.1: Heartbeat

Sends periodic or triggered meter readings.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredID of the connector (0 = main meter).
meterValuearrayRequiredOne or more meter values with timestamps.
timestampstringRequiredTimestamp of the meter value. A date and time.
sampledValuearrayRequiredOne or more sampled values.
valuestringRequiredThe measured value.
contextstringOptionalReading context. One of Interruption.Begin, Interruption.End, Sample.Clock, Sample.Periodic, Transaction.Begin, Transaction.End, Trigger, Other.
formatstringOptionalValue format. One of Raw, SignedData.
measurandstringOptionalType of measurement. One of Energy.Active.Export.Register, Energy.Active.Import.Register, Energy.Reactive.Export.Register, Energy.Reactive.Import.Register, Energy.Active.Export.Interval, Energy.Active.Import.Interval, Energy.Reactive.Export.Interval, Energy.Reactive.Import.Interval, Power.Active.Export, Power.Active.Import, Power.Offered, Power.Reactive.Export, Power.Reactive.Import, Power.Factor, Current.Import, Current.Export, Current.Offered, Voltage, Frequency, Temperature, SoC, RPM.
phasestringOptionalPhase to which the measurement applies. One of L1, L2, L3, N, L1-N, L2-N, L3-N, L1-L2, L2-L3, L3-L1.
locationstringOptionalLocation of measurement. One of Cable, EV, Inlet, Outlet, Body.
unitstringOptionalUnit of measurement. One of Wh, kWh, varh, kvarh, W, kW, VA, kVA, var, kvar, A, V, K, Celcius, Celsius, Fahrenheit, Percent.
transactionIdintegerOptionalTransaction to which these meter values apply.
Response

No fields: the response is empty.

Example
The charger sends
[2, "80a15023", "MeterValues", {
  "connectorId": 1,
  "meterValue": [
    {
      "timestamp": "2026-10-06T09:30:00Z",
      "sampledValue": [
        {
          "value": "19840",
          "measurand": "Energy.Active.Import.Register",
          "unit": "Wh"
        }
      ]
    }
  ],
  "transactionId": 4521
}]
The back office answers
[3, "80a15023", {}]

In OCPP 2.0.1: MeterValues

Remotely starts a charging session.

Request
FieldTypeUseWhat it holds
idTagstringRequiredThe identifier to use for this session. At most 20 characters.
connectorIdintegerOptionalConnector on which to start.
chargingProfileobjectOptionalCharging profile to apply to this session.
chargingProfileIdintegerRequiredUnique identifier of this charging profile.
stackLevelintegerRequiredPriority level of the profile (higher = higher priority).
chargingProfilePurposestringRequiredPurpose of the charging profile. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile.
chargingProfileKindstringRequiredKind of schedule. One of Absolute, Recurring, Relative.
chargingScheduleobjectRequiredThe charging schedule.
chargingRateUnitstringRequiredUnit of the charging rate (amps or watts). One of A, W.
chargingSchedulePeriodarrayRequiredList of schedule periods.
startPeriodintegerRequiredStart of the period in seconds from the schedule start.
limitnumberRequiredPower or current limit during this period. In steps of 0.1.
numberPhasesintegerOptionalNumber of phases to use for charging.
durationintegerOptionalDuration of the schedule in seconds.
startSchedulestringOptionalStart date/time of the schedule. A date and time.
minChargingRatenumberOptionalMinimum charging rate supported. In steps of 0.1.
transactionIdintegerOptionalTransaction to which this profile applies.
recurrencyKindstringOptionalRecurrence frequency for recurring profiles. One of Daily, Weekly.
validFromstringOptionalDate/time from which the profile is valid. A date and time.
validTostringOptionalDate/time after which the profile is no longer valid. A date and time.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the charge point accepted the request. One of Accepted, Rejected.
Example
The back office sends
[2, "b7e2ef8a", "RemoteStartTransaction", {
  "idTag": "04A2B3C4D5E6F7",
  "connectorId": 1
}]
The charger answers
[3, "b7e2ef8a", {
  "status": "Accepted"
}]

In OCPP 2.0.1: RequestStartTransaction

Remotely stops a charging session.

Request
FieldTypeUseWhat it holds
transactionIdintegerRequiredID of the transaction to stop.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the charge point accepted the request. One of Accepted, Rejected.
Example
The back office sends
[2, "7fb0afb2", "RemoteStopTransaction", {
  "transactionId": 4521
}]
The charger answers
[3, "7fb0afb2", {
  "status": "Accepted"
}]

In OCPP 2.0.1: RequestStopTransaction

Resets the charge point (hard or soft).

Request
FieldTypeUseWhat it holds
typestringRequiredType of reset to perform. One of Hard, Soft.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the charge point accepted the reset. One of Accepted, Rejected.
Example
The back office sends
[2, "526d688f", "Reset", {
  "type": "Soft"
}]
The charger answers
[3, "526d688f", {
  "status": "Accepted"
}]

In OCPP 2.0.1: Reset

Notifies the back office that a charging session has started.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector on which the transaction started.
idTagstringRequiredIdentifier used to start the transaction. At most 20 characters.
meterStartintegerRequiredMeter value at start of transaction (Wh).
timestampstringRequiredTimestamp when the transaction started. A date and time.
reservationIdintegerOptionalID of the reservation that was used.
Response
FieldTypeUseWhat it holds
idTagInfoobjectRequiredAuthorization information for the idTag.
statusstringRequiredAuthorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx.
expiryDatestringOptionalDate/time after which the idTag should be considered expired. A date and time.
parentIdTagstringOptionalParent idTag for group authorization. At most 20 characters.
transactionIdintegerRequiredTransaction ID assigned by the Central System.
Example
The charger sends
[2, "2410a6a5", "StartTransaction", {
  "connectorId": 1,
  "idTag": "04A2B3C4D5E6F7",
  "meterStart": 12500,
  "timestamp": "2026-10-06T09:30:00Z"
}]
The back office answers
[3, "2410a6a5", {
  "idTagInfo": {
    "status": "Accepted"
  },
  "transactionId": 4521
}]

In OCPP 2.0.1: TransactionEvent

Reports the current status and any errors of a connector.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector for which the status is reported.
errorCodestringRequiredError code (NoError if no error). One of ConnectorLockFailure, EVCommunicationError, GroundFailure, HighTemperature, InternalError, LocalListConflict, NoError, OtherError, OverCurrentFailure, PowerMeterFailure, PowerSwitchFailure, ReaderFailure, ResetFailure, UnderVoltage, OverVoltage, WeakSignal.
statusstringRequiredCurrent status of the connector. One of Available, Preparing, Charging, SuspendedEVSE, SuspendedEV, Finishing, Reserved, Unavailable, Faulted.
infostringOptionalAdditional free-text info about the status. At most 50 characters.
timestampstringOptionalTimestamp of the status change. A date and time.
vendorIdstringOptionalVendor-specific identifier. At most 255 characters.
vendorErrorCodestringOptionalVendor-specific error code. At most 50 characters.
Response

No fields: the response is empty.

Example
The charger sends
[2, "d9b0420e", "StatusNotification", {
  "connectorId": 1,
  "errorCode": "NoError",
  "status": "Available"
}]
The back office answers
[3, "d9b0420e", {}]

In OCPP 2.0.1: StatusNotification

Notifies the back office that a charging session has stopped.

Request
FieldTypeUseWhat it holds
transactionIdintegerRequiredID of the transaction being stopped.
timestampstringRequiredTimestamp when the transaction stopped. A date and time.
meterStopintegerRequiredMeter value at end of transaction (Wh).
idTagstringOptionalIdentifier that requested the stop. At most 20 characters.
reasonstringOptionalReason for stopping the transaction. One of EmergencyStop, EVDisconnected, HardReset, Local, Other, PowerLoss, Reboot, Remote, SoftReset, UnlockCommand, DeAuthorized.
transactionDataarrayOptionalArray of MeterValue objects (same structure as MeterValues.meterValue).
timestampstringRequiredTimestamp of the meter value. A date and time.
sampledValuearrayRequiredOne or more sampled values.
valuestringRequiredThe measured value.
contextstringOptionalReading context. One of Interruption.Begin, Interruption.End, Sample.Clock, Sample.Periodic, Transaction.Begin, Transaction.End, Trigger, Other.
formatstringOptionalValue format. One of Raw, SignedData.
measurandstringOptionalType of measurement. One of Energy.Active.Export.Register, Energy.Active.Import.Register, Energy.Reactive.Export.Register, Energy.Reactive.Import.Register, Energy.Active.Export.Interval, Energy.Active.Import.Interval, Energy.Reactive.Export.Interval, Energy.Reactive.Import.Interval, Power.Active.Export, Power.Active.Import, Power.Offered, Power.Reactive.Export, Power.Reactive.Import, Power.Factor, Current.Import, Current.Export, Current.Offered, Voltage, Frequency, Temperature, SoC, RPM.
phasestringOptionalPhase to which the measurement applies. One of L1, L2, L3, N, L1-N, L2-N, L3-N, L1-L2, L2-L3, L3-L1.
locationstringOptionalLocation of measurement. One of Cable, EV, Inlet, Outlet, Body.
unitstringOptionalUnit of measurement. One of Wh, kWh, varh, kvarh, W, kW, VA, kVA, var, kvar, A, V, K, Celcius, Celsius, Fahrenheit, Percent.
Response
FieldTypeUseWhat it holds
idTagInfoobjectOptionalAuthorization information for the idTag.
statusstringRequiredAuthorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx.
expiryDatestringOptionalDate/time after which the idTag should be considered expired. A date and time.
parentIdTagstringOptionalParent idTag for group authorization. At most 20 characters.
Example
The charger sends
[2, "b380dc07", "StopTransaction", {
  "transactionId": 4521,
  "timestamp": "2026-10-06T09:30:00Z",
  "meterStop": 19840,
  "idTag": "04A2B3C4D5E6F7"
}]
The back office answers
[3, "b380dc07", {
  "idTagInfo": {
    "status": "Accepted"
  }
}]

In OCPP 2.0.1: TransactionEvent

Remotely unlocks a connector.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector to unlock.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the unlock request. One of Unlocked, UnlockFailed, NotSupported.
Example
The back office sends
[2, "882ccab0", "UnlockConnector", {
  "connectorId": 1
}]
The charger answers
[3, "882ccab0", {
  "status": "Unlocked"
}]

In OCPP 2.0.1: UnlockConnector

Firmware management

Firmware updates and diagnostics upload for remote maintenance of charge points.

Requests the charger to upload diagnostic logs.

Request
FieldTypeUseWhat it holds
locationstringRequiredURI where diagnostics should be uploaded. An address (URI).
retriesintegerOptionalNumber of retries for uploading.
retryIntervalintegerOptionalSeconds between retry attempts.
startTimestringOptionalStart of the time range for log collection. A date and time.
stopTimestringOptionalEnd of the time range for log collection. A date and time.
Response
FieldTypeUseWhat it holds
fileNamestringOptionalName of the diagnostics file. At most 255 characters.
Example
The back office sends
[2, "da7920cd", "GetDiagnostics", {
  "location": "ftp://files.example.com/diagnostics/"
}]
The charger answers
[3, "da7920cd", {}]

In OCPP 2.0.1: GetLog

Reports the status of a diagnostics upload.

Request
FieldTypeUseWhat it holds
statusstringRequiredCurrent status of the diagnostics upload. One of Idle, Uploaded, UploadFailed, Uploading.
Response

No fields: the response is empty.

Example
The charger sends
[2, "d1c853b4", "DiagnosticsStatusNotification", {
  "status": "Uploaded"
}]
The back office answers
[3, "d1c853b4", {}]

In OCPP 2.0.1: LogStatusNotification

Reports the status of a firmware update.

Request
FieldTypeUseWhat it holds
statusstringRequiredCurrent status of the firmware update. One of Downloaded, DownloadFailed, Downloading, Idle, InstallationFailed, Installing, Installed.
Response

No fields: the response is empty.

Example
The charger sends
[2, "dc9afcb2", "FirmwareStatusNotification", {
  "status": "Installed"
}]
The back office answers
[3, "dc9afcb2", {}]

In OCPP 2.0.1: FirmwareStatusNotification

Instructs the charger to download and install new firmware.

Request
FieldTypeUseWhat it holds
locationstringRequiredURI where the firmware can be downloaded. An address (URI).
retrieveDatestringRequiredDate/time after which the charger should retrieve the firmware. A date and time.
retriesintegerOptionalNumber of retries for downloading.
retryIntervalintegerOptionalSeconds between retry attempts.
Response

No fields: the response is empty.

Example
The back office sends
[2, "a57cc6a2", "UpdateFirmware", {
  "location": "ftp://files.example.com/fw-1.4.3.bin",
  "retrieveDate": "2026-10-07T02:00:00Z"
}]
The charger answers
[3, "a57cc6a2", {}]

In OCPP 2.0.1: UpdateFirmware

Local authorization list

Manage a local authorization list on the charge point for offline authentication.

Retrieves the version number of the local authorization list.

Request

No fields: the request is empty.

Response
FieldTypeUseWhat it holds
listVersionintegerRequiredCurrent version number of the local authorization list.
Example
The back office sends
[2, "ccf23a29", "GetLocalListVersion", {}]
The charger answers
[3, "ccf23a29", {
  "listVersion": 1
}]

In OCPP 2.0.1: GetLocalListVersion

Sends a full or partial update to the local authorization list.

Request
FieldTypeUseWhat it holds
listVersionintegerRequiredVersion number of this list update.
updateTypestringRequiredWhether this is a full replacement or differential update. One of Differential, Full.
localAuthorizationListarrayOptionalList of authorization entries.
idTagstringRequiredThe identifier to authorize. At most 20 characters.
idTagInfoobjectOptionalAuthorization information for the idTag.
statusstringRequiredAuthorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx.
expiryDatestringOptionalDate/time after which the idTag should be considered expired. A date and time.
parentIdTagstringOptionalParent idTag for group authorization. At most 20 characters.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the local list update. One of Accepted, Failed, NotSupported, VersionMismatch.
Example
The back office sends
[2, "a23c9563", "SendLocalList", {
  "listVersion": 1,
  "updateType": "Full",
  "localAuthorizationList": [
    {
      "idTag": "04A2B3C4D5E6F7",
      "idTagInfo": {
        "status": "Accepted"
      }
    }
  ]
}]
The charger answers
[3, "a23c9563", {
  "status": "Accepted"
}]

In OCPP 2.0.1: SendLocalList

Reservation

Reserve a connector for a specific user ahead of time.

Cancels an existing reservation.

Request
FieldTypeUseWhat it holds
reservationIdintegerRequiredID of the reservation to cancel.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the reservation was cancelled. One of Accepted, Rejected.
Example
The back office sends
[2, "63258356", "CancelReservation", {
  "reservationId": 7
}]
The charger answers
[3, "63258356", {
  "status": "Accepted"
}]

In OCPP 2.0.1: CancelReservation

Creates a reservation on a specific connector.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector to reserve (0 = no specific connector).
expiryDatestringRequiredDate/time when the reservation expires. A date and time.
idTagstringRequiredIdentifier for which the reservation is made. At most 20 characters.
reservationIdintegerRequiredUnique ID for this reservation.
parentIdTagstringOptionalParent idTag for group reservation. At most 20 characters.
Response
FieldTypeUseWhat it holds
statusstringRequiredResult of the reservation request. One of Accepted, Faulted, Occupied, Rejected, Unavailable.
Example
The back office sends
[2, "62a25d78", "ReserveNow", {
  "connectorId": 1,
  "expiryDate": "2026-10-06T10:00:00Z",
  "idTag": "04A2B3C4D5E6F7",
  "reservationId": 7
}]
The charger answers
[3, "62a25d78", {
  "status": "Accepted"
}]

In OCPP 2.0.1: ReserveNow

Smart charging

Set and manage charging profiles for load balancing, solar integration, and scheduled charging.

Removes one or more charging profiles from the charger.

Request
FieldTypeUseWhat it holds
idintegerOptionalID of the charging profile to clear.
connectorIdintegerOptionalConnector for which to clear profiles.
chargingProfilePurposestringOptionalPurpose of profiles to clear. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile.
stackLevelintegerOptionalStack level of profiles to clear.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether any profiles were cleared. One of Accepted, Unknown.
Example
The back office sends
[2, "2c436739", "ClearChargingProfile", {}]
The charger answers
[3, "2c436739", {
  "status": "Accepted"
}]

In OCPP 2.0.1: ClearChargingProfile

Requests the combined charging schedule for a connector.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector for which to get the schedule.
durationintegerRequiredDuration in seconds for the requested schedule.
chargingRateUnitstringOptionalPreferred unit for the schedule. One of A, W.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the charge point can provide the schedule. One of Accepted, Rejected.
connectorIdintegerOptionalConnector to which the schedule applies.
scheduleStartstringOptionalStart date/time of the composite schedule. A date and time.
chargingScheduleobjectOptionalThe composite charging schedule.
chargingRateUnitstringRequiredUnit of the charging rate (amps or watts). One of A, W.
chargingSchedulePeriodarrayRequiredList of schedule periods.
startPeriodintegerRequiredStart of the period in seconds from the schedule start.
limitnumberRequiredPower or current limit during this period. In steps of 0.1.
numberPhasesintegerOptionalNumber of phases to use for charging.
durationintegerOptionalDuration of the schedule in seconds.
startSchedulestringOptionalStart date/time of the schedule. A date and time.
minChargingRatenumberOptionalMinimum charging rate supported. In steps of 0.1.
Example
The back office sends
[2, "50bc203f", "GetCompositeSchedule", {
  "connectorId": 1,
  "duration": 3600
}]
The charger answers
[3, "50bc203f", {
  "status": "Accepted"
}]

In OCPP 2.0.1: GetCompositeSchedule

Sends a charging profile to the charger.

Request
FieldTypeUseWhat it holds
connectorIdintegerRequiredConnector to which the profile applies.
csChargingProfilesobjectRequiredThe charging profile to install.
chargingProfileIdintegerRequiredUnique identifier of this charging profile.
stackLevelintegerRequiredPriority level of the profile (higher = higher priority).
chargingProfilePurposestringRequiredPurpose of the charging profile. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile.
chargingProfileKindstringRequiredKind of schedule. One of Absolute, Recurring, Relative.
chargingScheduleobjectRequiredThe charging schedule.
chargingRateUnitstringRequiredUnit of the charging rate (amps or watts). One of A, W.
chargingSchedulePeriodarrayRequiredList of schedule periods.
startPeriodintegerRequiredStart of the period in seconds from the schedule start.
limitnumberRequiredPower or current limit during this period. In steps of 0.1.
numberPhasesintegerOptionalNumber of phases to use for charging.
durationintegerOptionalDuration of the schedule in seconds.
startSchedulestringOptionalStart date/time of the schedule. A date and time.
minChargingRatenumberOptionalMinimum charging rate supported. In steps of 0.1.
transactionIdintegerOptionalTransaction to which this profile applies.
recurrencyKindstringOptionalRecurrence frequency for recurring profiles. One of Daily, Weekly.
validFromstringOptionalDate/time from which the profile is valid. A date and time.
validTostringOptionalDate/time after which the profile is no longer valid. A date and time.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the profile was accepted. One of Accepted, Rejected, NotSupported.
Example
The back office sends
[2, "01be9b20", "SetChargingProfile", {
  "connectorId": 1,
  "csChargingProfiles": {
    "chargingProfileId": 10,
    "stackLevel": 0,
    "chargingProfilePurpose": "TxDefaultProfile",
    "chargingProfileKind": "Relative",
    "chargingSchedule": {
      "chargingRateUnit": "A",
      "chargingSchedulePeriod": [
        {
          "startPeriod": 0,
          "limit": 16.0
        }
      ]
    }
  }
}]
The charger answers
[3, "01be9b20", {
  "status": "Accepted"
}]

In OCPP 2.0.1: SetChargingProfile

Remote trigger

Request the charge point to send a specific message on demand.

Requests the charge point to send a specific message immediately.

Request
FieldTypeUseWhat it holds
requestedMessagestringRequiredThe message the charge point should send. One of BootNotification, DiagnosticsStatusNotification, FirmwareStatusNotification, Heartbeat, MeterValues, StatusNotification.
connectorIdintegerOptionalConnector for which the message should be sent.
Response
FieldTypeUseWhat it holds
statusstringRequiredWhether the charge point will send the message. One of Accepted, Rejected, NotImplemented.
Example
The back office sends
[2, "4c736efd", "TriggerMessage", {
  "requestedMessage": "StatusNotification"
}]
The charger answers
[3, "4c736efd", {
  "status": "Accepted"
}]

In OCPP 2.0.1: TriggerMessage

OCPP 1.6 configuration keys

ChangeConfiguration sets one key at a time on a charger, and GetConfiguration reads them back. This is where most real-world charger behaviour is decided: how often meter values arrive, what is in them, whether a session survives a network outage, how a cable unlocks.

How the call behaves

  • Every value is a stringNumbers and booleans too: "60", "true". A JSON number breaks the message schema, and a charger that checks the schema answers with a CallError.
  • Spell key names as the specification doesThe specification treats key names as case insensitive, but not every charger does, so write MeterValuesSampledData and not metervaluessampleddata.
  • Some keys need a restartThe charger answers RebootRequired, and it is on you to send a Reset.
  • Manufacturers add their ownGetConfiguration with an empty key list returns every key a charger supports, including the manufacturer's own. Keys you ask for by name that it does not recognise come back in unknownKey.

The four answers

Accepted
The key is set and active now.
Rejected
The key exists but the value was refused: out of range, wrong format, or read-only on this charger.
RebootRequired
The value is stored but does not apply until the charger restarts.
NotSupported
The charger does not implement this key at all.

All 43 keys, by feature profile

KeyTypeAccessWhat it does
Core34
AllowOfflineTxForUnknownIdOptional in the specbooleanRead and writeWhether the charger starts a transaction for an unknown idTag while it is offline.True keeps a site charging through a network outage, at the cost of sessions you may not be able to bill to anyone.
AuthorizationCacheEnabledOptional in the specbooleanRead and writeWhether the charger caches the outcome of earlier Authorize calls.Different from the Local Auth List: the cache fills itself from real authorizations, the list is pushed by the backend.
AuthorizeRemoteTxRequestsbooleanReadWhether the charger authorizes the idTag in a RemoteStartTransaction before starting.If true, a remote start from the app still needs an Authorize round trip, so a bad idTag fails the start.
BlinkRepeatOptional in the specintegerRead and writeHow often the charger blinks the lamp during a blink sequence.
ClockAlignedDataIntervalintegerRead and writeInterval for clock-aligned meter values, measured from midnight. 0 disables them.900 gives a reading on every quarter hour. This is the one that feeds MeterValuesAlignedData, and it runs whether or not a car is plugged in.
ConnectionTimeOutintegerRead and writeHow long the charger waits for the driver to plug in after authorizing before it releases the connector.
ConnectorPhaseRotationCSLRead and writePhase rotation per connector, as connectorId.RST notation, for example 0.RST, 1.RST, 2.RTS.Wrong here means wrong phase-level meter values and wrong single-phase load balancing. Worth checking on any three-phase site.
ConnectorPhaseRotationMaxLengthOptional in the specintegerReadMaximum number of items in ConnectorPhaseRotation.
GetConfigurationMaxKeysintegerReadMaximum number of keys a single GetConfiguration request may ask for.Ask for more than this and the charger may answer with an error. Send GetConfiguration with no keys at all to get everything it supports.
HeartbeatIntervalintegerRead and writeHow often the charger sends a Heartbeat when nothing else is happening.The BootNotification response can override this. On a metered SIM, a short heartbeat is the quiet data cost that adds up.
LightIntensityOptional in the specintegerRead and writeBrightness of the charger's lighting, as a percentage.
LocalAuthorizeOfflinebooleanRead and writeWhether the charger authorizes from its local list or cache while offline.
LocalPreAuthorizebooleanRead and writeWhether the charger starts a transaction from the local list or cache while online, without waiting for the backend.Cuts the wait at the charger, at the cost of the backend not having the final say on every start.
MaxEnergyOnInvalidIdOptional in the specintegerRead and writeEnergy the charger still delivers after an authorization turns out to be invalid.
MeterValuesAlignedDataCSLRead and writeMeasurands sent in the clock-aligned MeterValues, on the ClockAlignedDataInterval.Same measurand vocabulary as MeterValuesSampledData, different trigger: the clock, not the session.
MeterValuesAlignedDataMaxLengthOptional in the specintegerReadMaximum number of measurands in MeterValuesAlignedData.
MeterValuesSampledDataCSLRead and writeMeasurands sampled during a transaction and sent in MeterValues, on the MeterValueSampleInterval.The single most useful key on this page. See the deep dive below.
MeterValuesSampledDataMaxLengthOptional in the specintegerReadMaximum number of measurands in MeterValuesSampledData.Read this before you build a long list: exceed it and the charger rejects the whole thing.
MeterValueSampleIntervalintegerRead and writeHow often, during a transaction, the charger samples MeterValuesSampledData. 0 disables sampling.60 is a sane default. Below 30, with a long measurand list, you are generating a lot of traffic for very little extra insight.
MinimumStatusDurationOptional in the specintegerRead and writeMinimum time the charger stays in a status before it reports the next one.Useful against status flapping on chargers that bounce between Preparing and Available.
NumberOfConnectorsintegerReadNumber of physical connectors on this charger.
ResetRetriesintegerRead and writeHow often the charger retries a failed reset.
StopTransactionOnEVSideDisconnectbooleanRead and writeWhether unplugging at the car side stops the running transaction.False means the session stays open after the cable is pulled, which is how you end up with sessions that never end.
StopTransactionOnInvalidIdbooleanRead and writeWhether the charger stops the transaction when the backend rejects the idTag.
StopTxnAlignedDataCSLRead and writeClock-aligned measurands added to the transactionData of StopTransaction.
StopTxnAlignedDataMaxLengthOptional in the specintegerReadMaximum number of measurands in StopTxnAlignedData.
StopTxnSampledDataCSLRead and writeSampled measurands added to the transactionData of StopTransaction.Keep this short. Everything in it is repeated for every sample of the whole session inside one StopTransaction payload, which is how chargers produce megabyte stop messages that backends reject.
StopTxnSampledDataMaxLengthOptional in the specintegerReadMaximum number of measurands in StopTxnSampledData.
SupportedFeatureProfilesCSLReadFeature profiles this charger implements, for example Core, FirmwareManagement, SmartCharging.The honest answer to what a charger can do. Read it before you promise a customer smart charging.
SupportedFeatureProfilesMaxLengthOptional in the specintegerReadMaximum number of items in SupportedFeatureProfiles.
TransactionMessageAttemptsintegerRead and writeHow often the charger retries sending a transaction message the backend did not acknowledge.
TransactionMessageRetryIntervalintegerRead and writeBase wait between those retries. The charger multiplies it by the attempt number.
UnlockConnectorOnEVSideDisconnectbooleanRead and writeWhether the cable unlocks at the charger when it is unplugged at the car.
WebSocketPingIntervalOptional in the specintegerRead and writeInterval for WebSocket ping frames on the OCPP-J connection.The quiet fix for chargers that keep dropping offline behind a NAT or firewall that closes idle connections.
Local authorization list3
LocalAuthListEnabledbooleanRead and writeWhether the local authorization list is in use.
LocalAuthListMaxLengthintegerReadHow many entries the local authorization list holds.
SendLocalListMaxLengthintegerReadHow many entries fit in a single SendLocalList message.A list bigger than this has to be sent in several differential updates.
Reservation1
ReserveConnectorZeroSupportedOptional in the specbooleanReadWhether the charger accepts a reservation on connector 0, meaning any connector.
Smart charging5
ChargeProfileMaxStackLevelintegerReadHighest stack level the charger accepts on a charging profile. Higher levels win.
ChargingScheduleAllowedChargingRateUnitCSLReadWhich units the charger accepts in a charging schedule: Current (A), Power (W), or both.Send a profile in watts to a charger that only takes amps and it is rejected. This key tells you which to use.
ChargingScheduleMaxPeriodsintegerReadMaximum number of periods in one charging schedule.
ConnectorSwitch3to1PhaseSupportedOptional in the specbooleanReadWhether the charger can switch between three-phase and single-phase charging.Decides whether you can throttle below the three-phase minimum instead of pausing altogether.
MaxChargingProfilesInstalledintegerReadHow many charging profiles can be installed at once.

MeterValuesSampledData: what a charger measures

One key, MeterValuesSampledData, decides what telemetry you get out of a charging session. It is a comma-separated list of measurands, and the charger samples every item on it at the interval set by MeterValueSampleInterval, then sends them in a MeterValues message. Leave it at the default and you get one cumulative energy reading, enough to bill, and nothing else: no power curve, no per-phase current, no voltage, no way to see whether a smart charging limit landed.

It never works alone. MeterValueSampleInterval sets how often it fires, MeterValuesSampledDataMaxLength caps how many measurands you may list, StopTxnSampledData decides which of them get repeated inside StopTransaction, and MeterValuesAlignedData is the same vocabulary on a clock schedule instead of a session.

The measurands

Any of these may appear in the list. Which ones a charger supports depends on its hardware: an AC wallbox usually does not report state of charge, and a basic charger may only have the energy register.

MeasurandUnitTypically onWhat it gives you
Energy.Active.Import.RegisterWhAC and DCCumulative energy drawn from the grid, read straight off the meter register. The default when MeterValuesSampledData is empty, and the value nearly every billing calculation is built on.
Energy.Active.Export.RegisterWhV2G capableCumulative energy fed back, for bidirectional setups.
Energy.Active.Import.IntervalWhAC and DCEnergy imported since the previous sample, rather than a running total.
Energy.Reactive.Import.RegistervarhMeter dependentCumulative reactive energy imported.
Power.Active.ImportWAC and DCInstantaneous active power. What you plot to see a charging curve, and what load management reacts to.
Power.OfferedWAC and DCPower the charger is currently offering the car. Compare it with Power.Active.Import to see whether a limit is actually being applied.
Power.Reactive.ImportvarMeter dependentInstantaneous reactive power.
Power.FactorratioMeter dependentRatio of active to apparent power.
Current.ImportAAC and DCCurrent drawn. Usually reported per phase, so this one measurand can become three values per sample.
Current.OfferedAAC and DCCurrent limit the charger is signalling to the car. The direct read-out of whether your smart charging profile landed.
Current.ExportAV2G capableCurrent fed back, for bidirectional setups.
VoltageVAC and DCSupply voltage, per phase on three-phase chargers. Useful for spotting a dropped phase or a weak connection.
FrequencyHzMeter dependentGrid frequency. Note that the spec gives it no unit field.
TemperatureCelsiusCharger dependentTemperature at the charger or connector. Explains derating on a hot day before anyone calls it a fault.
SoC%DC, or ISO 15118 on ACState of charge of the car's battery. Only present when the car actually reports it, which on plain AC charging it usually does not.
RPMrpmRareFan speed, on chargers that report it.

Lists that work

Copy one into the value of a ChangeConfiguration call. Start narrow, and add measurands once the charger accepts them.

  • Billing only

    The minimum that still produces a correct invoice. The default on most chargers.

    Energy.Active.Import.Register
  • Standard telemetry

    Sensible default for a managed AC site: a power curve, per-phase current and voltage for diagnosis.

    Energy.Active.Import.Register, Power.Active.Import, Current.Import, Voltage
  • Smart charging

    Adds the offered values, so you can see whether a profile is actually being applied rather than assuming.

    Energy.Active.Import.Register, Power.Active.Import, Power.Offered, Current.Import, Current.Offered, Voltage
  • DC fast charging

    Adds state of charge and temperature, which DC chargers do report and which explain most derating.

    Energy.Active.Import.Register, Power.Active.Import, Current.Import, Voltage, SoC, Temperature

What goes wrong

  • One bad measurand rejects the whole list

    Chargers validate the list as a unit. If a single item is unsupported you get Rejected or NotSupported for everything, with no indication which one failed. Set the list one measurand at a time to find the offender, or read MeterValuesSampledDataMaxLength and the vendor documentation first.

  • One measurand can be three values

    Current.Import and Voltage are reported per phase, so on a three-phase charger they arrive as three sampledValue entries each, tagged L1, L2, L3 or L1-N and so on. A list of six measurands can easily be a dozen values per sample. Payload size grows faster than the list length suggests.

  • Wh against kWh

    The energy register is Wh by default, but the unit field can say kWh and some firmware does that. Read the unit rather than assuming it, or you get an invoice that is off by a factor of a thousand.

  • A short interval is not free

    MeterValueSampleInterval at 10 seconds with a long list means hundreds of messages per session. On a metered SIM that is real money, and on a large site it is real backend load. 60 seconds is a good default, 300 for sites where you only need the shape of the curve.

  • StopTxnSampledData is the payload trap

    Everything listed there is repeated, for every sample of the entire session, inside a single StopTransaction message. A long list on a long session produces a payload big enough for backends to reject or truncate, and the transaction then fails to close cleanly. Keep it to the energy register unless you have a specific reason.

  • Drop the energy register and billing breaks

    If Energy.Active.Import.Register is not in the list, the periodic meter values carry no cumulative total. Most backends then fall back to meterStart and meterStop from the transaction messages, and any session where StopTransaction goes missing becomes unbillable. Keep it in the list, always.

  • SoC is usually not available on AC

    State of charge comes from the car, over ISO 15118 or the DC charging protocol. On a plain AC wallbox without Plug and Charge the car does not report it, so requesting SoC either gets rejected or returns nothing useful.

  • Read the context field

    Each sampledValue carries a context: Sample.Periodic, Transaction.Begin, Transaction.End, Sample.Clock or Trigger. A value at Transaction.Begin is a starting register, not consumption. Treating every sample as periodic is how sessions end up double-counted.

Questions about OCPP 1.6J

OCPP 1.6J is version 1.6 of the Open Charge Point Protocol in its JSON form. The charger opens a WebSocket to its back office, and both sides send JSON messages over it. The Open Charge Alliance published version 1.6 in 2015, and most chargers still support it: in our charger database, 483 of the 495 chargers with a known OCPP version support 1.6.

They carry the same messages in a different way. 1.6J sends JSON over a WebSocket that the charger keeps open, so the charger only needs an outgoing connection. 1.6S sends SOAP over HTTP, and then the back office also has to be able to reach the charger.

2.0.1 is a newer version with its own set of messages. It describes a charger's settings in a device model, has security profiles built in, replaces StartTransaction and StopTransaction with TransactionEvent and adds messages for Plug and Charge (ISO 15118). The two do not mix: a charger and its back office agree on one version when the connection opens. In our charger database, 102 chargers list 2.0.1 as well as or instead of 1.6. Every 2.0.1 and 2.1 message is in the OCPP 2.0.1 and 2.1 reference.

The Open Charge Alliance publishes it free of charge on its website, with a JSON schema for every message. This reference follows that specification. Where the two differ, the specification is right.

Through the Smart Charging profile. The back office sends SetChargingProfile with a schedule of limits in amps or watts. A ChargePointMaxProfile caps the whole charger, a TxDefaultProfile applies to every new session and a TxProfile to one running session. When two profiles with the same purpose overlap, the one with the higher stackLevel wins. How Plugchoice uses this is on the smart charging page.

Look it up in the charger database: 775 chargers, with the OCPP versions we know of and where each came from. The charger's datasheet usually says it too, often as OCPP 1.6J or OCPP 1.6 JSON.

In the charger's settings, often in the installer app or on its local web page, enter the back office's WebSocket URL (it starts with ws:// or wss://) and the charger's ID, the charge point identity. The charger opens the connection and sends a BootNotification. Once the back office answers Accepted, the charger is online and sends a StatusNotification for each connector.

Plugchoice and OCPP

  • A free back officeConnect an OCPP 1.6J charger and manage it in the web portal.
  • The appOwners and installers control the same charger from their phone.
  • The OCPP proxyOne charger on several back offices at the same time.
  • Back officesThe back offices you pick from a list when you connect a charger.

Further reading

  1. What is OCPP?

    Blog | 3 min read

This page for AI assistants

The whole reference, every message and every configuration key, as one plain-text file an assistant can read in one go.

The reference as plain text

Run your OCPP chargers on Plugchoice

Connect your OCPP 1.6J chargers to Plugchoice for free and manage them in the web portal and the app, and through the API.