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.
| Task | Contract | Who |
|---|---|---|
| List stations across tenants | GET /v1/admin/stations?status&tenant_id&after&limit | admin, platform-admin, platform-support |
| Fleet counts | GET /v1/admin/stats | admin, platform-admin, platform-support |
| List chargers waiting to be assigned | GET /v1/admin/unassigned-stations?serial&after&limit | admin, platform-admin, platform-support |
| Assign one to a tenant | POST /v1/admin/stations/{station_id}/assignment (Idempotency-Key) | admin, platform-admin |
| Read meter sampling defaults | GET /v1/admin/platform-settings | admin, platform-admin, platform-support |
| Set them | PUT /v1/admin/platform-settings (Idempotency-Key) | admin, platform-admin |
| Read the audit trail | GET /v1/admin/audit?tenant_id&actor&since&cursor&limit | admin, platform-admin, platform-support |
| Read a project's per-project charger URLs (preproduction only) | GET /v1/admin/tenants/{tenant_id}/charger-urls | admin, platform-admin, platform-support |
| Override them (preproduction only, on by default): turn them off or back on | PUT /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}.
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.connectionisdropped(the charger reconnects under its new tenant),not_connected(it was offline) ordrop_failed. Ondrop_failedthe 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.codeisstation_not_found,tenant_not_found,location_not_found,station_assigned(details.tenant_id; also when another assignment won),transaction_activeorinvalid_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_secondsis in seconds (0 to 86400, 0 switches periodic sampling off). It is 20 until set.meter_values_sampled_datalists OCPP measurands. An empty list leaves each charger's own list. Chargers reject measurands they cannot measure.PUTreplaces both values and needs areason. 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'sstatusandoperation_id.actorisuser:<identity ID>orkey:<API key ID>. Inputs are journaled only as a fingerprint, sodetailisnull.console: the operator console's audit trail, with itsactor_rolesanddetail.
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.