Tariffs
This guide covers how to create and manage tariffs — the building blocks of your electricity pricing model.
Copy linkCreating a Tariff
A tariff has a client-provided ID, a direction, and a unit (kWh or scalar). Tariffs with per: "kWh" also require a currency. The tariff is created empty — you push rate data separately. The system: ID prefix is reserved and cannot be used.
POST /flex/tariffs/energy-import
Content-Type: application/json
{
"direction": "import",
"currency": "EUR",
"per": "kWh"
}
The create endpoint returns 201 when a new tariff is created. If a tariff with the same ID and definition already exists, the existing resource is returned with 200. If it exists with a different definition, the request fails with 409.
Copy linkPushing Rate Data
Data is pushed by specifying a replacement window. All existing data in the window is replaced with the provided values. Timestamps must be timezone-aware (ISO 8601 with a UTC offset):
PUT /flex/tariffs/energy-import/timeseries
Content-Type: application/json
Idempotency-Key: 63bc5f16-8747-4206-8f4f-c53184d37ae8
{
"to": "2024-06-16T00:00:00+02:00",
"values": [
{ "at": "2024-06-15T00:00:00+02:00", "rate": 0.12 },
{ "at": "2024-06-15T06:00:00+02:00", "rate": 0.18 },
{ "at": "2024-06-15T12:00:00+02:00", "rate": 0.25 },
{ "at": "2024-06-15T18:00:00+02:00", "rate": 0.14 }
]
}
Idempotency-Key is required on every push request. Send the same key when retrying the same push request to deduplicate retries.
- Completed idempotency records are retained for 24 hours.
- In-progress locks expire after 3 minutes if a request does not finish.
- A request with a key currently in use returns
409 Conflict. - Reusing a key with a different payload returns
422 Unprocessable Entity.
The first value's at defines the start of the replacement window — all existing data in [firstValue.at, to) is replaced. Each value defines the rate from its timestamp until the next value (or until to). In this example:
0.12applies from 00:00 to 06:000.18applies from 06:00 to 12:000.25applies from 12:00 to 18:000.14applies from 18:00 to 24:00
Rules:
- At least one value is required
- Values must be in strictly ascending chronological order
- The last value's
atmust be strictly beforeto - The first value's timestamp must be at least 1 hour in the future
- Data outside the
[firstValue.at, to)window is untouched
You can push data for overlapping windows — each push fully replaces the specified window. Flat or fixed-rate tariffs must be periodically extended with new pushes before the current coverage expires.
Overwriting existing data counts against a per-client overwrite budget. Each client has a sliding 24-hour budget of overwrite points. If a push would exceed the budget, it is rejected with 429 Too Many Requests. Pushes that only extend coverage (no existing data in the window) are not limited. Avoid resending the same future data repeatedly — for example, instead of pushing 365 days of rates every day, prefer sending the next 48 hours daily or pushing a large batch once.
Copy linkData Availability
A tariff covers only the time ranges where you have pushed rate data. Push contiguous data when possible — gaps are tolerated but may cause unresolved intervals during formula evaluation.
Querying a time range that includes periods without pushed data returns those intervals as unresolved. The system never carries rates forward past the last pushed value, preventing stale prices.
When resolving a formula, any interval where an input tariff lacks data is marked unresolved. Only intervals where every input tariff has data produce resolved results.
Copy linkQuerying Tariff Data
The timeseries endpoint returns a tariff's rate data as timezone-aware timestamps for a given time range. The stored UTC data is annotated with the requested timezone's offset.
The from and to parameters are local dates (e.g., 2024-06-15). This avoids ambiguity during DST transitions, since DST changes never occur at midnight. The timezoneName parameter is required. The query range must not exceed 90 days.
GET /flex/tariffs/energy-import/timeseries?from=2024-06-15&to=2024-06-16&timezoneName=Europe/Berlin
{
"tariffId": "energy-import",
"direction": "import",
"currency": "EUR",
"per": "kWh",
"from": "2024-06-15",
"to": "2024-06-16",
"timezoneName": "Europe/Berlin",
"values": [
{ "at": "2024-06-15T00:00:00+02:00", "rate": 0.12 },
{ "at": "2024-06-15T06:00:00+02:00", "rate": 0.18 },
{ "at": "2024-06-15T12:00:00+02:00", "rate": 0.25 },
{ "at": "2024-06-15T18:00:00+02:00", "rate": 0.14 }
]
}
Copy linkListing and Deleting Tariffs
Copy linkList All Tariffs
GET /flex/tariffs
Supports pagination.
Copy linkDelete a Tariff
DELETE /flex/tariffs/energy-import
A tariff cannot be deleted if it is referenced by any location's formula.
Copy linkEndpoint Reference
| Task | Method | Endpoint |
|---|---|---|
| List tariffs | GET | /flex/tariffs |
| Create tariff | POST | /flex/tariffs/{tariffId} |
| Get tariff | GET | /flex/tariffs/{tariffId} |
| Delete tariff | DELETE | /flex/tariffs/{tariffId} |
| Query tariff data | GET | /flex/tariffs/{tariffId}/timeseries |
| Push rate data | PUT | /flex/tariffs/{tariffId}/timeseries |