Charger configuration and trigger messages
Read a charger's configuration, change one key at a time and ask the charger to
send a message now. The API translates each request into the charger's own
protocol: OCPP 1.6 GetConfiguration, ChangeConfiguration and
TriggerMessage, or OCPP 2.0.1/2.1 GetBaseReport, SetVariables and
TriggerMessage. No request carries a raw OCPP message.
| Route | Scope | What it does |
|---|---|---|
GET /v1/tenants/{tenant_id}/stations/{station_id}/configuration | stations:read | What the charging core last recorded; sends nothing to the charger |
POST .../stations/{station_id}/configuration | stations:control | Change one OCPP 1.6 key or OCPP 2.x variable |
POST .../stations/{station_id}/configuration/refresh | stations:control | Ask the charger to report its configuration again |
POST .../stations/{station_id}/trigger | stations:control | Ask the charger to send one message now |
Read the configuration
The read returns what the charging core recorded from the charger's own reports
and from accepted changes. It is not a live read, so it works while the charger
is offline. For a fresh copy, call the refresh route, poll its operation until
charger_status is set, then read again.
- OCPP 1.6 stations return
source: "get_configuration", one item per key. - OCPP 2.0.1/2.1 stations return
source: "device_model", one item per variable attribute.keyreadsComponent[.instance]/Variable[.instance], and the item also carriescomponent,variable,evse_number,attribute_typeand thestatusof the latestSetVariables.
Filter with ?key= (an OCPP 1.6 key or an OCPP 2.x variable name) and page with
after=next_cursor, up to limit=500.
Every item says whether it is sensitive or protected. A sensitive value is
always null, for every caller including agents: any key naming a password
(pass, pwd), a PIN or PUK (PinCode, SimPin, SimPuk), a key (AuthorizationKey, EncryptionKey,
LicenseKey), a secret, a token, a credential, or Wi-Fi or APN settings, and
every OCPP 2.x passwordString attribute.
Change a key
OCPP 1.6:
{"key":"HeartbeatInterval","value":"300"}
OCPP 2.0.1/2.1:
{"component":"OCPPCommCtrlr","variable":"HeartbeatInterval","value":"300"}
OCPP 2.x also accepts component_instance, variable_instance, evse_number
(the station's EVSE number) and attribute_type (Actual by default, or
Target, MinSet, MaxSet). Values are text: up to 500 characters on OCPP 1.6
and 1,000 on OCPP 2.x, with no control characters. Send an OCPP 1.6 body to an
OCPP 1.6 station; the other shape is rejected with
configuration_address_invalid.
Tenants may change only the standard keys: the OCPP 1.6 configuration keys
(Core, Local Auth List, Reservation and Smart Charging profiles) and the
OCPP 2.0.1 standardized component/variable pairs, such as
OCPPCommCtrlr/HeartbeatInterval, SampledDataCtrlr/TxUpdatedInterval or
TxCtrlr/EVConnectionTimeOut. Standard keys that could disconnect the charger
from Ivora or weaken its security are left out. Every other key is refused:
| Kind | Examples | Result |
|---|---|---|
| Sensitive | AuthorizationKey, SecurityCtrlr/BasicAuthPassword, WiFiPwd, SimPin, any key read back as null | configuration_key_sensitive for everyone. Set the station password with PUT .../credentials, which keeps the charging core's copy in step; a password changed behind its back locks the charger out at its next connection |
| Protected | WebSocketPingInterval, CpoName, certificate and ISO 15118 keys, every SecurityCtrlr, ISO15118Ctrlr, CertificateCtrlr and CustomizationCtrlr variable, NTP servers, and every vendor or unknown key (StaticIP, MqttBroker...) | configuration_key_protected unless the caller holds stations:admin (team owners and admins, Ivora platform administrators, API keys created with it). A protected key the charger reports read-only answers 403 configuration_key_read_only |
| Connection (protected) | WebSocketURL, OCPPID, SecurityProfile, CentralSystemURL, ChargeBoxIdentity, OCPPAddress, the OCPP 2.x NetworkConfiguration component, SecurityCtrlr/SecurityProfile and Identity, OCPPCommCtrlr/NetworkConfigurationPriority, ActiveNetworkProfile and NetworkProfileConnectionAttempts, and any key named like a URL, host, server, address, broker or identity | As protected, and the body also needs "confirm_connection_change": true (422 connection_change_unconfirmed otherwise). The result carries connection: true and a warning |
Warning
A connection key decides where the charger connects, as whom and how securely. A wrong value disconnects the charger from Ivora, and only someone at the charger can fix it then. Read the current value first, change one key at a time and keep someone at the site when you can.
stations:admin replaced allow_protected, which is now ignored. Configuration
changes still need stations:control as well. Configuration reads mark each key
protected and connection.
Keys are matched without case; instances and EVSEs are not part of the match.
A refused key (403, or 422 connection_change_unconfirmed) answers at once: no operation is created, nothing is sent
and the Idempotency-Key stays unused. The result of a protected change does
not repeat its value. Values are never logged by the API, and the idempotency
record keeps only a keyed digest of the value.
Every change is in the project's operations (kind
station.configuration) and emits station.configuration_changed with
station_id, operation_id, key, protected, connection and the actor
once Ivora sent it; value only for an unprotected key. The charger's answer
is the operation's charger_status.
Trigger a message
{"message":"StatusNotification","connector_id":14}
message is BootNotification, Heartbeat, MeterValues,
StatusNotification or FirmwareStatusNotification on every protocol,
DiagnosticsStatusNotification on OCPP 1.6 only, and LogStatusNotification
or TransactionEvent on OCPP 2.x only. Others, including a message the
station's protocol cannot trigger, answer 422 trigger_unsupported at once: no
operation is created and the Idempotency-Key stays unused.
connector_id is the connector resource ID from the station API; omit it for
the whole station. The requested message arrives through the usual charger
handling, for example as charger events.
Operations and the charger's answer
The three writes behave like charger commands. They take a
persisted Idempotency-Key, return 202 with an operation, and record the
caller as the operation's actor. An offline station is rejected with
station_offline and nothing is sent.
The API reads the answer from the charging core's message journal: the oldest
matching request (same message and, for changes and triggers, the same payload
and connector) sent while the operation dispatched that no other operation has
taken, then the charger's reply to it, the row carrying that request's message
ID. A refresh on OCPP 1.6 matches only a GetConfiguration of every key, not
one of named keys.
succeeded means the charging core sent the message. The charger's own answer
is in result.charger_status:
| Route | charger_status |
|---|---|
| Change | Accepted, RebootRequired (reset the station to apply), Rejected, NotSupported; OCPP 2.x also UnknownComponent, UnknownVariable |
| Refresh | Accepted; OCPP 2.x also Rejected, NotSupported, EmptyResultSet |
| Trigger | Accepted, Rejected, NotImplemented |
A CallError from the charger reads CallError. The API waits up to about
three seconds for the answer. If it has not arrived, charger_status is null:
poll GET /v1/tenants/{tenant_id}/operations/{operation_id} with the same
credentials, and the answer is filled in once the charging core records it.
Nothing is resent. The operation.completed webhook fires at dispatch, so it can
carry charger_status: null.
Diagram source
sequenceDiagram
participant App as Application backend
participant API as Ivora API
participant Core as Charging core
participant C as Charger
App->>API: POST configuration (Idempotency-Key)
API->>API: Key policy (allowlist, refused keys answer 403)
API->>Core: ChangeConfiguration or SetVariables
Core->>C: OCPP request
C-->>Core: Accepted, RebootRequired, Rejected...
API-->>App: 202 operation with charger_status
App->>API: Poll operation while charger_status is nullAgents
The MCP interface exposes only the read, as get_station_configuration.
Changes, refreshes and trigger messages are REST only.