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.
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]| Step | Contract |
|---|---|
| Locations | GET/POST /v1/tenants/{tenant_id}/locations, GET/PATCH …/locations/{location_id} |
| Stations | GET/POST /v1/tenants/{tenant_id}/stations, DELETE …/stations/{station_id} |
| Station state | GET /v1/tenants/{tenant_id}/stations/{station_id} |
| Tariffs | GET/POST /v1/tenants/{tenant_id}/tariffs, GET …/tariffs/{tariff_id} |
| Connection credentials | PUT /v1/tenants/{tenant_id}/stations/{station_id}/credentials |
| Operation polling | GET /v1/tenants/{tenant_id}/operations/{operation_id} (commands, credentials and moves only) |
| Charger screen QR | GET …/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.