GuidesAPI reference
Introduction
  • Overview
Orientation
  • What a CSMS does
  • OCPP in ten minutes
  • The vocabulary
  • Lifecycle of a charging session
  • Which OCPP version am I dealing with?
  • How Flowion maps onto OCPP
Getting started
  • Quickstart
  • Core concepts
  • Set up your workspace
  • Connect a simulated charger
  • Connect a real charger
  • Environments
API guide
  • Authentication
  • Your first API call
  • Interactive API reference
  • Roles and permissions
  • Errors, pagination and versioning
  • Live updates
  • Sending commands to a charger
  • Rate limits
How-to guides
  • Register and provision a charger
  • Read and change charger settings
  • Authorize drivers with RFID cards
  • Start and stop sessions remotely
  • Track sessions and energy
  • Take a charger in and out of service
  • Unlock a stuck connector
  • Reset a charger
  • Send vendor-specific data
  • Keep a site within its electrical limits
  • Use day-ahead electricity prices
  • Receive events with webhooks
  • OCPP feature coverage
Troubleshooting
  • 8 more coming soon
    • My charger will not connectSoon
    • It connects, then dropsSoon
    • A command timed out or returned 409Soon
    • A card is not being authorizedSoon
    • My transaction looks wrongSoon
    • Meter values are missing or sparseSoon
    • Reading the OCPP message logSoon
    • Known limitationsSoon
Reference
  • 5 more coming soon
    • GlossarySoon
    • Endpoint indexSoon
    • OCPP message supportSoon
    • Status and error codesSoon
    • ChangelogSoon
Flowion Docsflowion.io
PreviousErrors, pagination and versioningNextSending commands to a charger
Was this page helpful?
Edit this page

Live updates

Polling every list endpoint on a timer works, but it means guessing at an interval that is either too slow to feel live or too fast to be kind to the rate limit. GET /v1/environments/{environment_id}/live-events is a Server-Sent Events stream that tells you when to refetch, instead.

Shell
curl -N "$API/environments/$ENV/live-events" \
  -H "Authorization: Bearer $TOKEN"

-N matters for curl — without it, output buffers and you will not see frames as they arrive.

These are nudges, not data#

An event names what changed, never the new value. You still call the matching GET endpoint to find out what changed to. That is what makes a dropped event tolerable — delivery is best-effort, so a client has to reconcile once when the stream opens and again after every reconnect, rather than treating the stream as a complete history of everything that happened while it was connected.

The frame shape#

Every frame's SSE event: field matches its payload's type, and data: is one JSON object:

event: connector_status_changed
data: {"type":"connector_status_changed","charging_station_id":"...","connector_id":"...","status":"Occupied"}

The payload is deliberately flat rather than nested per event type — a client only ever needs charging_station_id (and usually connector_id) to know what to refetch, regardless of which kind of event arrived. Eight event types exist today:

typeCarries, beyond charging_station_idMeans
charging_station_connected—The station's OCPP connection came up.
charging_station_disconnected—It went down.
connector_status_changedconnector_id, statusA connector's status changed.
transaction_startedconnector_id, transaction_idA session began.
transaction_updatedconnector_id, transaction_idA session's meter values or state changed.
transaction_endedconnector_id, transaction_idA session finished.
meter_values_updatedconnector_idNew meter readings landed for a connector — coalesced, so this does not fire per sample.
command_status_changedcommand_idA command you created moved to a new status — see Sending commands to a charger.

A field the event type does not carry is simply absent from the JSON object, not sent as null.

The stream does not stay open forever#

Access is checked once, at connect — the same user-role environment check as everything else scoped to an environment. A stream that ran indefinitely would outlive a membership revoked five minutes into it, so it is closed after 30 minutes regardless. EventSource (or your own reconnect loop) picking the connection back up re-runs that check, which is also your cue to reconcile: refetch whatever you're tracking on every reconnect, not just the first connect.

A comment frame arrives immediately on connect, before any real event — harmless to an EventSource client, but it is what makes a quiet environment's stream visibly open rather than looking stuck for the first 15 seconds. After that, a keep-alive comment arrives every 15 seconds on its own, so a transparent proxy between you and the API does not time out an idle connection.

Next: Sending commands to a charger.