You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Stripe payment columns removed. The database migration drops the old stripe_* columns that the provider-neutral payment columns replaced in v0.1.38 and v0.1.39 (payment records, saved payment methods, guest sessions, site payment configs, drivers). Pods older than v0.1.39 still use these columns. Upgrade to v0.1.39 first, then to v0.1.40. After this migration you cannot roll back below v0.1.39.
Redis ACL update required. Reports are now generated by the worker. The API, OCPP and worker Redis users need the new report_generate channel, and the worker user needs read access to the OCPP connection registry (ocpp:conn:*) for the new offline sweep. Upgrade the Helm chart or the CDK stack together with the images. With an older ACL, report generation and the offline sweep fail with NOPERM. Docker Compose picks up the new rules automatically.
Rate-limited requests answer RATE_LIMITED. A 429 response now carries code RATE_LIMITED instead of VALIDATION_ERROR, with the message "Too many requests. Wait a moment and try again." Integrations that match on the error code need to handle RATE_LIMITED.
NEVI reports need a quarter and year.POST /v1/reports/generate and report schedules for the nevi type without a quarter (1 to 4) and a four-digit year are refused with 400 VALIDATION_ERROR. Before, the report failed later.
NEVI reports are always xlsx. NEVI always produced the EV-ChART workbook, but a request for csv or pdf stored and served it under that format. The report is now stored as xlsx, and the download answers with the xlsx content type. Clients that requested another format for NEVI should request xlsx.
System notifications are always on.PUT /v1/system-event-settings no longer takes isEnabled (the field is dropped, the setting is not changed), and the CSMS never skips a system event. The upgrade re-enables every stored disabled system event. API clients and scripts that turned a system event off should stop sending isEnabled.
Access-critical driver notifications cannot be turned off.driver.ForgotPassword, driver.AccountVerification, driver.PortalInvite and mfa.VerificationCode are always on and reach the driver regardless of their notification preferences. PUT /v1/driver-event-settings refuses to turn one off with 400 NOTIFICATION_EVENT_REQUIRED, and the upgrade re-enables any stored disabled row for them.
OCPI partner sync accepts only pullable modules.POST /v1/ocpi/partners/:id/sync/:module accepts only locations, tariffs and cdrs. tokens and sessions now return 400 VALIDATION_ERROR. Before, the request returned 200 and did nothing. Drop those calls.
Permission catalog response changed.GET /v1/permissions returns { resource, kind, labelKey, permissions } per group instead of { label, permissions }. kind is page or settings, and labelKey is a dashboard locale key. Clients that displayed label should use resource or translate labelKey.
No more nightly images. The nightly release channel is removed. The nightly image tag no longer moves and stays on the last nightly build. Prereleases use the alpha and beta channels. Deployments that track nightly should pin a version or move to stable, beta or alpha.
Upgrade notes
Upgrade path. Upgrade through v0.1.39 (see the Stripe column change above). Upgrade Helm or CDK with the images for the Redis ACL change.
Prepaid cost ceiling. A prepaid token's balance at session start is now the session's cost ceiling. The session is billed and debited at most that amount, so time and idle fees an OCPP 2.1 station accrues while suspended at maxCost no longer push the balance below zero. The CSMS stops an OCPP 1.6 session at the meter reading that reaches the ceiling, and an OCPP 2.1 session only when the station ignored maxCost, with stopped reason PrepaidCreditExhausted.
Sessions active during the upgrade: the migration gives every active prepaid session without a ceiling its token's current balance as the ceiling, so these sessions are capped and stopped like new ones.
During a rolling OCPP upgrade, a prepaid OCPP 1.6 session started on a v0.1.39 pod after the migration ran has no ceiling. It is billed in full and can take the balance below zero. Avoid starting prepaid OCPP 1.6 sessions during the rollout, or scale OCPP to 0 before the upgrade. An OCPP 2.1 session started in that window still has the station's maxCost, but time and idle fees accrued while suspended are billed in full.
While v0.1.39 and v0.1.40 OCPP pods run side by side, a v0.1.39 pod that stops a capped OCPP 2.1 prepaid session records the reason GuestHoldExhausted instead of PrepaidCreditExhausted. Only the label differs. Billing, the debit and notifications are the same.
Prepaid ceiling migration. Migration 0157_prepaid_session_cost_ceiling sets the ceiling on active prepaid sessions as described above. It is idempotent and touches only active, non-free-vend sessions without a ceiling.
Leftover plaintext credential rows removed. Migration 0158_drop_suffixless_secret_settings deletes settings rows stored under plaintext credential key names (for example s3.accessKeyId and sso.cert, left by the first migration). Every credential is read from its encrypted *Enc key, so nothing read these rows. Enter credentials in the dashboard, not by writing those keys.
Bill session migration. A metadata-only migration adds the session re-bill columns and the session audit log. New error codes: SESSION_REBILL_NOT_ELIGIBLE, SESSION_REBILL_PAYMENT_PENDING, SESSION_REBILL_IN_PROGRESS, NOTIFICATION_EVENT_REQUIRED.
Date formats. Dates follow the selected UI language or the recipient's language. English dates change from 1/15/2026, 2:30:45 PM to Jan 15, 2026, 2:30:45 PM, and notification dates drop the seconds. Station screens show the reservation end in the site time zone. Thanks to Marco Spittka (#35).
New user role defaults. The Create User page now starts a new user with the same role defaults the server uses. Before, it gave operators conformance:write, reports:write, logs:write, sustainability:write and audit:write beyond the server defaults. Operators created in the dashboard before this release may still hold those five write permissions. Existing users are not changed. Admins can review and remove them on the Users page.
Portal map default view. When a Google Maps default view setting is missing or not a number, the portal map falls back to the seeded default: the center of the US (39.8283, -98.5795) at zoom 4. Before, it fell back to San Francisco at zoom 12. Set the default view under Settings if you relied on the old fallback.
Reports run in the worker. The worker must run for reports to complete. Pending reports are queued again after 2 minutes, and reports still generating after 30 minutes are marked failed.
Deprecated.GET and PUT /v1/system-event-settings still work but have no effect on dispatch. They will be removed in the next release.
Features
Sessions and billing
Bill session. Operators can bill a session the CSMS could not end (stopped reason EndRequestFailed) with the Bill session action on the session detail (POST /v1/sessions/:id/rebill, requires sessions:write and payments:write). The cost is recomputed from the meter values and charged to the driver's default saved card or prepaid balance. A session that cannot be charged (no saved card, a guest, a declined card or one that needs 3D Secure) is marked for manual billing and listed by the new Manual billing filter. Each billing is recorded on the session's History tab.
Session end failure alert. Operators with sessions:write and access to the site get a Session End Failed alert when the CSMS gives up ending a session after repeated failed end requests.
Below-minimum sessions. When a session costs less than the payment provider's minimum charge, the hold is released and the receipt says nothing was charged. Before, the capture failed and the hold stayed open until it expired.
Notifications
Driver notification switches. Operators turn each driver notification type on or off on the Driver Events tab. Access-critical types are locked on.
Complete OCPP event list. Every OCPP event the dashboard lists now sends notifications. Before, only 12 of 39 did. Events are grouped as common, OCPP 1.6 only (including DiagnosticsStatus) and OCPP 2.1 only.
Complete driver and system event lists. The Driver Events tab now includes token, maintenance and station watch events, and GET /v1/ocpp-event-types lists every driver and system event in the right group.
Stations and operations
Offline sweep. A station whose OCPP process stopped without closing the connection is now marked offline within about 16 minutes at the default heartbeat interval. Before, it stayed online until it reconnected.
Report types endpoint.GET /v1/reports/types lists the report types, their formats and whether the dashboard offers them.
Localized dates. Dates and times in the dashboard, portal and notifications follow the selected language (#35).
Fixes
Payments
A lost database connection during session settlement no longer leaves an Adyen hold adjustment unresolved. The daily reconciliation re-sends an unanswered adjustment after 1 hour with the same idempotency key.
A stale adjustment claim is taken over atomically before it is sent again.
Saving Stripe settings with an empty publishable key now clears the stored key.
The demo data gives the first demo driver an always-approved simulated card, so the seeded re-bill session can be billed.
Adyen webhook Basic auth is compared without hashing, and role matching runs in linear time.
OCPP and sessions
Session start, update, end, meter values and settlement processing now retry safely after a lost database connection, so a reconnect storm after an OCPP restart no longer drops a session start, end, cost or settlement.
A session is marked faulted before its payment stop is sent, so a crash between the two no longer leaves it active.
A session whose payment gate fails still finishes its start processing.
No hold is placed when no payment provider is active.
An OCPP 1.6 start links only to a waiting remote start on the same connector.
OCPP 2.1 transaction limits are sent only for the limit types the station reports in TxCtrlr.SupportedLimits.
The simulator's TLS reachability probe verifies the server certificate.
API
POST /v1/cache/flush required a permission that did not exist, so every call returned 403. It now requires settings.system:write.
Report generation no longer stalls the API for large reports.
A report schedule without a creator no longer fails.
Support case attachments require a non-empty S3 bucket and region.
An empty encrypted setting is read as unset. S3 attachment storage without access keys now uses the default AWS credential chain (such as an ECS task role) instead of reporting that storage is not configured, and reCAPTCHA enabled without a secret key reports a clear error.
Reservation end times are passed to notifications as timestamps and formatted for the recipient.
Dashboard and portal
Pages that read feature flags or company branding no longer fail for users without settings permissions.
The permission editor shows group names and Read/Write labels in the UI language.
Report type load errors are shown.
A 429 on sign-in shows the rate limit message instead of "invalid credentials".
The emailed verification link verifies a signed-out driver, and the account verification email includes the link.
Account and email verification failures show the API error.
The MFA code input has an accessible name, a numeric keypad and one-time code autofill.
The page language attribute follows the UI language, and accessible names are translated.
Session, power and sustainability charts show times and labels in the UI language and the user's time zone.
Traditional Chinese uses the standard term for driver.
Conformance
OCTT test replies in TC_I_105, TC_O_06 and TC_K_43/44 are schema-valid.
A CSMS conformance run leaves the stations of a running charging station run alone, and charging station runner stations get IDs the station routes accept.
Changelog
Features
add session re-billing, notification toggles and retry-safe session projections (6461c07)
(lib): format dates and times in a given locale (a4bc56b)
Bug Fixes
(api): read empty encrypted settings as unset so S3 uses the task role (099734c)
(database): seed an always-approved card for the re-bill demo driver (7289465)
Adyen auth compare and role matching, TLS probe certificate checks (1838d59)
session receipt says nothing was charged when the hold is released below the minimum (d805a7d)
release holds below the capture minimum, page language, MFA keypad and autofill (b2c93fa)
signed-out email verify, portal chart times and numbers, MFA input label, clear Stripe key (c156997)
NEVI report format, rate-limit messages, verify link, chart times; drop nightly channel (cbcfe88)
(octt): keep CS conformance stations during a CSMS run and list all agent skills (b26d9e1)
(api): pass the reservation end to notifications as a timestamp (a08f4ae)
(portal): format dates in the selected UI language (f422450)
(csms): format dates in the selected UI language (e95a8a7)
(services): show the reservation end in the site time zone on displays (39056c3)
(notifications): format dates in the recipient language (f7ebb67)
Tests
(lib): compare German relative times with the runtime ICU output (d7e5072)
Other Changes
feat!: worker-generated reports, RATE_LIMITED on 429, NEVI filter checks, stripe_* column drop (375fd25)