Log inTalk to us
Charger management

Roll a pilot charger back to your previous platform

While your network moves to Ivora, a charger proxy sits between your chargers and the two platforms. Each charger keeps dialling the same address; the proxy routes it either to your previous platform or to Ivora, one charger at a time. During a pilot you can send any pilot charger back to your previous platform yourself, at any time, from your dashboard's Migration page or through the API below. To roll back a whole site or every charger at once, use the migration's workspace (Migration portal): it acts on the same rollbacks.

A rollback moves only the charger's connection:

  • The proxy routes the charger to your previous platform and closes its connection to Ivora. The charger reconnects by itself, usually within seconds, to your previous platform, which controls it again.
  • Nothing is sent to the charger, and nothing changes in Ivora's record of the station: it stays registered, with its history, and can be moved to Ivora again later by the migration team.
  • QR sticker scans of that charger go to your previous platform again (QR sticker redirects).
sequence diagram; its source follows
Diagram source
sequenceDiagram
  participant You as Your team admin
  participant API as Ivora API
  participant Proxy as Charger proxy
  participant Old as Previous platform
  You->>API: POST .../migration/chargers/{station_id}/rollback
  API-->>You: 202, status pending
  Proxy->>API: routing report (every few seconds)
  API-->>Proxy: rollbacks to apply
  Proxy->>Proxy: route to previous platform, close Ivora connection
  Proxy->>API: result: applied (no connection to Ivora open)
  API-->>You: migration.charger_rolled_back (webhook)
  Note over Proxy,Old: the charger reconnects through the proxy
  Proxy->>API: routing report: connected to previous platform
  You->>API: GET .../migration/rollbacks/{rollback_id}
  API-->>You: applied, reconnect: reconnected

Who can roll back

ActionNeeds
List migrating chargers, read a rollbackstations:read
Roll a charger backstations:admin: your team's owners and admins, Ivora staff, and API keys created with it

A rollback is never available to an AI agent: a person types the charger's name to confirm it.

List your migrating chargers

GET /v1/tenants/{tenant_id}/migration/chargers lists the chargers the proxy reports for your project, and those a site move recorded, ordered by station ID (after and limit, up to 500, page through them). GET /v1/tenants/{tenant_id}/migration/chargers/{station_id} reads one.

FieldMeaning
stateon_ivora, on_previous_platform (never moved, or rolled back) or rollback_pending
routeWhere the proxy routes the charger: ivora or previous_platform
proxiedtrue when the proxy reports the charger. Only these can be rolled back here
connectedThe side its connection through the proxy is open on: ivora, previous_platform, both (for a moment while it moves) or none (offline)
proxy_reported_at, proxy_staleWhen Ivora last heard from the proxy about it; stale after five minutes. A rollback asked while the proxy is stale waits until it reports again
shadowThe station is in shadow mode: your previous platform controls it and Ivora only observes
recorded_routeThe route Ivora recorded from site moves and rollbacks, which QR sticker scans follow
rollback_availableWhether a rollback would be accepted now
last_rollbackThe latest rollback of this charger, as below

Roll a charger back

curl -X POST "$API/v1/tenants/7/migration/chargers/42/rollback" \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name": "CP-0042", "reason": "Driver reported a failed start at bay 3"}'
  • name is the station's connection name (name in station reads), typed to confirm. Another name is refused with 409 station_name_mismatch (details.name), so a wrong station ID never moves another charger.
  • reason (3 to 300 characters) is kept with the rollback, in your audit log and in the event.
  • The answer is 202 with the rollback, status: pending. A retry with the same Idempotency-Key returns the same rollback as it is now.

A rollback works while Ivora's charging core is unavailable, which is when you are most likely to need it: the station is then read from the proxy's own report of it. A station the proxy does not report cannot be looked up then and the request answers 503; retry later or ask Ivora support.

A rollback is always accepted while the charger is routed to Ivora, also while it is charging. A session that is running on Ivora then stays open on Ivora: the charger ends it on your previous platform, and Ivora's copy is reconciled by hand with the migration team. Roll back between sessions when you can.

RefusalWhen
404 station_not_foundNo such station in your project
409 station_name_mismatchname is not the station's connection name
409 migration_charger_not_proxiedThe proxy does not report this charger. Ask Ivora support, who roll it back for you
409 migration_rollback_pendingA rollback of this charger is already pending or waiting for its connection to Ivora to close (details.rollback_id)
409 migration_already_rolled_backThe charger is already routed to your previous platform and has no connection to Ivora

Follow the result and the reconnect

GET /v1/tenants/{tenant_id}/migration/rollbacks/{rollback_id}:

statusMeaning
pendingRecorded; the proxy has not switched the route yet
applied_socket_openThe proxy routes the charger to your previous platform (rolled_back_at), but its connection to Ivora did not close yet. The proxy keeps closing it; the rollback becomes applied once it is closed
appliedThe proxy routes the charger to your previous platform and no connection to Ivora is open
failedThe proxy could not switch it (detail). Ask again, or ask Ivora support, who roll it back by hand
supersededNot applied: Ivora staff moved the charger to Ivora again after you asked (for example after rolling it back by hand while the proxy was unreachable). Ask again if you still want it back
expiredThe proxy did not apply it within 24 hours (it could not reach Ivora). Ivora on-call rolls the charger back by hand; ask again once the proxy reports

A rollback that is still pending or applied_socket_open ten minutes after you asked alerts Ivora on-call, who then roll the charger back by hand within four business hours.

reconnect says whether the charger reconnected to your previous platform, from the proxy's reports after the switch:

reconnectMeaning
waiting_for_switchStill pending
reconnectingWithin two minutes of the switch, no connection to your previous platform reported yet
reconnectedA connection to your previous platform is up
not_connectedTwo minutes after the switch, no connection at all: check the charger on site, or with your previous platform
still_on_ivoraA connection to Ivora is still open: the proxy could not close it yet (also while applied_socket_open)
supersededThe charger was moved to Ivora again since
unknownThe proxy has not reported since the switch
nullThe rollback failed, was superseded or expired

Poll every few seconds, or subscribe to the event below and then read the rollback.

Event

migration.charger_rolled_back (stations:read) is sent once, when the proxy has switched the charger and no connection to Ivora is open (so never while the rollback is applied_socket_open):

{
  "rollback_id": "mrb_1f0e9c...",
  "station_id": 42,
  "name": "CP-0042",
  "previous": "ivora",
  "current": "previous_platform",
  "rolled_back_at": "2026-10-28T15:04:11+00:00",
  "reason": "Driver reported a failed start at bay 3",
  "requested_by": "user:3b1f...",
  "requested_at": "2026-10-28T15:04:05+00:00",
  "team_id": "team_9a2c...",
  "source": "tenant"
}

source is tenant for your own team and ivora when Ivora staff asked for it. A failed, superseded or expired rollback sends no event; read the rollback for it.

Audit log

Each request is recorded as migration.rollback_requested with who asked, the team, the station and the reason. Each later status is recorded as migration.rollback_<status>: applied_socket_open, applied, failed, superseded and expired (by system:migration). Every change in the proxy's routing is recorded as migration.proxy_routes_changed.

For Ivora staff

Ivora staff roll a charger back through the same route, with their own sign-in. The charger proxy reaches Ivora through two staff routes, called with the project's proxy key (migration:proxy, made by Ivora staff); they are not part of a project's integration:

RouteWhat the proxy does
PUT /v1/admin/tenants/{tenant_id}/migration/proxy-stateEvery few seconds: reports every charger it routes for the project (routing key, station, route, open connections, and route_changed_at, when it last moved the charger to that route by its own clock). The answer lists the rollbacks to apply
POST /v1/admin/tenants/{tenant_id}/migration/rollbacks/{rollback_id}/resultReports applied, applied_socket_open, failed or superseded once it acted. A result that cannot follow the current status is refused with 409 migration_rollback_settled

The report answers pending rollbacks, and applied_socket_open ones while the proxy still reports a connection to Ivora, so the proxy closes it again. Before applying one, Ivora and the proxy both check for a forward flip after the request: Ivora from the proxy's route report and the recorded site flips and route reports, the proxy from its own flip log. Either one marks it superseded instead. Ivora compares the request with the time the proxy sends in route_changed_at (a time ahead of Ivora's clock counts as the time Ivora received it), not with when the report arrived. A charger the proxy reports for the first time, or again after it stopped reporting it, without that time does not count as moved forward. A known charger is matched from Ivora's own record of the proxy's last report, so the report keeps working while the charging core is unavailable; a charger the core cannot confirm then is kept, not dropped.

Both routes keep working until the pilot's sync unit moves to the migration's runner channel: a runner credential with the single scope migration:routes (Migration portal). A rollback asked through a migration reaches the proxy on either channel.

Production notes

  • The proxy's key is the project's proxy key: it reaches these two routes and the QR route report of the pilot project only, and every other route refuses it. Keep it on the pilot proxy host only, never in a laptop or a shared vault entry, and revoke it when the pilot ends. Rotation and the replacement of an older staff key: Proxy keys.
  • On-call is paged by the API's ALERT migration_rollback_stuck line (one per rollback, after IVORA_MIGRATION_ROLLBACK_ALERT_MINUTES, ten by default) and by the production watch's count of rollbacks open for more than ten minutes (WATCH_ROLLBACK_MINUTES). Roll the charger back by hand on the proxy host with pilot rollback.
  • The deploy checklist (the database migration, the key, the proxy files, its pilot.portal block and service, the lab rehearsal) is in the pilot proxy runbook in Ivora's ivora-migrate repository: pilot/README.md, "Production deploy checklist".