Contracts¶
Every CPE must have a contract that defines the commercial terms between the member and their energy retailer. Contracts are used by the settlement engine to compute grid costs, member savings, and KPIs such as the comparison between collective self-consumption (CSC) and individual self-consumption (ISC).
Contracts are attached to a CPE meter and scoped to a member via user_id.
Contract Fields¶
| Field | Required | Description |
|---|---|---|
buy_type |
Use: NO_VALUES |
How buy-side tariff values are provided — FIXED, INDEXED, INDEXED_SIMPLIFIED, or NO_VALUES. NO_VALUES means you must upload opportunity costs |
sell_type |
Use: NO_VALUES |
How sell-side tariff values are provided — same options as buy_type. NO_VALUES means you must upload opportunity costs |
contracted_power |
✅ | Contracted power of the meter (kVA) |
voltage_level |
✅ | Voltage level (MAT, AT, MT, BT, BTN simples, etc.) |
tariff_cycle |
✅ | Tariff cycle per Portuguese regulation (e.g. TETRA_SEMANAL, BI_HORARIA) |
with_holidays |
✅ | Whether public holidays are treated as Sundays for tariff period calculations |
start_date |
✅ | First day (inclusive, Europe/Lisbon) on which this contract applies. Replaces the old validity field |
end_date |
— | Last day (inclusive) on which this contract applies. null = open-ended |
user_id |
✅ | UUID of the community member this contract belongs to |
meter_id |
✅ | UUID of the CPE meter this contract is attached to |
Contract Validity¶
A CPE can have several contracts over time, for example when the member changes retailer or
tariff. Each contract covers its own [start_date, end_date] period, and for every day the
platform uses exactly one contract: the one whose period contains that day.
%%{init: {"themeVariables": {"fontSize": "18px"}, "gantt": {"barHeight": 30, "barGap": 8}}}%%
gantt
title Contracts of one CPE
dateFormat YYYY-MM-DD
axisFormat %b %Y
section Contracts
Retailer A (Jan 1 to Jun 30) :done, c1, 2026-01-01, 2026-07-01
Retailer B (Jul 1, end_date null) :active, c2, 2026-07-01, 2026-12-31
- Two contracts of the same meter cannot overlap on any day (
409 Conflict). - Contracts are never chosen by "latest created" and never applied before their
start_dateor after theirend_date. - Make sure every day you run market clearing or settlement for is covered by a contract on each CPE. A gap between two contracts means the CPE has no contract on those days.
- When cloning a contract, give the copy dates that do not overlap the original.
GET /meters/{meter_id}/contracts?effective_at=YYYY-MM-DDreturns the contract valid on that day.DELETE /meters/{meter_id}/contracts/{contract_id}?effective_at=YYYY-MM-DDremoves the contract from that day. Add&end_date=YYYY-MM-DDto remove only that period.
Deprecated validity field
Requests that still send validity are accepted and treated as start_date. Responses
always use start_date and end_date. Update your integration to send start_date.
See Business Validity.
Buy and Sell Payloads¶
When buy_type or sell_type is defined, a payload must be provided with tariff values per
period. An example for contracts of type FIXED is described below, but different contract types can be chosen to fit whatever real life Contract is envisioned.
| Field | Description |
|---|---|
peak_value |
Tariff value during peak hours (€/kWh) |
mid_peak_value |
Tariff value during mid-peak hours (€/kWh) |
off_peak_value |
Tariff value during off-peak hours (€/kWh) |
super_off_peak_value |
Tariff value during super off-peak hours (€/kWh) |
multiplierPMD |
Multiplier applied to the network access tariff (PMD) component |
multiplierERSE |
Multiplier applied to the ERSE peak hour power tariff component |
Contracts without values
Setting buy_type and sell_type to NO_VALUES creates a valid contract structure
without tariff data, so you must upload opportunity costs. This is sufficient for market clearing but will prevent settlement
from computing cost-related KPIs.