Simulate a tariff draft against a session

post/v1/tenants/{tenant_id}/tariffs/simulate
Requires an API key

Stateless: validates a tariff definition exactly as tariff creation does (422 tariff_invalid with every problem in details.errors) and prices the session with the billing function, without storing anything. Use it to build and check a tariff before creating it.

Path parameters

  • tenant_idintegerRequired

Request body

  • tariffTariffDefinitionInputRequired
    A tariff to simulate without storing it.
    Child attributes
    • currencystringRequired
      Pattern ^[A-Z]{3}$
    • elementsarray of TariffElementRequired
      OCPI 2.2.1 TariffElements, the native tariff format. For each moment of a session the first element that prices a dimension and whose restrictions all hold applies. Overlapping time windows must nest (narrower first) and an element may not hide a later one.
      Child attributes
      • price_componentsarray of PriceComponentRequired
        Child attributes
        • typeenumRequired
          ENERGY: price per kWh. TIME: price per hour while charging. PARKING_TIME: price per hour idle (connected, not charging). FLAT: a fee per session (per reservation in a reservation element). Bills tell charging from idle time from the charger's reports and charge TIME and PARKING_TIME accordingly; when a session has too little data, all of it is charging time.
          One of ENERGY, TIME, PARKING_TIME, FLAT
        • pricenumberRequired
          Major units excluding tax, at most 4 decimal places (OCPI): 0.35 is $0.35 per kWh.
          Minimum 0 · Maximum 10000
        • step_sizeinteger
          OCPI step size: ENERGY in Wh, TIME and PARKING_TIME in seconds; the dimension's total rounds up to a multiple of the last billed element's step. 1 bills the metered quantity exactly. Ignored for FLAT.
          Default 1 · Minimum 1 · Maximum 86400
      • restrictionsobject | null
        OCPI 2.2.1 TariffRestrictions, evaluated in the tariff's local time. All given restrictions must hold. min values are inclusive, max values and end times/dates exclusive; an end_time before its start_time wraps midnight.
        Child attributes
        • start_timestring | null
          Local time of day (HH:MM) from which the element applies.
          Pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$
        • end_timestring | null
          Local time of day (HH:MM) until which the element applies (exclusive).
          Pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$
        • start_datestring | null
          Local date (YYYY-MM-DD) from which the element applies.
          Pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
        • end_datestring | null
          Local date (YYYY-MM-DD) until which the element applies (exclusive).
          Pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
        • min_kwhnumber | null
          Energy already charged in the session, kWh (inclusive).
          Minimum 0 · Maximum 100000
        • max_kwhnumber | null
          Energy already charged in the session, kWh (exclusive).
          Minimum 0 · Maximum 100000
        • min_currentnumber | null
          Charging current, A (inclusive). An element restricting current never applies when the current is unknown.
          Minimum 0 · Maximum 10000
        • max_currentnumber | null
          Charging current, A (exclusive).
          Minimum 0 · Maximum 10000
        • min_powernumber | null
          Charging power, kW (inclusive). Unknown power matches no power-restricted element.
          Minimum 0 · Maximum 10000
        • max_powernumber | null
          Charging power, kW (exclusive).
          Minimum 0 · Maximum 10000
        • min_durationinteger | null
          Session duration so far, seconds (inclusive).
          Minimum 0 · Maximum 604800
        • max_durationinteger | null
          Session duration so far, seconds (exclusive).
          Minimum 0 · Maximum 604800
        • day_of_weekarray of enum | null
          Local days on which the element applies.
        • reservationenum | null
          Prices a reservation (TIME: reserved time, FLAT: reservation fee) instead of charging; RESERVATION_EXPIRES only when the reservation expires unused.
          One of RESERVATION, RESERVATION_EXPIRES
    • tariff_alt_textarray of AltText | null
      Driver-facing descriptions (OCPI tariff_alt_text), at most one per language. Omit to have Ivora generate an English one from the elements; a tariff too complex to describe in 512 characters is refused unless you supply it.
      Child attributes
      • languagestringRequired
        ISO 639-1 language code.
        Pattern ^[a-z]{2}$
      • textstringRequired
        Driver-facing description of the tariff.
        1–512 characters
    • rulesobject | null
      Ivora billing rules applied after the elements, in this order, and never published over OCPI: partners see the elements and tariff_alt_text only.
      Child attributes
      • group_discountsarray of GroupDiscount
        Member/RFID group discounts: the largest matching one applies; they never stack.
        Child attributes
        • idstringRequired
          Your name for this discount; shown on quote and bill adjustments.
          Pattern ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$
        • groupsarray of string
          Member or RFID groups (the session's group) the discount applies to.
        • id_tokensarray of string
          RFID or app tokens (the session's id_token) the discount applies to.
        • percent_offintegerRequired
          Minimum 1 · Maximum 100
      • merchant_validationobject | null
        A discount when the session carries a merchant validation code.
        Child attributes
        • percent_offinteger | null
          Minimum 1 · Maximum 100
        • amount_off_minorinteger | null
          Integer minor units off, never below 0.
          Minimum 1 · Maximum 10000000
        • codesarray of string
          Accepted validation codes; empty accepts any code the session carries.
      • max_session_cost_minorinteger | null
        Cap on a session's total, integer minor units.
        Minimum 1 · Maximum 100000000
      • prepaid_limitboolean
        Report, on quotes for sessions with prepaid_balance_minor, how much the balance covers and whether the session reaches it. It never changes the total; your application stops or tops up.
        Default false
    • time_zonestring | null
      IANA time zone of the restrictions' local times. Omit to use the station location's time zone when billing (UTC without one).
      Up to 64 characters
  • sessionSessionProfileRequired
    A charging session to price. Energy is cumulative kWh: energy_kwh spreads evenly over duration_minutes, or energy_curve gives it at points (linear between them).
    Child attributes
    • start_atstringRequired
      When charging starts, ISO 8601 with an offset.
    • time_zonestring | null
      IANA time zone for the tariff's local-time restrictions. Default: the tariff's time_zone, else start_at's offset.
      Up to 64 characters
    • duration_minutesnumber
      Charging time in minutes (TIME is billed on it).
      Default 0 · Minimum 0 · Maximum 10080
    • energy_kwhnumber | null
      Total energy, kWh. Omit when energy_curve is given.
      Minimum 0 · Maximum 100000
    • energy_curvearray of CurvePoint | null
      Cumulative kWh at minutes into charging, ascending.
      Child attributes
      • minutenumberRequired
        Minutes after charging started.
        Minimum 0 · Maximum 10080
      • kwhnumberRequired
        Cumulative energy charged by then, kWh.
        Minimum 0 · Maximum 100000
    • idle_minutesnumber
      Minutes connected after charging ends (PARKING_TIME is billed on it).
      Default 0 · Minimum 0 · Maximum 10080
    • power_kwnumber | null
      Constant charging power for power restrictions, kW. Default: the energy curve's slope.
      Minimum 0 · Maximum 10000
    • current_anumber | null
      Charging current for current restrictions, A. Unknown matches no current-restricted element.
      Minimum 0 · Maximum 10000
    • reservation_minutesnumber
      Minutes reserved before charging starts (reservation elements price them).
      Default 0 · Minimum 0 · Maximum 1440
    • reservation_expiredboolean
      The reservation expired unused: no charging; RESERVATION_EXPIRES elements apply.
      Default false
    • groupstring | null
      Member or RFID group, for group discounts.
      Up to 128 characters
    • id_tokenstring | null
      RFID or app token, for group discounts that list tokens. Not stored.
      Up to 64 characters
    • merchant_validationstring | null
      A merchant validation code, for the merchant validation rule.
      Pattern ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$
    • prepaid_balance_minorinteger | null
      A prepaid balance, for the prepaid_limit report.
      Minimum 0 · Maximum 100000000

Returns · 200

  • tariff_idinteger | null
    The stored tariff quoted; null for a simulation.
  • currencystringRequired
  • pricing_versionenumRequired
    energy-v1: a simple tariff (kWh × rate, unchanged); elements-v1: elements and rules.
    One of energy-v1, elements-v1
  • linesarray of QuoteLineRequired
    Child attributes
    • typeenumRequired
      One of ENERGY, TIME, PARKING_TIME, FLAT
    • elementintegerRequired
      Index of the element that priced this line.
    • reservationbooleanRequired
      The line prices a reservation.
    • quantitystringRequired
      Decimal quantity in unit (rounded to 6 places for display).
    • unitenumRequired
      One of kWh, h, session
    • price_minorstringRequired
      Minor units per unit (decimal string).
    • exact_minorstringRequired
      Unrounded amount, minor units (decimal string, 6 places).
    • amount_minorintegerRequired
      Amount rounded half up to integer minor units, for display. total_minor rounds the exact sum once, so line amounts may differ from it by rounding.
  • subtotal_minorintegerRequired
    The elements' exact sum rounded half up, before rules.
  • exact_subtotal_minorstringRequired
  • adjustmentsarray of QuoteAdjustmentRequired
    Child attributes
    • kindenumRequired
      One of group_discount, merchant_validation, max_session_cost
    • rulestringRequired
      The group discount id, the validation code, or max_session_cost_minor.
    • exact_minorstringRequired
    • amount_minorintegerRequired
      Negative: a reduction.
  • total_minorintegerRequired
    Integer minor units: the exact subtotal after rules, rounded half up once. Bills finalize with this same calculation.
  • prepaidobject | nullRequired
    Child attributes
    • balance_minorintegerRequired
    • covered_minorintegerRequired
    • shortfall_minorintegerRequired
    • limit_reachedbooleanRequired
      The session's total reaches the balance: stop or top up.
  • tariff_alt_textarray of AltText
    The tariff's driver-facing descriptions, for receipts.
    Child attributes
    • languagestringRequired
      ISO 639-1 language code.
      Pattern ^[a-z]{2}$
    • textstringRequired
      Driver-facing description of the tariff.
      1–512 characters
  • activityobject | null
    Bills on complex tariffs only: the charging and idle time the bill was priced over. Null on quotes, simulations and simple tariffs (which price kWh only).
    Child attributes
    • methodenumRequired
      ocpp201_charging_state: the charger's OCPP 2.x chargingState. ocpp16_status: OCPP 1.6 connector statuses (Charging; SuspendedEV, SuspendedEVSE and Finishing are idle). ocpp16_status_and_power: those statuses, plus idle wherever the meter shows almost no power for a while. meter_power: the meter alone. none: not enough data; the whole transaction is charging time, as before idle detection (unless it drew less than 1 Wh: see reason no_energy).
      One of ocpp201_charging_state, ocpp16_status, ocpp16_status_and_power, meter_power, none
    • detectedbooleanRequired
      False: method none, and reason says why. A session with less than 1 Wh is all waiting (reason no_energy), and detected is true then, also with method none.
    • reasonstring | null
      Why nothing was detected (for example no_state_or_meter_data); no_energy: a session with less than 1 Wh is all waiting, billing neither TIME nor PARKING_TIME nor energy; else null.
    • charging_secondsintegerRequired
    • idle_secondsintegerRequired
    • waiting_secondsinteger
      Plugged in before the first charging: neither TIME nor PARKING_TIME.
      Default 0
    • intervalsarray of ActivityIntervalRequired
      The transaction from start to end, oldest first.
      Child attributes
      • startstringRequired
        UTC, ISO 8601.
      • endstringRequired
        UTC, ISO 8601.
      • stateenumRequired
        waiting: plugged in before the first charging, priced as neither TIME nor PARKING_TIME.
        One of charging, idle, waiting
POST /v1/tenants/{tenant_id}/tariffs/simulate
curl --fail-with-body -X POST "https://api.ivoracharge.com/v1/tenants/1042/tariffs/simulate" \
  -H "Authorization: Bearer $IVORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "tariff": {
    "currency": "usd",
    "elements": [
      {
        "price_components": [
          {
            "type": null,
            "price": null
          }
        ]
      }
    ]
  },
  "session": {
    "start_at": "2026-10-15T17:30:00-07:00"
  }
}'
Response · 200
{
  "tariff_id": 42,
  "currency": "usd",
  "pricing_version": "energy-v1",
  "lines": [
    {
      "type": "ENERGY",
      "element": 1,
      "reservation": false,
      "quantity": "string",
      "unit": "kWh",
      "price_minor": "string",
      "exact_minor": "string",
      "amount_minor": 1250
    }
  ],
  "subtotal_minor": 1250,
  "exact_subtotal_minor": "string",
  "adjustments": [
    {
      "kind": "group_discount",
      "rule": "string",
      "exact_minor": "string",
      "amount_minor": 1250
    }
  ],
  "total_minor": 1250,
  "prepaid": {
    "balance_minor": 1250,
    "covered_minor": 1250,
    "shortfall_minor": 1250,
    "limit_reached": false
  },
  "tariff_alt_text": [
    {
      "language": "string",
      "text": "string"
    }
  ],
  "activity": {
    "method": "ocpp201_charging_state",
    "detected": false,
    "reason": "string",
    "charging_seconds": 1,
    "idle_seconds": 1,
    "waiting_seconds": 0,
    "intervals": [
      {
        "start": "string",
        "end": "string",
        "state": "charging"
      }
    ]
  }
}
Try it is not available here yetRequests from this page are off until the production API at https://api.ivoracharge.com is public. Use the code samples from your application server; Ivora grants production access. Keys are created in Developer tools.