OCPI publishing
Available: tenant settings API. Ivora can publish your charging locations and tariffs over OCPI 2.2.1 to roaming data partners such as Eco-Movement, which feeds maps and navigation apps. Publishing is a per-tenant setting. It is off by default, and changes apply on the partner's next request without any restart. Start in the OCPI publishing group of the API reference.
Production stores these settings, but it does not serve the OCPI endpoint yet,
so versions_url is null and nothing is published. Your settings take effect
once Ivora enables OCPI in production.
| Step | Contract |
|---|---|
| Read | GET /v1/tenants/{tenant_id}/ocpi (stations:read; viewers too) |
| Change | PUT /v1/tenants/{tenant_id}/ocpi (stations:write, never a viewer; Idempotency-Key) |
| Read imported EVSE IDs | GET /v1/tenants/{tenant_id}/ocpi/evse-ids (stations:read) |
| Import EVSE IDs | PUT /v1/tenants/{tenant_id}/ocpi/evse-ids (stations:write; Idempotency-Key) |
There is no separate OCPI scope. OCPI publishes your inventory, so it uses the
inventory scopes. PUT replaces every setting, and omitted fields return to
their defaults. Send the whole record each time.
{"publish": true,
"display_name": "Northside EV",
"website": "https://northside.example",
"time_zone": "America/Chicago",
"connector_defaults": {"standard": "IEC_62196_T1", "max_amperage": 40},
"excluded_location_ids": [31],
"own_party": {"country_code": "US", "party_id": "NTH"}}
| Field | Meaning |
|---|---|
publish | Required. true publishes your locations and tariffs. Needs display_name |
display_name | The operator name partners show: the OCPI Location operator and owner (1–100 characters) |
website | Your https website, shown with the operator name |
time_zone | IANA zone for locations without their own. Without either, a location is not published |
connector_defaults | Connector facts for connectors with no hardware data: standard, format, power_type (OCPI 2.2.1 values), max_voltage (V) and max_amperage (A). Unset ones are a North American Level 2 J1772 cable, 240 V and 32 A |
excluded_location_ids | Location IDs that are never published |
own_party | Your own OCPI party (see below), or null for Ivora's shared party |
The response adds published: whether partners receive your data now. That
requires publish, a display_name, and a tenant that is not private. It
also adds party, the party your data is published under now, and
connector_defaults merged over the Level 2 values.
Updates to partners
Partners read your published locations and tariffs. Partners that accept updates are also sent each change shortly after it happens, so maps show a charger's availability without waiting for the next full read:
- When a partner connects, it is sent every published location and tariff.
- A new location, EVSE or tariff is sent whole, and so is a tariff whose prices,
elements or
tariff_alt_textchange. Billing rules are never sent, so changing only them sends nothing. - A change of EVSE status (available, charging, out of order) or of a location field is sent as just that change.
- When you set
publishtofalse, exclude a location, or your locations move to another party, partners are told to stop showing them. Removed tariffs are deleted at the partner. Nothing else about them is sent.
A location's last_updated changes only when what partners see changes, so a
charger checking in with Ivora is not sent as an update.
Partners receive exactly what they would read, and nothing of a private tenant. Prices are your published tariff prices, excluding tax; when a tariff has a tax rate, each price carries it as the VAT percentage. Updates are retried when a partner is briefly unavailable and are delivered in order for each location. There is nothing to configure; Ivora staff manage partner connections.
Roaming drivers
While you publish, drivers of Ivora's roaming partners (eMSPs) can charge at your chargers with their partner's RFID card or app. Each partner sends Ivora its tokens, and your chargers authorize them like your own cards:
| The partner marks a token | Your charger |
|---|---|
| Always or allowed (whitelisted) | Accepts it at once |
| Real-time, offline allowed | Ivora asks the partner within a few seconds. If the partner does not answer, it accepts |
| Real-time only | Ivora asks the partner within a few seconds. If the partner does not answer, it refuses |
| Not valid | Refuses it (blocked) |
The partner's answer is what your charger tells the driver: accepted, blocked, expired, or refused. A card no partner sent and you did not register is refused, as before. On a charger with several connectors, the partner may be asked when the session starts rather than at the tap.
- Roaming tokens never appear in your token list, and a card you registered first always stays yours: a partner's token of the same value is not used at your chargers.
- A partner's tokens work at every published operator its connection covers. A partner that Ivora connected for your own party ID alone can charge with its tokens at your chargers only, and one connected for another operator's party ID cannot charge at yours.
- When you set
publishtofalse, or Ivora ends a partnership, the partner's tokens stop working at your chargers within about two minutes. Transactions already charged on them keep the token's value like any other.
Sessions and charge records
The partner bills its driver, so Ivora reports each roaming charge to the partner whose token started it, and to no other partner. A partner that Ivora connected for one party ID alone receives only the charges under that party:
- While charging, an OCPI Session: start, energy in kWh, the cost so far and its status. Energy updates are sent at most about once a minute; the stop is sent at once, with the charging period.
- After the charge, one charge detail record (CDR) with the total energy (kWh), the session time and idle time (hours), the cost excluding tax and, when your tariff has a tax rate, including tax, with the tariff that priced it. When the charger reported idle time, the charging periods follow it: charging periods carry energy and time, idle periods parking time, and the wait before the vehicle first draws has no period. A charge with no energy and no cost has no CDR.
Prices are the ones in force when the session started: those of the session's Ivora bill if it has one, else of the tariff on the charging transaction, else of the tariff on the connector. Ivora reads that tariff within about 15 seconds of the start, and uses it only if it was not edited after the start. Editing or archiving a tariff later never changes a session or CDR. If there is no tariff, it was edited after the start, or it has time-of-day or other price blocks (roaming CDRs price simple tariffs only for now), Ivora never sends a guessed or zero price: the session shows no cost, and its CDR waits until Ivora staff decide how to price it. A CDR also waits while the location, EVSE or connector lacks an address, coordinates or connector type a CDR must state; fix it and tell Ivora support.
A CDR is never changed once sent. If one is wrong, Ivora staff issue a credit
CDR that cancels it and a replacement with a new ID. Your own cards' and your
drivers' payment sessions are never reported. When you set publish to
false, no new roaming session is reported; sessions already under way are
still reported to their end, with their CDRs. Charging preferences that partners
send are declined: your chargers keep their own schedule.
Parties
Each OCPI object carries a country_code and a party_id. Party IDs are issued
by national registries, so Ivora publishes your own party only after Ivora staff
check that you hold it.
Diagram source
sequenceDiagram
participant App as Your application
participant API as Ivora API
participant Staff as Ivora staff
participant Partner as OCPI partner
App->>API: PUT /v1/tenants/{tenant_id}/ocpi with own_party US NTH
API-->>App: own_party.status pending_approval, party US IVR
Partner->>API: GET locations, published under US IVR with your display_name
Staff->>API: PATCH /v1/admin/ocpi/tenants/{tenant_id} approved_party US NTH
API-->>Staff: own_party.status approved
Partner->>API: GET locations, now published under US NTH- Without
own_party, or while it ispending_approvalorrejected, your locations publish under Ivora's shared partyUS*IVR. Yourdisplay_nameis the operator. EVSE IDs readUS*IVR*E<station>*<evse>. - Once approved, they publish under your party, and the credentials roles
partners receive include a CPO role with your
display_name. - If you request a different party, publishing falls back to
US*IVRuntil staff approve the new one. Switching back to the approved pair needs no new approval.US*IVRitself cannot be anown_party. - Staff approve on evidence that you hold the party: its registry entry, a
partner's confirmation or a letter of authorization. If they cannot confirm
it,
own_party.statusisrejectedandown_party.rejection_notesays why. Your locations stay underUS*IVR. Send Ivora the missing evidence, and staff can still approve the same pair. - A party belongs to one operator. Requesting a party that Ivora already
approved for another tenant answers
409 ocpi_party_in_use. If you hold it in the registry, contact Ivora. - Nothing is published under your party until it is approved and
publishistrue. Your locations and tariffs are only ever published under your own approved party orUS*IVR, never another operator's.
Moving from another CSMS
Partners already know your network by its party and its EVSE IDs. To keep them when you move to Ivora:
Request the party you already hold as
own_party. Staff approve it as above.Import the EVSE IDs your previous CSMS published:
{"evse_ids": [{"station_id": 41, "evse_number": 1, "evse_id": "US*XYZ*E123"}, {"station_id": 41, "evse_number": 2, "evse_id": "US*XYZ*E124"}]}station_idandevse_numbername the EVSE as the API does: the station must be one of yours, andevse_numberis the number in the generated ID.evse_idis the eMI3 ID with separators: your party,E, then your own ID (up to 48 characters, read in upper case).
You can import EVSE IDs once staff have approved your party. While the
request is pending or rejected, the import is refused. An imported ID replaces
the generated <party>*E<station>*<evse> while your locations publish under
that party. In
the response, applies shows which IDs partners receive now. EVSEs without one
keep the generated ID. The list replaces the stored one, and [] removes them
all. Partners that accept updates are sent a changed ID.
Location IDs are Ivora's own. Partners see your locations under your approved party with the EVSE IDs above.
Private tenants
Ivora keeps some tenants private: private hosts' networks, the OCPP bench and
test tenants. A private tenant is never published or listed. private is true
in its record, and PUT with publish: true answers 409 ocpi_tenant_private.
Only Ivora staff change this.
Partner commands and charging profiles
A registered roaming partner can also act on what you publish, over OCPI 2.2.1 Commands and ChargingProfiles:
| Partner request | What happens on your charger |
|---|---|
START_SESSION | Off until Ivora enables partner starts. Then, a remote start on the EVSE and connector the partner names, with the partner's driver token, which your charger accepts there for 10 minutes |
STOP_SESSION | A remote stop of a session the partner started |
UNLOCK_CONNECTOR | A connector unlock |
| Charging profile set or removed | A power or current cap on a session the partner started (purpose session). A limit of 0 pauses charging |
| Active charging profile | A composite schedule read; nothing changes on the charger |
Reservations (RESERVE_NOW, CANCEL_RESERVATION) are not supported.
- Only what you publish. A partner reaches only EVSEs at your published
locations, under the party they are published under. Excluded locations and
private tenants are never reachable. Turning
publishoff stops partner commands on the partner's next request. - Only the partner's own drivers. Partner starts are off until Ivora enables them. Then a start must carry a valid token the partner issued, and a token that is already one of your own (an RFID card in your tokens list) is always refused, so a partner cannot start or stop charging on your drivers' cards. A partner can stop, or set charging profiles for, only a session its own start produced: one your charger accepted and then started with that token. One partner start per connector runs at a time.
- Same rules as your own commands. Starts and charging profile changes are
refused while your team has no usable payment method for the usage fee
(
payment_method_required). Stops, unlocks and the composite schedule read never are. What the charger reported it cannot take is refused as forPOST .../charging-profiles. - Visible in your API. Session caps a partner sets are listed in
GET /v1/tenants/{tenant_id}/stations/{station_id}/charging-profiles, and their sessions in the transactions API.
Errors
| Code | When |
|---|---|
invalid_request (422) | Validation failed. Examples: publish without display_name, a non-https website, a party_id that is not 3 capital letters or digits, country_code not ISO alpha-2 in capitals, an unknown connector value, or own_party US*IVR. For EVSE IDs: not eMI3, a station_id that is not one of your stations, an EVSE or ID listed twice, or an ID that reads as the generated ID of another of your EVSEs |
ocpi_tenant_private (409) | Ivora keeps the tenant private |
ocpi_party_in_use (409) | Ivora approved the requested party for another operator |
ocpi_evse_id_party (409) | An imported EVSE ID is not under your own_party, or staff have not approved that party yet |
ocpi_evse_id_in_use (409) | Another operator on Ivora publishes this EVSE ID |
forbidden (403) | A viewer writing, or another tenant's key or user |
idempotency_key_reused (409) | The same Idempotency-Key with a different body |
Ivora's staff routes (GET /v1/admin/ocpi/tenants, and PATCH /v1/admin/ocpi/tenants/{tenant_id} with private, approved_party or
rejected_party, and a reason) also return ocpi_party_not_requested and ocpi_party_in_use. The
staff CDR correction (POST /v1/admin/ocpi/cdrs/{cdr_id}/correct) returns
ocpi_cdr_not_found, ocpi_cdr_credited, ocpi_cdr_credit, ocpi_cdr_held
and ocpi_session_not_completed. The staff decision on a waiting CDR
(POST /v1/admin/ocpi/sessions/{session_id}/release) returns
ocpi_session_not_found, ocpi_session_not_held, ocpi_decision_required,
ocpi_cdr_held and ocpi_tenant_unknown. These routes take signed-in Ivora
staff only, never an API key. Tenant applications never call them.
AI agents read these settings with get_ocpi_publishing. Changing them stays a
REST call of your administrators.