Charger management

Fleet administration (Ivora staff)

Ivora staff only. These routes let the Ivora Platform run the fleet across every tenant: see it, assign chargers that connected on their own, set the platform's meter sampling defaults and read the audit trail. Tenant applications never need them. They are in the Platform administration group of the API reference.

TaskContractWho
List stations across tenantsGET /v1/admin/stations?status&tenant_id&after&limitadmin, platform-admin, platform-support
Fleet countsGET /v1/admin/statsadmin, platform-admin, platform-support
List chargers waiting to be assignedGET /v1/admin/unassigned-stations?serial&after&limitadmin, platform-admin, platform-support
Assign one to a tenantPOST /v1/admin/stations/{station_id}/assignment (Idempotency-Key)admin, platform-admin
Read meter sampling defaultsGET /v1/admin/platform-settingsadmin, platform-admin, platform-support
Set themPUT /v1/admin/platform-settings (Idempotency-Key)admin, platform-admin
Read the audit trailGET /v1/admin/audit?tenant_id&actor&since&cursor&limitadmin, platform-admin, platform-support
Read a project's per-project charger URLs (preproduction only)GET /v1/admin/tenants/{tenant_id}/charger-urlsadmin, platform-admin, platform-support
Override them (preproduction only, on by default): turn them off or back onPUT /v1/admin/tenants/{tenant_id}/charger-urls (Idempotency-Key, enabled, reason)admin, platform-admin

Every route needs a signed-in staff member. API keys are refused with 403 forbidden, even a key a staff member owns, and so are tenant roles. platform-support reads but never writes. Every write is journaled with its actor, logged as an audit line and listed by the audit route.

Fleet

GET /v1/admin/stations lists every tenant's stations by ID, with tenant_name. status filters online, offline or faulted, which means a connector reports Faulted. A faulted station is also online or offline. unassigned is true for chargers in the inventory tenant (see below). Paginate with after=next_cursor.

GET /v1/admin/stats returns stations, online, offline (online plus offline equals stations), faulted, unassigned and active_transactions, in total and per tenant, with as_of.

Assign an auto-registered charger

A charger that connects to Ivora under a name the core does not know is registered by the core itself in its inventory tenant (Ivora Inventory). GET /v1/admin/unassigned-stations lists those chargers. serial finds one by the serial number printed on it or its OCPP connection name.

POST /v1/admin/stations/30/assignment with:

{"tenant_id": 7, "location_id": 3}

The response is 202 with an operation, journaled under the receiving tenant. Poll it at /v1/tenants/{tenant_id}/operations/{operation_id}.

sequence diagram; its source follows
Diagram source
sequenceDiagram
  participant Staff as Ivora Platform
  participant API as Ivora API
  participant Core as Charging core
  participant Charger
  Staff->>API: POST assignment (tenant, location)
  API->>Core: move station, EVSEs, connectors and boot record
  API->>Core: close the connection under the inventory tenant
  Core-->>Charger: WebSocket closed
  Charger->>Core: reconnects under the new tenant
  API-->>Staff: 202 operation, result.connection dropped
  • The station, its EVSEs and connectors and its boot record move in one step.
  • Connector tariffs are cleared, because an inventory tariff is not the tenant's. Assign the tenant's tariffs next.
  • result.connection is dropped (the charger reconnects under its new tenant), not_connected (it was offline) or drop_failed. On drop_failed the charger keeps reporting under the inventory tenant until it reconnects, so power-cycle it.
  • Past transactions, OCPP messages and the recorded configuration stay with the inventory tenant. Refresh the configuration and set a connection password afterwards if the charger needs one.
  • A rejected operation moved nothing. result.error.code is station_not_found, tenant_not_found, location_not_found, station_assigned (details.tenant_id; also when another assignment won), transaction_active or invalid_request (the inventory tenant itself).

Platform settings

The charging core pushes the meter sampling defaults to every charger on each accepted boot: OCPP 1.6 MeterValueSampleInterval and MeterValuesSampledData, OCPP 2.x SampledDataCtrlr.TxUpdatedInterval and TxUpdatedMeasurands.

PUT /v1/admin/platform-settings with:

{"meter_sample_interval_seconds": 10,
 "meter_values_sampled_data": ["Energy.Active.Import.Register", "Power.Active.Import"],
 "reason": "Shorter samples for running cost"}
  • meter_sample_interval_seconds is in seconds (0 to 86400, 0 switches periodic sampling off). It is 20 until set.
  • meter_values_sampled_data lists OCPP measurands. An empty list leaves each charger's own list. Chargers reject measurands they cannot measure.
  • PUT replaces both values and needs a reason. Nothing is sent to chargers now: each receives the values on its next accepted boot. A station's own interval, where the core holds one, still wins.
  • A core without platform settings answers 409 platform_settings_unavailable.

Audit trail

GET /v1/admin/audit lists two sources, newest first:

  • api: every write this API journaled, for tenants and staff alike, with the operation's status and operation_id. actor is user:<identity ID> or key:<API key ID>. Inputs are journaled only as a fingerprint, so detail is null.
  • console: the operator console's audit trail, with its actor_roles and detail.

tenant_id, actor and since (an ISO 8601 timestamp with an offset) filter both sources. Platform-wide entries, such as platform_settings.update, have tenant_id null. Pass next_cursor as cursor for older entries. It is null once both sources are exhausted.