Charging Stations
Provisioning, credentials, and lifecycle for charging stations — both OCPP 1.6J and 2.x (see e.g. the get-variables/set-variables and device-model endpoints under Commands/Settings, and each charging station's own ocpp_version field). User reads; Admin provisions, deprovisions, unlinks, rotates credentials, and manages pairing and topology.
16 endpoints
Fetches a single charging station's detail.
get/v1/charging-stations/{chargingStationId}Requires a bearer token
Requires the caller to be at least a Member of the charging station's
organization. bootReport/createdAt/updatedAt may read null for
a station this response resolved through a path with no boot history
available — see [ChargerSummary]'s own field docs. A station's OCPP
boot-handshake decision (Accepted/Pending/Rejected) is never part of
this response.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
Responses
| Status | Body | Description |
|---|
| 200 | ChargerSummary | The charging station |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No charging station with this id exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | asset-service is not configured in this environment |
Deprovisions a charging station.
delete/v1/charging-stations/{chargingStationId}Requires a bearer token
A soft delete: the row, and everything hanging off it (EVSEs,
connectors, transaction history), stays intact and visible through this
API. What actually changes is that the charging station's credential
stops verifying, so it can no longer open a *new* connection — an
already-open connection is not forcibly closed by this alone.
Idempotent: deprovisioning an already-deprovisioned charging station is
not an error and keeps its original disabledAt. Requires the caller
to be an Owner or Admin.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
Responses
| Status | Body | Description |
|---|
| 200 | ChargerSummary | The deprovisioned charging station |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No charging station with this id exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | The internal asset-tracking component is unreachable (assetServiceUnavailable) |
Lists a charging station's boot history, most recent first.
get/v1/charging-stations/{chargingStationId}/boot-reportsRequires a bearer token
Requires the caller to be at least a Member of the charging station's
organization — a read-only diagnostic. Repeated entries minutes apart
are a reboot loop; an entry whose firmwareVersion differs from its
predecessor is a firmware change.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
| page | query | integer<int32> | 1-indexed page number. Defaults to 1. |
| perPage | query | integer<int32> | Boot reports per page, capped at 100. Defaults to 20. A larger value
is clamped to 100 rather than rejected. |
Responses
| Status | Body | Description |
|---|
| 200 | ListBootReportsResponse | A page of the charging station's boot notification history, most recent first |
| 400 | ErrorBody | An unrecognised or malformed query parameter |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No charging_station with this id exists, or you cannot access its environment |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | asset-service is not configured in this environment |
Reports how a charging station is connected.
get/v1/charging-stations/{chargingStationId}/connectivityRequires a bearer token
Requires the caller to be at least a Member of the charging station's
organization — a read-only diagnostic. links holds only what the
station itself has reported, so an empty list means it has never said
— not that it has no connection. Each link carries when the station
last reported it; an active link is a claim about that moment, not a
live measurement.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
Responses
| Status | Body | Description |
|---|
| 200 | ConnectivityResponse | How this charging station reaches the platform |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No charging_station with this id exists, or you cannot access its environment |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | asset-service is not configured in this environment |
Rotates a charging station's authorization key.
post/v1/charging-stations/{chargingStationId}/credentialRequires a bearer token
Returns the fresh one-time key. The previous key stops verifying
immediately. Requires the caller to be an Owner or Admin.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
Responses
| Status | Body | Description |
|---|
| 200 | RotateCredentialResponse | The charging station's freshly generated one-time authorization key |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No charging station with this id exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
Reports where a charging station's registration stands.
get/v1/charging-stations/{chargingStationId}/registrationRequires a bearer token
Current status, current step, when each completed step completed,
attempt count, and the most recent failure with what the station said.
Requires the caller to be at least a Member of the charging station's
organization — a read-only diagnostic, same bucket as reading the
station itself.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | ChargingStation id |
Responses
| Status | Body | Description |
|---|
| 200 | RegistrationResponse | The station's registration standing |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No charging_station with this id exists, or you cannot access its environment |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | asset-service is not configured in this environment |
Reports what tariffs a charging station currently has installed.
get/v1/charging-stations/{chargingStationId}/tariffsRequires a bearer token
Issues GetTariffs to the station live, over a fresh round-trip to
the station itself, and returns its answer directly — this is what
the station actually thinks it has, not the platform's own record of
what it meant to send (GET .../tariffs for that). Because it
depends on the station, it can fail in ways a plain catalog read
cannot — an offline station, or one that does not support the
message — and is slower than the endpoints around it.
Parameters
| Name | In | Type | Description |
|---|
| chargingStationId* | path | string<uuid> | Charging station id |
| evseId | query | integer<int32> | Which EVSE to ask about; defaults to 0 (the whole station). |
Responses
| Status | Body | Description |
|---|
| 200 | GetStationTariffsResponse | The station's own answer to GetTariffs |
| 400 | ErrorBody | An unrecognised or malformed query parameter |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No charging_station with this id exists, or you cannot access its environment |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | The energy pricing service is unreachable |
Lists an environment's charging stations, paginated.
get/v1/environments/{environmentId}/charging-stationsRequires a bearer token
Each entry carries its live connection status and lastSeen
timestamp. Pass status to restrict the page (and total) to one
bucket — online/offline (computed from a live connectivity check,
one round trip per candidate) or faulted/neverConnected (always an
empty page today — no data source can compute either bucket yet). Pass
q to further restrict the page (and total) to charging stations
whose chargePointId case-insensitively contains it (composes with
status — both narrow the same listing). Requires the caller to be at
least a Member of the environment's organization.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| page | query | integer<int32> | 1-indexed page number. Defaults to 1. |
| perPage | query | integer<int32> | ChargingStations per page, capped at 100. Defaults to 20. A larger
value is clamped to 100 rather than rejected. |
| status | query | "online" | "offline" | "faulted" | "neverConnected" | Restrict the listing to one status bucket (online, offline,
faulted, neverConnected) instead of every charging_station.
Omitted returns every charging_station in the environment.
Inlined rather than $ref'd: IntoParams does not pull a
parameter's enum into components.schemas the way a response
body's ToSchema does, so a bare reference here would emit a
$ref to a component that is never written. |
| q | query | string | Free-text filter over chargePointId, matched case-insensitively
as a substring — q=100 matches a charging_station whose id is
CP-100-A. Composes with status (both narrow the same listing)
and with pagination (page/perPage/total describe the
filtered set). Omitted, empty, or whitespace-only behaves as no
filter at all. |
Responses
| Status | Body | Description |
|---|
| 200 | ListChargersResponse | A page of the environment's charging_stations |
| 400 | ErrorBody | An unrecognised or malformed query parameter |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No environment with this id exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | asset-service is not configured in this environment |
Provisions a new charging station, returning its one-time key.
post/v1/environments/{environmentId}/charging-stationsRequires a bearer token
Requires the caller to be an Owner or Admin of the environment's
organization — provisioning a charging station is the same bucket as
environment management. Enforces the organization's plan-level charger
cap before minting the station; see the 402 response below.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
Request bodyCreateChargerRequest
| Field | Type | Description |
|---|
| chargePointId* | string | — |
| currentType | string | null | AC or DC, the station's billable class. AC when omitted;
anything else is 422 invalidCurrentType. |
Responses
| Status | Body | Description |
|---|
| 201 | CreateChargerResponse | The newly created charging station, plus its one-time authorization key |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 402 | ErrorBody | chargerLimitReached: the organization's plan caps active stations and the fleet is already at that cap |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No environment with this id exists, or the caller cannot access it |
| 409 | ErrorBody | A charging station with this charge point id already exists |
| 422 | ErrorBody | invalidCurrentType: currentType was neither AC nor DC |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | billingServiceUnavailable (the cap could not be checked) or assetServiceUnavailable |
Reports each Easee-imported charger's OCPP commissioning progress.
get/v1/environments/{environmentId}/easee/claims/{claimId}/commissioningRequires a bearer token
Read-only — never triggers a commissioning attempt. A charger stuck
short of commissioned can be nudged with POST .../commissioning/retry.
Requires the caller to be at least a Member of the environment's
organization, since this is status display, not a mutation.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Responses
| Status | Body | Description |
|---|
| 200 | GetCommissioningStatusResponse | Per-charger commissioning status |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 404 | ErrorBody | No environment with this id exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee commissioning is not configured |
Manually re-runs commissioning for a claim's unfinished chargers.
post/v1/environments/{environmentId}/easee/claims/{claimId}/commissioning/retryRequires a bearer token
Includes one standing in awaitingOperatorSelection, once an installer
has separately reassigned the site's Easee operator. Manual
counterpart to GET .../commissioning's status display: re-attempts
commissioning for whichever of the claim's chargers have not reached
commissioned yet, rather than waiting for the next automatic attempt.
Requires the caller to be an Owner or Admin of the environment's
organization.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Responses
| Status | Body | Description |
|---|
| 200 | RetryCommissioningResponse | Commissioning re-ran |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No environment or claim with these ids exists, or the caller cannot access it |
| 409 | ErrorBody | This claim's environment could not be resolved |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached, or commissioning is not configured |
Records where this Easee site belongs in Flowion, then imports it.
post/v1/environments/{environmentId}/easee/claims/{claimId}/mappingRequires a bearer token
Third step of the Easee integration lifecycle: commits the target
site/circuit mapping an operator chose after reviewing GET
.../topology, then imports the site — one charging_station per Easee
charger found on it. After this, GET .../commissioning and POST
.../commissioning/retry track and retry per-charger OCPP
commissioning. Requires the caller to be an Owner or Admin of the
environment's organization — same bucket as pairing itself.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Request bodyApplyEaseeMappingRequest
| Field | Type | Description |
|---|
| circuits | array<CircuitMappingRequest> | — |
| flowionSiteId | string | null | — |
| newSiteName | string | null | — |
Responses
| Status | Body | Description |
|---|
| 200 | ApplyEaseeMappingResponse | The mapping was applied and the site imported |
| 400 | ErrorBody | invalidSiteTarget: no usable site target was given |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 402 | ErrorBody | chargerLimitReached: importing the mapped circuits would take the organization past its plan's charger cap |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | claimNotFound: no such environment or claim |
| 409 | ErrorBody | claimNotEligible: this claim has already been mapped, or is being unlinked |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached (vendorUnreachable), pairing is not configured (integrationEaseeServiceUnavailable), or the charger cap could not be checked (billingServiceUnavailable/assetServiceUnavailable) |
Re-runs whole-site import against a claim's current Easee topology.
post/v1/environments/{environmentId}/easee/claims/{claimId}/reconcileRequires a bearer token
Later step of the Easee integration lifecycle, for a site already
imported by POST .../mapping: re-fetches the site's current Easee
topology and imports whatever changed there since (a charger added or
removed at Easee's side), rather than requiring the whole claim to be
unlinked and re-paired. Requires the caller to be an Owner or Admin of
the environment's organization — same bucket as pairing itself.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Responses
| Status | Body | Description |
|---|
| 200 | ReconcileEaseeResponse | Reconciliation ran |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 402 | ErrorBody | chargerLimitReached: the organization's plan caps active stations and the fleet is already at that cap |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No environment or claim with these ids exists, or the caller cannot access it |
| 409 | ErrorBody | claimNotEligible: the claim is not currently eligible for reconciliation |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached (vendorUnreachable), reconciliation is not configured (integrationEaseeServiceUnavailable), or the charger cap could not be checked (billingServiceUnavailable/assetServiceUnavailable) |
What Easee reports for a claimed site, before any of it is imported.
get/v1/environments/{environmentId}/easee/claims/{claimId}/topologyRequires a bearer token
Second step of the Easee integration lifecycle, after POST
.../easee/pair claims the site: this is a read-only preview of the
site's chargers/circuits as Easee sees them, meant to be reviewed
before POST .../mapping commits an import from it. Requires the
caller to be an Owner or Admin of the environment's organization —
same bucket as pairing itself.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Responses
| Status | Body | Description |
|---|
| 200 | EaseeTopologyResponse | The Easee site's topology |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No such environment or claim |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached, or pairing is not configured |
Releases a claimed Easee site.
post/v1/environments/{environmentId}/easee/claims/{claimId}/unlinkRequires a bearer token
Disables OCPP at Easee for every present known charger under the claim,
then moves it to unlinked once all of them succeed. Safe to call
again if a previous call left the claim unlinking — this is the same
one action for both "unlink" and "retry a partial unlink", no separate
resume endpoint.
Final step of the Easee integration lifecycle: offboards a claim
created by POST .../easee/pair, ending its chargers' OCPP
commissioning at Easee rather than deleting anything on this side —
deprovisioning each imported charging station (if wanted) is a
separate, explicit DELETE /charging-stations/{id} per station.
Requires the caller to be an Owner or Admin of the environment's
organization — same bucket as pairing/reconciliation.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
| claimId* | path | string<uuid> | Easee site claim id |
Responses
| Status | Body | Description |
|---|
| 200 | UnlinkEaseeResponse | Unlinking ran (or has already completed) |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No environment or claim with these ids exists, or the caller cannot access it |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached, or unlinking is not configured |
Pairs an Easee charger by serial number and PIN.
post/v1/environments/{environmentId}/easee/pairRequires a bearer token
Claims the charger's site for this environment. First step of the
Easee integration lifecycle: pair (this endpoint) creates a site claim
for the site the given charger belongs to,
then GET .../topology previews what Easee reports for that site,
POST .../mapping records where it belongs in Flowion and imports it
(one charging_station per Easee charger on the site), GET
.../commissioning and POST .../commissioning/retry track and retry
per-charger OCPP commissioning after import, POST .../reconcile
re-imports against Easee's current topology after a vendor-side change,
and POST .../unlink offboards the whole claim. Requires the caller to
be an Owner or Admin of the environment's organization — same bucket as
provisioning a generic charger.
Parameters
| Name | In | Type | Description |
|---|
| environmentId* | path | string<uuid> | Environment id |
Request bodyPairEaseeRequest
| Field | Type | Description |
|---|
| pin* | string | — |
| serialNumber* | string | — |
Responses
| Status | Body | Description |
|---|
| 200 | PairEaseeResponse | The Easee site was claimed |
| 401 | ErrorBody | Missing, invalid, or expired bearer token |
| 402 | ErrorBody | chargerLimitReached: the organization's plan caps active stations and the fleet is already at that cap |
| 403 | ErrorBody | The caller is a member but not an Owner or Admin |
| 404 | ErrorBody | No environment with this id exists, or the caller cannot access it, or the serial is unknown (unknownSerial) |
| 409 | ErrorBody | The site is already claimed, by this environment or another Easee operator (siteClaimedElsewhere/siteOwnedByAnotherEaseeOperator) |
| 422 | ErrorBody | wrongPin: the PIN does not match |
| 429 | ErrorBody | The caller has exceeded its request budget. error is rateLimited. Wait Retry-After seconds before retrying — a prior successful response's own RateLimit-Remaining/RateLimit-Reset headers show this coming before it happens. |
| 500 | ErrorBody | An unexpected internal error. error is always internalError; message is deliberately the fixed string "an unexpected error occurred", never the real cause, which is logged server-side instead of being returned to the caller. |
| 503 | ErrorBody | Easee could not be reached (vendorUnreachable), pairing is not configured (integrationEaseeServiceUnavailable), or the charger cap could not be checked (billingServiceUnavailable/assetServiceUnavailable) |