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.
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
| Field | Type | Use | What it holds |
|---|---|---|---|
| idTag | string | Required | The identifier to authorize. At most 20 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| idTagInfo | object | Required | Authorization information for the idTag. |
| status | string | Required | Authorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx. |
| expiryDate | string | Optional | Date/time after which the idTag should be considered expired. A date and time. |
| parentIdTag | string | Optional | Parent idTag for group authorization. At most 20 characters. |
Example
[2, "7f83df9c", "Authorize", {
"idTag": "04A2B3C4D5E6F7"
}][3, "7f83df9c", {
"idTagInfo": {
"status": "Accepted"
}
}]In OCPP 2.0.1: Authorize
Sent after startup to register with the back office.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| chargePointVendor | string | Required | Vendor of the charge point. At most 20 characters. |
| chargePointModel | string | Required | Model of the charge point. At most 20 characters. |
| chargePointSerialNumber | string | Optional | Serial number of the charge point. At most 25 characters. |
| chargeBoxSerialNumber | string | Optional | Serial number of the charge box. At most 25 characters. |
| firmwareVersion | string | Optional | Firmware version of the charge point. At most 50 characters. |
| iccid | string | Optional | ICCID of the SIM card. At most 20 characters. |
| imsi | string | Optional | IMSI of the SIM card. At most 20 characters. |
| meterType | string | Optional | Type of the energy meter. At most 25 characters. |
| meterSerialNumber | string | Optional | Serial number of the energy meter. At most 25 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Registration status. One of Accepted, Pending, Rejected. |
| currentTime | string | Required | Current time of the Central System. A date and time. |
| interval | integer | Required | Heartbeat interval in seconds. |
Example
[2, "392b5b40", "BootNotification", {
"chargePointVendor": "ExampleVendor",
"chargePointModel": "ExampleModel",
"firmwareVersion": "1.4.2"
}][3, "392b5b40", {
"status": "Accepted",
"currentTime": "2026-10-06T09:30:00Z",
"interval": 300
}]In OCPP 2.0.1: BootNotification
Changes availability of a connector.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | ID of the connector (0 = entire charge point). |
| type | string | Required | Requested availability change. One of Inoperative, Operative. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the availability change request. One of Accepted, Rejected, Scheduled. |
Example
[2, "be3dcf2e", "ChangeAvailability", {
"connectorId": 1,
"type": "Operative"
}][3, "be3dcf2e", {
"status": "Accepted"
}]In OCPP 2.0.1: ChangeAvailability
Changes a configuration key on the charger.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| key | string | Required | Configuration key to change. At most 50 characters. |
| value | string | Required | New value for the configuration key. At most 500 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the configuration change. One of Accepted, Rejected, RebootRequired, NotSupported. |
Example
[2, "6fdf2255", "ChangeConfiguration", {
"key": "MeterValueSampleInterval",
"value": "60"
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the cache clear request. One of Accepted, Rejected. |
Example
[2, "e993e844", "ClearCache", {}][3, "e993e844", {
"status": "Accepted"
}]In OCPP 2.0.1: ClearCache
Vendor-specific data exchange.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| vendorId | string | Required | Identifies the vendor. At most 255 characters. |
| messageId | string | Optional | Additional identification of the message. At most 50 characters. |
| data | string | Optional | Vendor-specific data. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the data transfer. One of Accepted, Rejected, UnknownMessageId, UnknownVendorId. |
| data | string | Optional | Vendor-specific response data. |
Example
[2, "e1a403d5", "DataTransfer", {
"vendorId": "com.example"
}][3, "e1a403d5", {
"status": "Accepted"
}]In OCPP 2.0.1: DataTransfer
Retrieves configuration keys from the charger.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| key | array | Optional | List of configuration keys to retrieve. items At most 50 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| configurationKey | array | Optional | List of known configuration keys. |
| key | string | Required | Configuration key name. At most 50 characters. |
| readonly | boolean | Required | Whether the key is read-only. |
| value | string | Optional | Current value of the key. At most 500 characters. |
| unknownKey | array | Optional | List of requested keys that are unknown. items At most 50 characters. |
Example
[2, "02bd00f5", "GetConfiguration", {
"key": [
"MeterValueSampleInterval"
]
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| currentTime | string | Required | Current time of the Central System. A date and time. |
Example
[2, "83622997", "Heartbeat", {}][3, "83622997", {
"currentTime": "2026-10-06T09:30:00Z"
}]In OCPP 2.0.1: Heartbeat
Sends periodic or triggered meter readings.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | ID of the connector (0 = main meter). |
| meterValue | array | Required | One or more meter values with timestamps. |
| timestamp | string | Required | Timestamp of the meter value. A date and time. |
| sampledValue | array | Required | One or more sampled values. |
| value | string | Required | The measured value. |
| context | string | Optional | Reading context. One of Interruption.Begin, Interruption.End, Sample.Clock, Sample.Periodic, Transaction.Begin, Transaction.End, Trigger, Other. |
| format | string | Optional | Value format. One of Raw, SignedData. |
| measurand | string | Optional | Type 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. |
| phase | string | Optional | Phase to which the measurement applies. One of L1, L2, L3, N, L1-N, L2-N, L3-N, L1-L2, L2-L3, L3-L1. |
| location | string | Optional | Location of measurement. One of Cable, EV, Inlet, Outlet, Body. |
| unit | string | Optional | Unit of measurement. One of Wh, kWh, varh, kvarh, W, kW, VA, kVA, var, kvar, A, V, K, Celcius, Celsius, Fahrenheit, Percent. |
| transactionId | integer | Optional | Transaction to which these meter values apply. |
Response
No fields: the response is empty.
Example
[2, "80a15023", "MeterValues", {
"connectorId": 1,
"meterValue": [
{
"timestamp": "2026-10-06T09:30:00Z",
"sampledValue": [
{
"value": "19840",
"measurand": "Energy.Active.Import.Register",
"unit": "Wh"
}
]
}
],
"transactionId": 4521
}][3, "80a15023", {}]In OCPP 2.0.1: MeterValues
Remotely starts a charging session.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| idTag | string | Required | The identifier to use for this session. At most 20 characters. |
| connectorId | integer | Optional | Connector on which to start. |
| chargingProfile | object | Optional | Charging profile to apply to this session. |
| chargingProfileId | integer | Required | Unique identifier of this charging profile. |
| stackLevel | integer | Required | Priority level of the profile (higher = higher priority). |
| chargingProfilePurpose | string | Required | Purpose of the charging profile. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile. |
| chargingProfileKind | string | Required | Kind of schedule. One of Absolute, Recurring, Relative. |
| chargingSchedule | object | Required | The charging schedule. |
| chargingRateUnit | string | Required | Unit of the charging rate (amps or watts). One of A, W. |
| chargingSchedulePeriod | array | Required | List of schedule periods. |
| startPeriod | integer | Required | Start of the period in seconds from the schedule start. |
| limit | number | Required | Power or current limit during this period. In steps of 0.1. |
| numberPhases | integer | Optional | Number of phases to use for charging. |
| duration | integer | Optional | Duration of the schedule in seconds. |
| startSchedule | string | Optional | Start date/time of the schedule. A date and time. |
| minChargingRate | number | Optional | Minimum charging rate supported. In steps of 0.1. |
| transactionId | integer | Optional | Transaction to which this profile applies. |
| recurrencyKind | string | Optional | Recurrence frequency for recurring profiles. One of Daily, Weekly. |
| validFrom | string | Optional | Date/time from which the profile is valid. A date and time. |
| validTo | string | Optional | Date/time after which the profile is no longer valid. A date and time. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the charge point accepted the request. One of Accepted, Rejected. |
Example
[2, "b7e2ef8a", "RemoteStartTransaction", {
"idTag": "04A2B3C4D5E6F7",
"connectorId": 1
}][3, "b7e2ef8a", {
"status": "Accepted"
}]In OCPP 2.0.1: RequestStartTransaction
Remotely stops a charging session.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| transactionId | integer | Required | ID of the transaction to stop. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the charge point accepted the request. One of Accepted, Rejected. |
Example
[2, "7fb0afb2", "RemoteStopTransaction", {
"transactionId": 4521
}][3, "7fb0afb2", {
"status": "Accepted"
}]In OCPP 2.0.1: RequestStopTransaction
Resets the charge point (hard or soft).
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| type | string | Required | Type of reset to perform. One of Hard, Soft. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the charge point accepted the reset. One of Accepted, Rejected. |
Example
[2, "526d688f", "Reset", {
"type": "Soft"
}][3, "526d688f", {
"status": "Accepted"
}]In OCPP 2.0.1: Reset
Notifies the back office that a charging session has started.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector on which the transaction started. |
| idTag | string | Required | Identifier used to start the transaction. At most 20 characters. |
| meterStart | integer | Required | Meter value at start of transaction (Wh). |
| timestamp | string | Required | Timestamp when the transaction started. A date and time. |
| reservationId | integer | Optional | ID of the reservation that was used. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| idTagInfo | object | Required | Authorization information for the idTag. |
| status | string | Required | Authorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx. |
| expiryDate | string | Optional | Date/time after which the idTag should be considered expired. A date and time. |
| parentIdTag | string | Optional | Parent idTag for group authorization. At most 20 characters. |
| transactionId | integer | Required | Transaction ID assigned by the Central System. |
Example
[2, "2410a6a5", "StartTransaction", {
"connectorId": 1,
"idTag": "04A2B3C4D5E6F7",
"meterStart": 12500,
"timestamp": "2026-10-06T09:30:00Z"
}][3, "2410a6a5", {
"idTagInfo": {
"status": "Accepted"
},
"transactionId": 4521
}]In OCPP 2.0.1: TransactionEvent
Reports the current status and any errors of a connector.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector for which the status is reported. |
| errorCode | string | Required | Error code (NoError if no error). One of ConnectorLockFailure, EVCommunicationError, GroundFailure, HighTemperature, InternalError, LocalListConflict, NoError, OtherError, OverCurrentFailure, PowerMeterFailure, PowerSwitchFailure, ReaderFailure, ResetFailure, UnderVoltage, OverVoltage, WeakSignal. |
| status | string | Required | Current status of the connector. One of Available, Preparing, Charging, SuspendedEVSE, SuspendedEV, Finishing, Reserved, Unavailable, Faulted. |
| info | string | Optional | Additional free-text info about the status. At most 50 characters. |
| timestamp | string | Optional | Timestamp of the status change. A date and time. |
| vendorId | string | Optional | Vendor-specific identifier. At most 255 characters. |
| vendorErrorCode | string | Optional | Vendor-specific error code. At most 50 characters. |
Response
No fields: the response is empty.
Example
[2, "d9b0420e", "StatusNotification", {
"connectorId": 1,
"errorCode": "NoError",
"status": "Available"
}][3, "d9b0420e", {}]In OCPP 2.0.1: StatusNotification
Notifies the back office that a charging session has stopped.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| transactionId | integer | Required | ID of the transaction being stopped. |
| timestamp | string | Required | Timestamp when the transaction stopped. A date and time. |
| meterStop | integer | Required | Meter value at end of transaction (Wh). |
| idTag | string | Optional | Identifier that requested the stop. At most 20 characters. |
| reason | string | Optional | Reason for stopping the transaction. One of EmergencyStop, EVDisconnected, HardReset, Local, Other, PowerLoss, Reboot, Remote, SoftReset, UnlockCommand, DeAuthorized. |
| transactionData | array | Optional | Array of MeterValue objects (same structure as MeterValues.meterValue). |
| timestamp | string | Required | Timestamp of the meter value. A date and time. |
| sampledValue | array | Required | One or more sampled values. |
| value | string | Required | The measured value. |
| context | string | Optional | Reading context. One of Interruption.Begin, Interruption.End, Sample.Clock, Sample.Periodic, Transaction.Begin, Transaction.End, Trigger, Other. |
| format | string | Optional | Value format. One of Raw, SignedData. |
| measurand | string | Optional | Type 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. |
| phase | string | Optional | Phase to which the measurement applies. One of L1, L2, L3, N, L1-N, L2-N, L3-N, L1-L2, L2-L3, L3-L1. |
| location | string | Optional | Location of measurement. One of Cable, EV, Inlet, Outlet, Body. |
| unit | string | Optional | Unit of measurement. One of Wh, kWh, varh, kvarh, W, kW, VA, kVA, var, kvar, A, V, K, Celcius, Celsius, Fahrenheit, Percent. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| idTagInfo | object | Optional | Authorization information for the idTag. |
| status | string | Required | Authorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx. |
| expiryDate | string | Optional | Date/time after which the idTag should be considered expired. A date and time. |
| parentIdTag | string | Optional | Parent idTag for group authorization. At most 20 characters. |
Example
[2, "b380dc07", "StopTransaction", {
"transactionId": 4521,
"timestamp": "2026-10-06T09:30:00Z",
"meterStop": 19840,
"idTag": "04A2B3C4D5E6F7"
}][3, "b380dc07", {
"idTagInfo": {
"status": "Accepted"
}
}]In OCPP 2.0.1: TransactionEvent
Remotely unlocks a connector.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector to unlock. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the unlock request. One of Unlocked, UnlockFailed, NotSupported. |
Example
[2, "882ccab0", "UnlockConnector", {
"connectorId": 1
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| location | string | Required | URI where diagnostics should be uploaded. An address (URI). |
| retries | integer | Optional | Number of retries for uploading. |
| retryInterval | integer | Optional | Seconds between retry attempts. |
| startTime | string | Optional | Start of the time range for log collection. A date and time. |
| stopTime | string | Optional | End of the time range for log collection. A date and time. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| fileName | string | Optional | Name of the diagnostics file. At most 255 characters. |
Example
[2, "da7920cd", "GetDiagnostics", {
"location": "ftp://files.example.com/diagnostics/"
}][3, "da7920cd", {}]In OCPP 2.0.1: GetLog
Reports the status of a diagnostics upload.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Current status of the diagnostics upload. One of Idle, Uploaded, UploadFailed, Uploading. |
Response
No fields: the response is empty.
Example
[2, "d1c853b4", "DiagnosticsStatusNotification", {
"status": "Uploaded"
}][3, "d1c853b4", {}]In OCPP 2.0.1: LogStatusNotification
Reports the status of a firmware update.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Current status of the firmware update. One of Downloaded, DownloadFailed, Downloading, Idle, InstallationFailed, Installing, Installed. |
Response
No fields: the response is empty.
Example
[2, "dc9afcb2", "FirmwareStatusNotification", {
"status": "Installed"
}][3, "dc9afcb2", {}]In OCPP 2.0.1: FirmwareStatusNotification
Instructs the charger to download and install new firmware.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| location | string | Required | URI where the firmware can be downloaded. An address (URI). |
| retrieveDate | string | Required | Date/time after which the charger should retrieve the firmware. A date and time. |
| retries | integer | Optional | Number of retries for downloading. |
| retryInterval | integer | Optional | Seconds between retry attempts. |
Response
No fields: the response is empty.
Example
[2, "a57cc6a2", "UpdateFirmware", {
"location": "ftp://files.example.com/fw-1.4.3.bin",
"retrieveDate": "2026-10-07T02:00:00Z"
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| listVersion | integer | Required | Current version number of the local authorization list. |
Example
[2, "ccf23a29", "GetLocalListVersion", {}][3, "ccf23a29", {
"listVersion": 1
}]In OCPP 2.0.1: GetLocalListVersion
Sends a full or partial update to the local authorization list.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| listVersion | integer | Required | Version number of this list update. |
| updateType | string | Required | Whether this is a full replacement or differential update. One of Differential, Full. |
| localAuthorizationList | array | Optional | List of authorization entries. |
| idTag | string | Required | The identifier to authorize. At most 20 characters. |
| idTagInfo | object | Optional | Authorization information for the idTag. |
| status | string | Required | Authorization status. One of Accepted, Blocked, Expired, Invalid, ConcurrentTx. |
| expiryDate | string | Optional | Date/time after which the idTag should be considered expired. A date and time. |
| parentIdTag | string | Optional | Parent idTag for group authorization. At most 20 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the local list update. One of Accepted, Failed, NotSupported, VersionMismatch. |
Example
[2, "a23c9563", "SendLocalList", {
"listVersion": 1,
"updateType": "Full",
"localAuthorizationList": [
{
"idTag": "04A2B3C4D5E6F7",
"idTagInfo": {
"status": "Accepted"
}
}
]
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| reservationId | integer | Required | ID of the reservation to cancel. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the reservation was cancelled. One of Accepted, Rejected. |
Example
[2, "63258356", "CancelReservation", {
"reservationId": 7
}][3, "63258356", {
"status": "Accepted"
}]In OCPP 2.0.1: CancelReservation
Creates a reservation on a specific connector.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector to reserve (0 = no specific connector). |
| expiryDate | string | Required | Date/time when the reservation expires. A date and time. |
| idTag | string | Required | Identifier for which the reservation is made. At most 20 characters. |
| reservationId | integer | Required | Unique ID for this reservation. |
| parentIdTag | string | Optional | Parent idTag for group reservation. At most 20 characters. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Result of the reservation request. One of Accepted, Faulted, Occupied, Rejected, Unavailable. |
Example
[2, "62a25d78", "ReserveNow", {
"connectorId": 1,
"expiryDate": "2026-10-06T10:00:00Z",
"idTag": "04A2B3C4D5E6F7",
"reservationId": 7
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| id | integer | Optional | ID of the charging profile to clear. |
| connectorId | integer | Optional | Connector for which to clear profiles. |
| chargingProfilePurpose | string | Optional | Purpose of profiles to clear. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile. |
| stackLevel | integer | Optional | Stack level of profiles to clear. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether any profiles were cleared. One of Accepted, Unknown. |
Example
[2, "2c436739", "ClearChargingProfile", {}][3, "2c436739", {
"status": "Accepted"
}]In OCPP 2.0.1: ClearChargingProfile
Requests the combined charging schedule for a connector.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector for which to get the schedule. |
| duration | integer | Required | Duration in seconds for the requested schedule. |
| chargingRateUnit | string | Optional | Preferred unit for the schedule. One of A, W. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the charge point can provide the schedule. One of Accepted, Rejected. |
| connectorId | integer | Optional | Connector to which the schedule applies. |
| scheduleStart | string | Optional | Start date/time of the composite schedule. A date and time. |
| chargingSchedule | object | Optional | The composite charging schedule. |
| chargingRateUnit | string | Required | Unit of the charging rate (amps or watts). One of A, W. |
| chargingSchedulePeriod | array | Required | List of schedule periods. |
| startPeriod | integer | Required | Start of the period in seconds from the schedule start. |
| limit | number | Required | Power or current limit during this period. In steps of 0.1. |
| numberPhases | integer | Optional | Number of phases to use for charging. |
| duration | integer | Optional | Duration of the schedule in seconds. |
| startSchedule | string | Optional | Start date/time of the schedule. A date and time. |
| minChargingRate | number | Optional | Minimum charging rate supported. In steps of 0.1. |
Example
[2, "50bc203f", "GetCompositeSchedule", {
"connectorId": 1,
"duration": 3600
}][3, "50bc203f", {
"status": "Accepted"
}]In OCPP 2.0.1: GetCompositeSchedule
Sends a charging profile to the charger.
Request
| Field | Type | Use | What it holds |
|---|---|---|---|
| connectorId | integer | Required | Connector to which the profile applies. |
| csChargingProfiles | object | Required | The charging profile to install. |
| chargingProfileId | integer | Required | Unique identifier of this charging profile. |
| stackLevel | integer | Required | Priority level of the profile (higher = higher priority). |
| chargingProfilePurpose | string | Required | Purpose of the charging profile. One of ChargePointMaxProfile, TxDefaultProfile, TxProfile. |
| chargingProfileKind | string | Required | Kind of schedule. One of Absolute, Recurring, Relative. |
| chargingSchedule | object | Required | The charging schedule. |
| chargingRateUnit | string | Required | Unit of the charging rate (amps or watts). One of A, W. |
| chargingSchedulePeriod | array | Required | List of schedule periods. |
| startPeriod | integer | Required | Start of the period in seconds from the schedule start. |
| limit | number | Required | Power or current limit during this period. In steps of 0.1. |
| numberPhases | integer | Optional | Number of phases to use for charging. |
| duration | integer | Optional | Duration of the schedule in seconds. |
| startSchedule | string | Optional | Start date/time of the schedule. A date and time. |
| minChargingRate | number | Optional | Minimum charging rate supported. In steps of 0.1. |
| transactionId | integer | Optional | Transaction to which this profile applies. |
| recurrencyKind | string | Optional | Recurrence frequency for recurring profiles. One of Daily, Weekly. |
| validFrom | string | Optional | Date/time from which the profile is valid. A date and time. |
| validTo | string | Optional | Date/time after which the profile is no longer valid. A date and time. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the profile was accepted. One of Accepted, Rejected, NotSupported. |
Example
[2, "01be9b20", "SetChargingProfile", {
"connectorId": 1,
"csChargingProfiles": {
"chargingProfileId": 10,
"stackLevel": 0,
"chargingProfilePurpose": "TxDefaultProfile",
"chargingProfileKind": "Relative",
"chargingSchedule": {
"chargingRateUnit": "A",
"chargingSchedulePeriod": [
{
"startPeriod": 0,
"limit": 16.0
}
]
}
}
}][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
| Field | Type | Use | What it holds |
|---|---|---|---|
| requestedMessage | string | Required | The message the charge point should send. One of BootNotification, DiagnosticsStatusNotification, FirmwareStatusNotification, Heartbeat, MeterValues, StatusNotification. |
| connectorId | integer | Optional | Connector for which the message should be sent. |
Response
| Field | Type | Use | What it holds |
|---|---|---|---|
| status | string | Required | Whether the charge point will send the message. One of Accepted, Rejected, NotImplemented. |
Example
[2, "4c736efd", "TriggerMessage", {
"requestedMessage": "StatusNotification"
}][3, "4c736efd", {
"status": "Accepted"
}]In OCPP 2.0.1: TriggerMessage
No message matches that search.
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
| Key | Type | Access | What it does |
|---|---|---|---|
| Core34 | |||
| AllowOfflineTxForUnknownIdOptional in the spec | boolean | Read and write | Whether 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 spec | boolean | Read and write | Whether 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. |
| AuthorizeRemoteTxRequests | boolean | Read | Whether 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 spec | integer | Read and write | How often the charger blinks the lamp during a blink sequence. |
| ClockAlignedDataInterval | integer | Read and write | Interval 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. |
| ConnectionTimeOut | integer | Read and write | How long the charger waits for the driver to plug in after authorizing before it releases the connector. |
| ConnectorPhaseRotation | CSL | Read and write | Phase 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 spec | integer | Read | Maximum number of items in ConnectorPhaseRotation. |
| GetConfigurationMaxKeys | integer | Read | Maximum 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. |
| HeartbeatInterval | integer | Read and write | How 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 spec | integer | Read and write | Brightness of the charger's lighting, as a percentage. |
| LocalAuthorizeOffline | boolean | Read and write | Whether the charger authorizes from its local list or cache while offline. |
| LocalPreAuthorize | boolean | Read and write | Whether 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 spec | integer | Read and write | Energy the charger still delivers after an authorization turns out to be invalid. |
| MeterValuesAlignedData | CSL | Read and write | Measurands sent in the clock-aligned MeterValues, on the ClockAlignedDataInterval.Same measurand vocabulary as MeterValuesSampledData, different trigger: the clock, not the session. |
| MeterValuesAlignedDataMaxLengthOptional in the spec | integer | Read | Maximum number of measurands in MeterValuesAlignedData. |
| MeterValuesSampledData | CSL | Read and write | Measurands 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 spec | integer | Read | Maximum number of measurands in MeterValuesSampledData.Read this before you build a long list: exceed it and the charger rejects the whole thing. |
| MeterValueSampleInterval | integer | Read and write | How 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 spec | integer | Read and write | Minimum 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. |
| NumberOfConnectors | integer | Read | Number of physical connectors on this charger. |
| ResetRetries | integer | Read and write | How often the charger retries a failed reset. |
| StopTransactionOnEVSideDisconnect | boolean | Read and write | Whether 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. |
| StopTransactionOnInvalidId | boolean | Read and write | Whether the charger stops the transaction when the backend rejects the idTag. |
| StopTxnAlignedData | CSL | Read and write | Clock-aligned measurands added to the transactionData of StopTransaction. |
| StopTxnAlignedDataMaxLengthOptional in the spec | integer | Read | Maximum number of measurands in StopTxnAlignedData. |
| StopTxnSampledData | CSL | Read and write | Sampled 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 spec | integer | Read | Maximum number of measurands in StopTxnSampledData. |
| SupportedFeatureProfiles | CSL | Read | Feature 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 spec | integer | Read | Maximum number of items in SupportedFeatureProfiles. |
| TransactionMessageAttempts | integer | Read and write | How often the charger retries sending a transaction message the backend did not acknowledge. |
| TransactionMessageRetryInterval | integer | Read and write | Base wait between those retries. The charger multiplies it by the attempt number. |
| UnlockConnectorOnEVSideDisconnect | boolean | Read and write | Whether the cable unlocks at the charger when it is unplugged at the car. |
| WebSocketPingIntervalOptional in the spec | integer | Read and write | Interval 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 | |||
| LocalAuthListEnabled | boolean | Read and write | Whether the local authorization list is in use. |
| LocalAuthListMaxLength | integer | Read | How many entries the local authorization list holds. |
| SendLocalListMaxLength | integer | Read | How 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 spec | boolean | Read | Whether the charger accepts a reservation on connector 0, meaning any connector. |
| Smart charging5 | |||
| ChargeProfileMaxStackLevel | integer | Read | Highest stack level the charger accepts on a charging profile. Higher levels win. |
| ChargingScheduleAllowedChargingRateUnit | CSL | Read | Which 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. |
| ChargingScheduleMaxPeriods | integer | Read | Maximum number of periods in one charging schedule. |
| ConnectorSwitch3to1PhaseSupportedOptional in the spec | boolean | Read | Whether 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. |
| MaxChargingProfilesInstalled | integer | Read | How many charging profiles can be installed at once. |
No key matches that search.
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.
| Measurand | Unit | Typically on | What it gives you |
|---|---|---|---|
| Energy.Active.Import.Register | Wh | AC and DC | Cumulative 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.Register | Wh | V2G capable | Cumulative energy fed back, for bidirectional setups. |
| Energy.Active.Import.Interval | Wh | AC and DC | Energy imported since the previous sample, rather than a running total. |
| Energy.Reactive.Import.Register | varh | Meter dependent | Cumulative reactive energy imported. |
| Power.Active.Import | W | AC and DC | Instantaneous active power. What you plot to see a charging curve, and what load management reacts to. |
| Power.Offered | W | AC and DC | Power the charger is currently offering the car. Compare it with Power.Active.Import to see whether a limit is actually being applied. |
| Power.Reactive.Import | var | Meter dependent | Instantaneous reactive power. |
| Power.Factor | ratio | Meter dependent | Ratio of active to apparent power. |
| Current.Import | A | AC and DC | Current drawn. Usually reported per phase, so this one measurand can become three values per sample. |
| Current.Offered | A | AC and DC | Current limit the charger is signalling to the car. The direct read-out of whether your smart charging profile landed. |
| Current.Export | A | V2G capable | Current fed back, for bidirectional setups. |
| Voltage | V | AC and DC | Supply voltage, per phase on three-phase chargers. Useful for spotting a dropped phase or a weak connection. |
| Frequency | Hz | Meter dependent | Grid frequency. Note that the spec gives it no unit field. |
| Temperature | Celsius | Charger dependent | Temperature at the charger or connector. Explains derating on a hot day before anyone calls it a fault. |
| SoC | % | DC, or ISO 15118 on AC | State of charge of the car's battery. Only present when the car actually reports it, which on plain AC charging it usually does not. |
| RPM | rpm | Rare | Fan speed, on chargers that report it. |
No measurand matches that search.
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
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.
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.