Charger management

Register and manage chargers

Available: tenant fleet API. Provisioning is independent of payment-provider selection. Start in the Locations and Stations groups of the API reference.

flowchart diagram; its source follows
Diagram source
flowchart TD
  Location[Create or select a tenant location] --> Register[Register station]
  Register --> Credentials[Set connection credentials]
  Credentials --> Hardware[Configure the charger with the returned OCPP URL]
  Hardware --> Connected[Read online state and connectors]
StepContract
LocationsGET/POST /v1/tenants/{tenant_id}/locations, GET/PATCH …/locations/{location_id}
StationsGET/POST /v1/tenants/{tenant_id}/stations, DELETE …/stations/{station_id}
Station stateGET /v1/tenants/{tenant_id}/stations/{station_id}
TariffsGET/POST /v1/tenants/{tenant_id}/tariffs, GET …/tariffs/{tariff_id}
Connection credentialsPUT /v1/tenants/{tenant_id}/stations/{station_id}/credentials
Operation pollingGET /v1/tenants/{tenant_id}/operations/{operation_id} (commands, credentials and moves only)
Charger screen QRGET …/stations/{station_id}/displays, PUT/GET/DELETE …/evses/{evse_number}/display (charger displays)

Creation is synchronous

Creating a location, station or tariff returns 201 and the resource itself, including its numeric id. No polling is needed to learn the ID. The journal still guarantees one upstream insert per Idempotency-Key: replaying the same key and body returns the same resource, and a different body with the same key returns 409 idempotency_key_reused.

{"name": "Harbor Loft", "latitude": 42.36, "longitude": -71.06,
 "time_zone": "America/New_York", "external_reference": "property:8f1c…"}

Only charger-bound writes return a 202 operation: commands, credentials and station moves. A creation that the core does not answer returns 503 outcome_unknown with the journaled operation_id; list the resource by name or external_reference before retrying with a new key.

PATCH …/locations/{location_id} changes only the supplied fields (latitude and longitude together; coordinates are optional at creation). DELETE …/stations/{station_id} removes a station, its EVSEs and connectors only when it never charged, disconnecting it first if connected; a station with history returns 409 station_has_history and stays in inventory, and an active transaction returns 409 transaction_active. Both are synchronous and journaled like creates. Station records also carry serial and last_seen, the time of the charger's most recent OCPP message.

External references instead of name matching

Every create accepts an optional external_reference (up to 128 characters of letters, digits, _ . : / -). It is unique per tenant and resource type, is returned on reads and filters lists with ?external_reference=. Use it for your own property, listing or price-plan identifier so a name never has to act as a foreign key. A second create with the same reference returns 409 external_reference_taken with details.resource_id, so a retry after a lost response can adopt the existing resource instead of creating a duplicate.

Tariffs are immutable versions: create another rather than editing one. Amounts are integer minor units (rate_minor_per_kwh, authorization_minor).

Credentials

The credentials endpoint returns an operation because it can reach hardware. An offline station stores the password for its next connection (result.applied = "stored"). A connected OCPP 2.0.1 or 2.1 station receives it over OCPP and the core stores it once the charger accepts it (result.applied = "pushed"). A connected OCPP 1.6 charger is rejected with station_online: the core cannot push a password to it, so disconnect it or change the password in the charger's own configuration first.

Many chargers append their own charge point id to the configured URL or use it as the BasicAuth username. The core resolves …/<station-name>/<charger-id> to the station named in the URL and accepts the charger's own id as the username against that station's password, so a fixed-identity charger still connects as the station you registered.

Each station record carries its default connection_url (wss://csmsws.ivoracharge.com/sp1/{station_name}). A custom OCPP domain publishes its own template. Before a new charger goes into service, set its heartbeat and WebSocket ping as described in connecting chargers.

Station IDs, connector resource IDs, OCPP connector numbers and EVSE IDs are different identifiers. Discover them through reads rather than calculating them. The Host registry also has its own IDs; do not substitute them into tenant routes.

Host account workflows

Ivora Host is itself a consumer of this contract. Its application backend keeps the charger registry (display name, address, price, setup progress) and calls the tenant routes above with the signed-in user's token: locations and stations with external_reference, credentials, live state, immutable price tariffs, bills and, where Ivora has enabled live payments, the managed Stripe adapter with return_surface: driver for driver checkouts. The former /v1/host compatibility routes were retired on 2026-09-25. Host's Stripe setup uses the tenant payment account routes with the signed-in user's token.

Ivora Host generates its own driver-page links and printable QR cards from station/EVSE identifiers. QR artwork, branding, print layout and application navigation are application features, not unified API capabilities. Host responses omit qr_path and checkout_url, and the unified API has no QR image endpoint for applications or signage. Its only QR images are the PNGs that OCPP 2.0.1 charger displays load from /v1/display-images/<sha256>.png, which exist only for QRs a display push registered. Other applications should construct links to their own driver experience and render their own signage. These links are navigation, never charging authority.

Showing that link on the charger's own screen is a reusable charger capability. Host sets the same checkout URL as its printed card through charger displays, and Ivora keeps it on the screen where an adapter supports the charger. The application still chooses the URL and serves the page; chargers without an adapter need the printed card.

Host application writes derive one durable Idempotency-Key per record and action, so the tenant journal's retry rules apply to Ivora Host exactly as to any other application.