Charger management

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.

RouteScopeWhat it does
GET /v1/tenants/{tenant_id}/stations/{station_id}/configurationstations:readWhat the charging core last recorded; sends nothing to the charger
POST .../stations/{station_id}/configurationstations:controlChange one OCPP 1.6 key or OCPP 2.x variable
POST .../stations/{station_id}/configuration/refreshstations:controlAsk the charger to report its configuration again
POST .../stations/{station_id}/triggerstations:controlAsk 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. key reads Component[.instance]/Variable[.instance], and the item also carries component, variable, evse_number, attribute_type and the status of the latest SetVariables.

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:

KindExamplesResult
SensitiveAuthorizationKey, SecurityCtrlr/BasicAuthPassword, WiFiPwd, SimPin, any key read back as nullconfiguration_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
ProtectedWebSocketPingInterval, 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 identityAs 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:

Routecharger_status
ChangeAccepted, RebootRequired (reset the station to apply), Rejected, NotSupported; OCPP 2.x also UnknownComponent, UnknownVariable
RefreshAccepted; OCPP 2.x also Rejected, NotSupported, EmptyResultSet
TriggerAccepted, 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.

sequence diagram; its source follows
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 null

Agents

The MCP interface exposes only the read, as get_station_configuration. Changes, refreshes and trigger messages are REST only.