Log inTalk to us
Charger management

Session limits

A session you start from a bill can carry one limit: a maximum energy, or a maximum amount at the bill's price. Ivora watches the session's meter values and stops it when it reaches the limit. Prepaid and pay-in-store flows use it: take the payment, then start a session that ends at what was paid for.

The limit is a stop control, not a price. The bill still prices the energy the charger actually delivered, at its tariff, exactly as it would without a limit. Some energy usually flows after the stop, so a session can end slightly above its limit. Ivora reports that overrun with the final totals.

Set a limit at start

Send limit in the body of either start call:

StartRouteScopes
Managed billPOST /v1/tenants/{tenant_id}/bills/{bill_id}/startbilling:write, stations:control
Application-managed sessionPOST /v1/tenants/{tenant_id}/charging-sessions/{session_id}/startbilling:write, stations:control, settlement:write

Set exactly one of these:

{"limit": {"energy_kwh": "12.5"}}
{"funding_confirmed": true, "limit": {"amount_minor": 1500, "currency": "USD"}}
FieldRules
energy_kwhAbove 0 and at most 500 kWh, with at most 3 decimal places (1 Wh). A decimal string or a JSON number
amount_minor1 to 100000 minor units of the bill's currency (up to $1,000 in USD or CA$1,000 in CAD)
currencyRequired with amount_minor. It must be the bill's tariff currency, otherwise 422 limit_currency_mismatch

The limit is checked before the start is journaled: a refused limit answers 422 and creates no operation, so you can retry with the same Idempotency-Key. A retry with the same key and the same limit replays the original start. A different limit under that key answers 409 idempotency_key_reused. A start without limit has no limit, as before. A limit is set once, at start. It cannot be changed or removed later. You can still stop the session yourself at any time.

Limits are available on bill starts only. The plain station start command has no bill, tariff or receipt, so it takes no limit. A managed bill that starts itself when the driver returns from hosted checkout has no limit either: to use a limit, start that bill yourself.

Amount limits

An amount converts to energy once, when the start is reserved, at the bill's per-kWh rate (rate_minor, frozen with the bill when it was created): energy_kwh = amount_minor / rate_minor, rounded down to the Wh. The limit record shows the rate it used and the energy cap it enforces.

Only the energy rate counts. Session fees, time-based fees and idle or parking fees are not counted against the amount. On a tariff with those fees, the final amount can exceed the limit by them. overrun_minor reports the difference. On a tariff with time-of-day energy prices, the conversion uses the bill's base rate. A bill with no energy price (a free tariff) refuses an amount limit with 422 limit_unpriced; use energy_kwh. An amount that buys less than 1 Wh answers 422 limit_too_small. An amount that buys more than 500 kWh at the rate (the most an energy limit can be) answers 422 limit_too_large; Ivora never caps it silently, so set a smaller amount or an energy_kwh limit.

How Ivora stops the session

Every OCPP version is stopped the same way, from the server. Ivora reads the session's energy, its current power and the charger's meter interval. It sends the stop when:

delivered + expected until the next meter value + margin >= limit
  • delivered: the transaction's energy so far, in kWh.
  • expected: the current power multiplied by the interval between the charger's two latest meter values (60 seconds when unknown). Ivora's check runs about every 15 seconds, so the interval is never taken as shorter than that. Without a reported power, Ivora uses the energy rate between the two latest registers.
  • margin: an extra energy allowance set for the environment, 0 kWh by default.

The stop is the ordinary stop command: RemoteStopTransaction on OCPP 1.6, RequestStopTransaction on OCPP 2.0.1 and 2.1. Ivora does not send charger-side transaction limits. If the transaction is still active a minute after a stop, Ivora sends the stop again, up to three attempts in all. On an application-managed session the stop is the session's single stop operation: the session reads stopping, and your own stop call answers 409 stop_already_reserved. If you stopped the session first, Ivora does not send a second stop.

If the charger still has not ended the transaction a minute after the third stop, Ivora stops retrying and raises a session_limit_unanswered alert for its operators: the session is still charging past its limit. From then on your own stop call is accepted again on an application-managed session. The alert resolves when the transaction ends or the bill is final.

Ivora sends a stop only when meter values arrive. A charger that reports no meter values during the session is never stopped by a limit. Set a meter interval on the charger (MeterValueSampleInterval on OCPP 1.6, the SampledDataCtrlr interval on 2.x) for a closer stop.

Read the outcome

Every bill read, and the bill inside a charging-session read, carries limit:

{
  "type": "amount",
  "energy_kwh": "42.857",
  "energy_wh": 42857,
  "amount_minor": 1500,
  "currency": "USD",
  "rate_minor": "35.00",
  "stop_reason": "limit_reached",
  "stop_requested_at": "2026-10-21T09:41:12+00:00",
  "stop_energy_kwh": "42.61",
  "stop_operation": {"id": "op_…", "status": "succeeded", "result": {"reason": "limit_reached"}},
  "final_energy_kwh": "42.874",
  "final_amount_minor": 1501,
  "overrun_kwh": "0.017",
  "overrun_wh": 17,
  "overrun_minor": 1
}
FieldMeaning
stop_reasonlimit_reached once Ivora decided to stop the session at its limit; null while the session runs below it, or when it ended another way
stop_energy_kwhThe energy delivered when Ivora decided to stop
stop_operationThe latest stop Ivora sent. succeeded means the charging core accepted the command. The transaction ending confirms the stop
final_energy_kwh, final_amount_minorSet once the bill is final: the billed energy and total, fees included
overrun_kwh, overrun_whFinal energy minus the energy cap, never below 0
overrun_minorAmount limits: final amount minus the limit, never below 0

Energy is a kWh decimal string with an integer Wh beside it, as everywhere in the API. Raw OCPP 1.6 meter registers are Wh. Ivora converts them, and the transaction's own energy is already kWh.

The same limit travels in the receipt data: the final bill, which bill.finalized and the charging-session read carry.

Events

EventWhenPayload
bill.limit_reachedOnce per bill, when Ivora's first stop is acceptedbill (with limit), session_id (application-managed sessions, else null), transaction_id
bill.finalizedThe bill is finalbill with limit, including the final totals and overrun
charging_session.status_changedAn application-managed session's status changes, for example to stoppingsession with bill.limit

The stop itself is also an operation.completed event under the bill scope. See Webhooks and events.