Register and provision a charger
OCPP functional block B — Provisioning.
Provisioning is everything between "a station exists" and "a station is operating": creating its record, giving it credentials, deciding whether to accept it, and reading back what it says about itself.
Connect a real charger covers the physical commissioning. This page covers the CSMS side, and what to do when a station is already connected.
The boot handshake is the whole thing#
A station's first message after connecting is BootNotification. Everything
about provisioning hangs off how you answer it.
Until you answer Accepted or Pending, the station may not send anything
else at all — not status, not meter values, not queued messages from before
a reboot. That makes your answer a gate rather than an acknowledgement.
The answer comes from the charger's stored registration_status, which you
own. It is not derived from the station's behaviour.
| Status | Effect |
|---|---|
Accepted | Operates normally. Adopts the heartbeat interval and clock we return. |
Pending | Stays connected, answers you, volunteers nothing, starts no transactions. |
Rejected | Goes silent — stops sending and stops answering until its retry interval elapses. |
New chargers are created Accepted.
Holding a station still while you configure it#
Pending is the useful middle state, and the reason it exists.
Set it before a station is first powered on, and it will connect, boot, and then wait. You can read and change its settings; it will answer. What it will not do is start charging anyone or flood you with status while you work.
curl -X PATCH https://api.flowion.io/v1/chargers/$CHARGER \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"registration_status": "Pending"}'
Move it to Accepted when you are done. The station picks up the change at
its next boot — trigger one rather than waiting, with
a triggered BootNotification.
Avoid
Rejectedunless you mean it. A rejected station stops responding to you entirely, so no command can bring it back. You wait for its retry interval. Use it to decommission, not to pause.
What a station tells you about itself#
Once booted, the charger record carries a boot report: vendor, model, serial numbers, firmware version, and modem details if it has any.
curl https://api.flowion.io/v1/chargers/$CHARGER \
-H "Authorization: Bearer $TOKEN"
Alongside it:
ocpp_version— what it actually negotiated (ocpp1.6,ocpp2.0.1,ocpp2.1), which is frequently not what its datasheet claims.status—onlineoroffline, meaning whether a gateway currently holds its socket. A cache: a gateway killed without unwinding can leave a stale row, so this can briefly lag.last_seen— the durable complement. Use it to judge whether anonlinecharger is genuinely alive.last_boot_at— when the most recentBootNotificationarrived.
Only the latest boot report is kept. A firmware upgrade overwrites the previous one, and a reboot loop leaves no trail — if you need boot history, you will have to record it yourself as you observe changes.
EVSEs and connectors appear on their own#
You never create these. They come into existence as the station reports itself, which is why a freshly provisioned charger has none.
curl https://api.flowion.io/v1/chargers/$CHARGER/evses \
-H "Authorization: Bearer $TOKEN"
Check the shape against the physical hardware during commissioning. A two-cable post reporting two EVSEs rather than one EVSE with two connectors is modelling itself in a way that will mislead load management — it implies two vehicles can charge at once when they cannot. See The vocabulary.
Credentials#
Provisioning returns an authorization_key exactly once. Only an Argon2id
hash is stored.
To replace it:
curl -X POST https://api.flowion.io/v1/chargers/$CHARGER/credential \
-H "Authorization: Bearer $TOKEN"
The old key stops working immediately. A station you cannot reconfigure is a station you have just taken offline, so rotate before a site visit, not after.
Heartbeat interval#
The interval a station uses is the one you return at boot, not the one it is configured with. A per-charger override lives on the charger record; unset means the system default.
Shorter intervals detect a dead station sooner and cost more traffic — which matters on metered mobile connections across a large fleet. Note that heartbeats also carry the clock the station synchronises against, so an interval measured in hours means a station's clock can drift meaningfully between corrections.
Deprovisioning#
curl -X DELETE https://api.flowion.io/v1/chargers/$CHARGER \
-H "Authorization: Bearer $TOKEN"
A soft delete, and idempotent. The record and its history survive;
disabled_at records when it happened.
This does not reach the hardware. A deprovisioned station that is still powered on and configured will keep trying to connect. If it must genuinely stop, reconfigure or power down the hardware as well.