Meters, Contracts, Resources & Ownerships API¶
Base paths (all under /core/api/communities/{community_id}):
/metersand/meters/{meter_id}/contracts(meters and their commercial contracts)/resources(generators, batteries, EVs, water heaters, installations)/ownerships(member shares of a resource)/resp(public-grid RESP relationships between CPE pairs)
Meters, contracts, resources, ownerships and RESP pairs are dated records. Every create and
update takes a required start_date and an optional inclusive end_date, most reads accept
effective_at, and deletes end the entity from a given day. See
Business Validity. For the data model behind these endpoints
see Meters, Contracts,
Resources and Ownerships and Members. Enum
values are listed in Enums & Constants. A full walkthrough that calls
these endpoints in order is in the Promoter Community Guide.
Common rules
- All endpoints need a bearer token of a verified user. Platform super-users may call everything.
A community admin may call everything inside their community. A community member may only
call
GETendpoints, and on the endpoints marked "member-scoped" below they only see the meters, contracts and resources that are behind resources they own (shares valid oneffective_at). An empty result is returned when they own nothing. - Dates are whole calendar days in Europe/Lisbon.
effective_atdefaults to today. - A path
community_idthat does not exist, and an unknownmeter_id,resource_id,user_idorcontract_id, are answered with403and a "... does not exist." detail (the platform'sNotFounderror uses status 403). A non-member of the community also gets403. - Body validation errors return
422with the Pydantic error list. - Structural edits invalidate the community's already-computed market sessions in the affected period, so they are recomputed with the new structure.
Endpoint summary¶
| Method | Path | Purpose |
|---|---|---|
POST |
/core/api/communities/{community_id}/meters |
Create a meter (and RESP pairs for a CPE) |
GET |
/core/api/communities/{community_id}/meters |
List the meters of a community |
GET |
/core/api/communities/{community_id}/meters/by-identifier |
Get a meter by its identifier code |
GET |
/core/api/communities/{community_id}/meters/{meter_id} |
Get a meter by ID |
PUT |
/core/api/communities/{community_id}/meters/{meter_id} |
Update a meter for a period |
DELETE |
/core/api/communities/{community_id}/meters/{meter_id} |
End a meter from a date |
POST |
/core/api/communities/{community_id}/meters/{meter_id}/contracts |
Create a contract |
POST |
/core/api/communities/{community_id}/meters/{meter_id}/contracts/{contract_id}/clone |
Clone a contract |
GET |
/core/api/communities/{community_id}/meters/{meter_id}/contracts |
List the contracts valid on a day |
PUT |
/core/api/communities/{community_id}/meters/{meter_id}/contracts/{contract_id} |
Replace a contract for a period |
DELETE |
/core/api/communities/{community_id}/meters/{meter_id}/contracts/{contract_id} |
Remove a contract from a date or for a period |
POST |
/core/api/communities/{community_id}/resources |
Create a resource with type details and ownerships |
GET |
/core/api/communities/{community_id}/resources/available-meters |
List meters free for a resource period |
GET |
/core/api/communities/{community_id}/resources |
List the resources of a community |
GET |
/core/api/communities/{community_id}/resources/by-name |
Get a resource by name |
GET |
/core/api/communities/{community_id}/resources/meter/{meter_id} |
List the resources behind a meter |
GET |
/core/api/communities/{community_id}/resources/{resource_id} |
Get a resource by ID |
PUT |
/core/api/communities/{community_id}/resources/{resource_id} |
Update a resource for a period |
DELETE |
/core/api/communities/{community_id}/resources/{resource_id} |
End a resource from a date |
POST |
/core/api/communities/{community_id}/ownerships/{user_id}/{resource_id} |
Assign an ownership share |
GET |
/core/api/communities/{community_id}/ownerships/{user_id} |
List a member's ownership shares |
PUT |
/core/api/communities/{community_id}/ownerships/{user_id}/{resource_id} |
Change an ownership share for a period |
DELETE |
/core/api/communities/{community_id}/ownerships/{user_id}/{resource_id} |
End an ownership share from a date |
GET |
/core/api/communities/{community_id}/resp |
List the RESP pairs of a community |
PUT |
/core/api/communities/{community_id}/resp/{resp_id} |
Activate or deactivate a RESP pair for a period |
Meters¶
Base path: /core/api/communities/{community_id}/meters
Meter types are CPE, INTERNAL and AGGREGATOR_METER. Installation types are IC, IPR, IA
and IAC; status is ACTIVE, INACTIVE or DELETED. See Meters.
Create a Meter¶
Creates a meter with its first dated version. When the meter is a CPE, the platform also
creates the RESP relationships (see RESP) between the new CPE and every other CPE valid
on start_date.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
identifier |
body | string | Yes | Meter code (for example PT0002...). Unique in the community, case-insensitive, for all time |
type |
body | enum | Yes | CPE, INTERNAL or AGGREGATOR_METER. Fixed after creation |
installation_type |
body | enum | Yes | IC, IPR, IA or IAC |
community_id |
body | UUID | Yes | Must match the path community |
ord |
body | string | See tip | DSO name, for example E-REDES. Required for CPE and AGGREGATOR_METER |
production_identifier |
body | string | No | Injection-point code. Mandatory in practice for IAC meters |
status |
body | enum | No | ACTIVE, INACTIVE, DELETED. Defaults to INACTIVE when omitted |
cpe_id |
body | UUID | No | Parent CPE. Only allowed for INTERNAL meters and must be a CPE of the same community |
start_date |
body | date | Yes | First day of validity (inclusive) |
end_date |
body | date | No | Last day of validity (inclusive). null = open-ended |
Example
curl -X POST https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"installation_type": "IC",
"ord": "E-REDES",
"status": "ACTIVE",
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"start_date": "2026-01-01"
}'
Response (abridged, 201 Created)
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"ord": "E-REDES",
"installation_type": "IC",
"production_identifier": null,
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "ACTIVE",
"cpe_id": null,
"version_id": null,
"start_date": null,
"end_date": null
}
Tip
ordis required forCPEandAGGREGATOR_METER; without it the call fails with400"ORD is not valid for this community.".INTERNALmeters do not need it, and anordsent with a non-CPEmeter is discarded.- Only
CPEmeters generate RESP pairs (both directions,is_active: true, samestart_date/end_dateas the meter). - A duplicate
identifierin the community returns409. An invalid parent (cpe_idon a non-internal meter, or a parent that is not a CPE of this community) returns422. - The create response is the stable meter record, so
version_id,start_dateandend_dateare returned empty; read the meter withGETto get the dated version.
List Meters¶
Lists the meters whose version is valid on effective_at, ordered by identifier.
Auth / permissions: any community member or admin (member-scoped: members only get meters behind resources they own).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
effective_at |
query | date | No | Day to evaluate. Default: today (Europe/Lisbon) |
exclude_deleted |
query | string | No | true (default) hides meters with status DELETED. Send false to include them |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"ord": "E-REDES",
"installation_type": "IC",
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "ACTIVE",
"cpe_id": null,
"version_id": "9b2f1c1e-6d3a-4a55-8f7e-1d2c3b4a5f60",
"start_date": "2026-01-01",
"end_date": null
}
]
Tip
A meter with no version covering effective_at (before its start_date, after its
end_date, or in a gap) is not listed. The list is empty ([]), not an error, when nothing
matches.
Get a Meter by Identifier¶
Finds a meter by its identifier code (matched case-insensitively) inside the community.
Auth / permissions: any community member or admin (member-scoped: 403 when a member does
not own a resource behind the meter).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
identifier |
query | string | Yes | Meter code |
effective_at |
query | date | No | Day to evaluate the version |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/by-identifier?identifier=PT0002000000000000000000001234" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"status": "ACTIVE",
"start_date": "2026-01-01",
"end_date": null
}
Tip
Returns 404 "Meter not found" when no such meter exists. Without effective_at the lookup
ignores validity and only excludes meters whose stable status is DELETED; with
effective_at it requires a version valid on that day.
Get a Meter by ID¶
Returns the meter version valid on effective_at.
Auth / permissions: any community member or admin (member-scoped: 403 "Access denied" for a
meter the member does not reach through an owned resource).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
meter_id |
path | UUID | Yes | Meter |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"installation_type": "IC",
"status": "ACTIVE",
"version_id": "9b2f1c1e-6d3a-4a55-8f7e-1d2c3b4a5f60",
"start_date": "2026-01-01",
"end_date": null
}
Tip
404 "Meter not found" when the meter has no non-deleted version valid on that day.
Update a Meter¶
Changes a meter from start_date (or for [start_date, end_date]). Fields that are not sent keep
the values of the version valid on start_date; earlier history is untouched. Any version already
covering the period is replaced (older and newer parts of it are kept as fragments).
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
meter_id |
path | UUID | Yes | Meter |
start_date |
body | date | Yes | First day the change applies |
end_date |
body | date | No | Last day the change applies. null = open-ended |
installation_type |
body | enum | No | IC, IPR, IA, IAC |
production_identifier |
body | string | No | Injection-point code |
ord |
body | string | No | DSO name |
cpe_id |
body | UUID | No | New parent CPE (internal meters only) |
status |
body | enum | No | ACTIVE, INACTIVE, DELETED |
identifier / type |
body | - | No | Accepted only if equal to the current value; changing them returns 400 |
Example
curl -X PUT https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "INACTIVE",
"start_date": "2026-03-01"
}'
Response (abridged)
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE",
"status": "INACTIVE",
"installation_type": "IC"
}
Tip
identifierandtypeare immutable (400). To replace a physical meter, end the old one and create a new one.403"Meter version with effective_date: ... does not exist." when no version of the meter is valid onstart_date.422whencpe_idis set on a non-internal meter, or the parent is not aCPEof the same community.- The response is the stable meter record: it echoes the updated fields but does not carry
start_date/end_date. UseGET ...?effective_at=to read a specific version.
End a Meter¶
Ends the meter from effective_at (versions from that day on are removed, earlier history is kept)
and sets its stable status to INACTIVE.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
meter_id |
path | UUID | Yes | Meter |
effective_at |
query | date | Yes | First day the meter no longer exists |
Example
curl -X DELETE "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response
204 No Content on success. When a resource is still assigned to the meter on or after
effective_at, nothing is deleted and the call answers 200 with:
{
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Contador está associado a um recurso e não pode ser removido. Por favor remova a associação."
}
Tip
The "assigned to a resource" refusal is a 200 response with a message, not an error
status, so check for 204 (or for message) in your client. First end or reassign the
resource (see Update a Resource).
Contracts¶
Base path: /core/api/communities/{community_id}/meters/{meter_id}/contracts
A contract defines the commercial terms of a CPE or aggregator meter for a period. See Contracts for the fields and the buy/sell payloads.
| Key field | Type | Description |
|---|---|---|
buy_type, sell_type |
enum | NO_VALUES, FIXED, INDEXED, INDEXED_SIMPLIFIED |
voltage_level |
enum | For example MAT, AT, MT, BTE, BT, BTN simples, BTN 6.9 kVA (full list in the schema) |
tariff_cycle |
enum | TETRA_SEMANAL, TETRA_OPCIONAL, DIARIO, TRI_DIARIO, BI_DIARIO, TRI_SEMANAL, BI_SEMANAL |
with_holidays |
bool | Holidays treated as Sundays |
contracted_power |
float | kVA |
start_date / end_date |
date | Inclusive period; end_date optional and must not be before start_date |
user_id, meter_id |
UUID | Member responsible for the contract and the meter it is attached to |
buy_payload, sell_payload |
object | Tariff values, shape chosen by buy_type / sell_type (below) |
Payload shapes:
| Contract type | Payload fields |
|---|---|
FIXED |
buy_or_sell_type, peak_value, mid_peak_value, off_peak_value, super_off_peak_value, multiplierPMD (default 0), multiplierERSE (default 0) |
INDEXED |
buy_or_sell_type and the 16 coefficients k1_, k2_, k5_, k6_ x peak_value, mid_peak_value, off_peak_value, super_off_peak_value |
INDEXED_SIMPLIFIED |
buy_or_sell_type, multiplierPMD, multiplierERSE, additiveC |
buy_or_sell_type is CONTRACT_BUY_VALUES for buy_payload and CONTRACT_SELL_VALUES for
sell_payload. With NO_VALUES no payload is stored; opportunity costs must be uploaded instead.
Deprecated validity
validity is still accepted as an alias of start_date in contract request bodies. Responses
always use start_date and end_date. Use start_date in new integrations.
Create a Contract¶
Creates a contract for the meter in meter_id of the body, for [start_date, end_date].
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter (the meter must exist) |
buy_type, sell_type |
body | enum | Yes | See table above |
voltage_level |
body | enum | Yes | Voltage level |
tariff_cycle |
body | enum | Yes | Tariff cycle |
with_holidays |
body | bool | Yes | Holidays as Sundays |
contracted_power |
body | float | Yes | kVA |
start_date |
body | date | Yes | First day (inclusive) |
end_date |
body | date | No | Last day (inclusive) |
user_id |
body | UUID | Yes | Responsible member |
meter_id |
body | UUID | Yes | CPE or aggregator meter. Should equal the path meter_id |
buy_payload, sell_payload |
body | object | No | Tariff values |
Example
curl -X POST https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7/contracts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"buy_type": "FIXED",
"sell_type": "FIXED",
"voltage_level": "BTN simples",
"tariff_cycle": "TETRA_SEMANAL",
"with_holidays": true,
"contracted_power": 6.9,
"start_date": "2026-01-01",
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"buy_payload": {
"buy_or_sell_type": "CONTRACT_BUY_VALUES",
"peak_value": 0.21,
"mid_peak_value": 0.17,
"off_peak_value": 0.12,
"super_off_peak_value": 0.10,
"multiplierPMD": 1,
"multiplierERSE": 1
},
"sell_payload": {
"buy_or_sell_type": "CONTRACT_SELL_VALUES",
"peak_value": 0.06,
"mid_peak_value": 0.05,
"off_peak_value": 0.04,
"super_off_peak_value": 0.03,
"multiplierPMD": 1,
"multiplierERSE": 0
}
}'
Response (abridged, 201 Created)
{
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"version_id": "a1b2c3d4-0000-4000-8000-000000000001",
"buy_type": "FIXED",
"sell_type": "FIXED",
"voltage_level": "BTN simples",
"tariff_cycle": "TETRA_SEMANAL",
"with_holidays": true,
"contracted_power": 6.9,
"start_date": "2026-01-01",
"end_date": null,
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
Tip
- Returns
409when the meter already has a contract starting on exactly the samestart_date. - Any other contract that overlaps the new period is trimmed or split (its parts outside
[start_date, end_date]are kept as new contract versions) instead of being rejected, so the new contract takes precedence over the period. - The meter (from the body
meter_id, valid onstart_date) must be aCPEorAGGREGATOR_METER, otherwise400"Meter is not CPE". An unknown meter returns403. end_datebeforestart_datereturns422.- The tariff payload is stored according to the type:
FIXEDas a fixed tariff,INDEXEDas coefficients,INDEXED_SIMPLIFIEDas the simplified index.NO_VALUESstores none. - Every contract version has its own
id; the responseversion_idequalsid. - The path
meter_idis only checked for existence; the bodymeter_iddecides which meter receives the contract, so send the same value in both.
Clone a Contract¶
Creates a new contract from the stored values of contract_id (general fields plus buy and sell
payloads). The request has no body.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter |
contract_id |
path | UUID | Yes | Contract to copy |
Example
curl -X POST https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7/contracts/a1b2c3d4-0000-4000-8000-000000000001/clone \
-H "Authorization: Bearer $TOKEN"
Response (abridged, 201 Created)
{
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"version_id": "a1b2c3d4-0000-4000-8000-000000000002",
"buy_type": "FIXED",
"sell_type": "FIXED",
"start_date": "2026-01-01",
"end_date": null,
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
Tip
The copy keeps the original's start_date and end_date, and the clone goes through the same
overlap handling as Create a Contract. Because the periods are identical,
the copy replaces the original: the response carries a new id and the original contract
is no longer returned. To obtain a copy with different dates or values, read the contract and
POST a new one (or PUT the contract).
List Contracts of a Meter¶
Returns the contract(s) of the meter whose period contains effective_at, with their buy and sell
payloads.
Auth / permissions: any community member or admin (member-scoped: 403 "Access denied" when a
member does not reach the meter through an owned resource).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7/contracts?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"buy_type": "FIXED",
"sell_type": "FIXED",
"voltage_level": "BTN simples",
"tariff_cycle": "TETRA_SEMANAL",
"with_holidays": true,
"contracted_power": 6.9,
"start_date": "2026-01-01",
"end_date": null,
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"buy_payload": {
"buy_or_sell_type": "CONTRACT_BUY_VALUES",
"contract_id": "a1b2c3d4-0000-4000-8000-000000000001",
"peak_value": 0.21,
"mid_peak_value": 0.17,
"off_peak_value": 0.12,
"super_off_peak_value": 0.10,
"multiplierPMD": 1.0,
"multiplierERSE": 1.0
},
"sell_payload": { "buy_or_sell_type": "CONTRACT_SELL_VALUES", "peak_value": 0.06 }
}
]
Tip
When no contract covers effective_at the call fails with 403 "Contracts not found for
meter." (the platform's not-found status), rather than returning an empty list. A gap between
two contracts therefore shows up as this error.
Update a Contract¶
Replaces the meter's contract for [start_date, end_date] with the full body. The body has the
same fields as Create a Contract; it is a full replacement of the values
(general fields and payloads), not a partial patch.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter |
contract_id |
path | UUID | Yes | An existing contract of the meter |
| body | body | object | Yes | Same schema as the create body. meter_id must equal the contract's meter |
Example
curl -X PUT https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7/contracts/a1b2c3d4-0000-4000-8000-000000000001 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"buy_type": "NO_VALUES",
"sell_type": "NO_VALUES",
"voltage_level": "BTN simples",
"tariff_cycle": "TETRA_SEMANAL",
"with_holidays": true,
"contracted_power": 10.35,
"start_date": "2026-07-01",
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}'
Response (abridged, 200 OK)
{
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"version_id": "a1b2c3d4-0000-4000-8000-000000000003",
"buy_type": "NO_VALUES",
"sell_type": "NO_VALUES",
"contracted_power": 10.35,
"start_date": "2026-07-01",
"end_date": null,
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
Tip
- The update is a replacement over the period: every contract of the meter overlapping
[start_date, end_date]is removed (their parts beforestart_dateand afterend_dateare kept as new contract versions) and one new contract is created. The response therefore has a newid. - In the example above, the January contract is kept for 2026-01-01 to 2026-06-30 and the new terms apply from July 1.
- The
meter_idof the body cannot differ from the contract's meter. This is raised as an unhandled error and answered with500; create a new contract on the other meter instead.
Delete a Contract¶
Removes the contract from effective_at onwards, or only for [effective_at, end_date] when
end_date is given. The parts of the contract outside the removed period are kept.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter |
contract_id |
path | UUID | Yes | Contract |
effective_at |
query | date | Yes | First day removed (raised to the contract's start_date if earlier) |
end_date |
query | date | No | Last day removed. null = remove to the end of the contract |
Example
curl -X DELETE "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/meters/7c9e6679-7425-40de-944b-e07fc1f90ae7/contracts/a1b2c3d4-0000-4000-8000-000000000001?effective_at=2026-06-01&end_date=2026-06-30" \
-H "Authorization: Bearer $TOKEN"
Response
204 No Content.
Tip
- Removing a period in the middle of a contract splits it in two new contract versions (with new IDs), leaving a gap for the removed days.
end_datebeforeeffective_atis answered with500(unhandled error).- If
effective_atis after the contract'send_date, nothing changes but the call still returns204. - Market and settlement need a contract on every CPE for every processed day, so avoid gaps.
Resources¶
Base path: /core/api/communities/{community_id}/resources
Resource types are IU, IC, SCPU, STORAGE, EV, EWH and HP. See
Resources for the meaning of each type and field. The general fields
(name, status, meter_id) and the type-specific details are versioned together.
Create a Resource¶
Creates a resource together with its type-specific details and, optionally, its ownership shares, as one dated record.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
resource_payload.name |
body | string | Yes | Name, unique in the community (case-insensitive, whitespace trimmed, across all history) |
resource_payload.type |
body | enum | Yes | IU, IC, SCPU, STORAGE, EV, EWH, HP. Fixed after creation |
resource_payload.status |
body | enum | Yes | ACTIVE, INACTIVE, DELETED |
resource_payload.community_id |
body | UUID | Yes | Must match the path community |
resource_payload.meter_id |
body | UUID | No | Meter directly above the resource. Without it the resource is view-only |
resource_payload.start_date |
body | date | Yes | First day (inclusive) |
resource_payload.end_date |
body | date | No | Last day (inclusive) |
iu_payload, ic_payload |
body | object | One of | sum_certified_power (kW, required), ic_voltage_level (required), description |
scpu_payload |
body | object | One of | generation_capacity (kW, required) |
storage_payload |
body | object | One of | nominal_capacity, max_power, charging_efficiency, discharging_efficiency, min_SOC, max_SOC (all required), deg_cost, init_soc |
ev_payload |
body | object | One of | max_power_input, max_power_output, charging_efficiency, discharging_efficiency, min_SOC, max_SOC (required), nominal_capacity, desired_min_SOC, deg_cost, init_soc |
ewh_payload |
body | object | One of | capacity, power, max_temp, default_start_temp, target_temp (all required) |
hp_payload |
body | object | One of | Heat-pump parameters, all optional (specification in development) |
ownerships_payload |
body | array | No | Items {user_id, perc_ownership, start_date, end_date?} |
At least one *_payload is required, and the one matching resource_payload.type must be present.
Example
curl -X POST https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resource_payload": {
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"start_date": "2026-01-01"
},
"ownerships_payload": [
{
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"perc_ownership": 100,
"start_date": "2026-01-01"
}
],
"storage_payload": {
"nominal_capacity": 10.0,
"max_power": 5.0,
"charging_efficiency": 95,
"discharging_efficiency": 95,
"min_SOC": 10,
"max_SOC": 100
}
}'
Response (abridged, 201 Created)
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"details": {
"nominal_capacity": 10.0,
"max_power": 5.0,
"charging_efficiency": 95.0,
"discharging_efficiency": 95.0,
"min_SOC": 10.0,
"max_SOC": 100.0
},
"total_ownership": 100.0
}
Tip
- Returns
422when no type payload is sent, the name is empty, the ownership list repeats a user or sums to more than 100, or the meter is not valid for the whole resource period ("The resource period must be covered by the meter's validity."). - Returns
409when the name is already used in the community, or when themeter_id(aCPEorINTERNALmeter) already has another resource on any day of the period. Put each extra resource behind its own internal meter. An unknown meter, or one not valid onstart_date, returns403. - Everything (resource, version, details, ownerships) is saved in one transaction.
- To see the dated ownership shares, read the resource with
GETafter creating it. charging_efficiencyanddischarging_efficiencyare percentages;*_SOCare percentages; capacities are kWh and powers kW.
List Meters Available for a Resource¶
Lists the meters that can receive a resource for the whole period: meters valid on start_date
that have no other resource in [start_date, end_date]. Use it to fill the meter picker before
creating or updating a resource.
Auth / permissions: any community member or admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
start_date |
query | date | Yes | First day of the period |
end_date |
query | date | No | Last day of the period. Omit for open-ended |
resource_id |
query | UUID | No | Ignore this resource's own assignment (use when editing it) |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/available-meters?start_date=2026-01-01&end_date=2026-12-31" \
-H "Authorization: Bearer $TOKEN"
Response
[
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "PT0002000000000000000000001234",
"type": "CPE"
}
]
Tip
Only CPE and INTERNAL meters are excluded when occupied; an AGGREGATOR_METER is always
listed. Deleted meters and meters with no version valid on start_date are not listed. The
list is ordered by identifier.
List Resources¶
Lists the resources valid on effective_at, with type details, ownerships and total_ownership.
Auth / permissions: any community member or admin (member-scoped: members only get the resources they own).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
effective_at |
query | date | No | Day to evaluate. Default: today |
exclude_deleted |
query | string | No | true (default) hides resources with status DELETED. Send false to include them |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"created_at": "2026-01-01T09:00:00Z",
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"version_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716",
"start_date": "2026-01-01",
"end_date": null,
"details": { "nominal_capacity": 10.0, "max_power": 5.0 },
"total_ownership": 100.0,
"ownerships": [
{
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"resource_id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"perc_ownership": 100.0,
"start_date": "2026-01-01",
"end_date": null
}
]
}
]
Tip
- A resource with
status: DELETEDthat cannot be fully removed (because sessions or settlements reference it) is hidden unlessexclude_deleted=false. - Returns
[]when there are no resources for the day. total_ownershipis the sum of the shares valid oneffective_at; it is below 100 when the resource is only partly allocated.
Get a Resource by Name¶
Finds a resource by name inside the community (case-insensitive).
Auth / permissions: any community member or admin (member-scoped: 403 "Access denied" for a
resource the member does not own).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
name |
query | string | Yes | Resource name |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/by-name?name=battery%201" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"start_date": "2026-01-01",
"end_date": null,
"details": { "nominal_capacity": 10.0, "max_power": 5.0 },
"ownerships": []
}
Tip
404 "Resource not found" when no resource has that name on the day. The match uses SQL
ILIKE, so % and _ in the name act as wildcards.
List Resources by Meter¶
Returns the resources assigned to a meter on effective_at, with details and ownerships.
Auth / permissions: any community member or admin (not member-scoped).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, meter_id |
path | UUID | Yes | Community and meter |
effective_at |
query | date | No | Day to evaluate. Default: today |
exclude_deleted |
query | string | No | true (default) hides DELETED resources. Send false to include them |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/meter/7c9e6679-7425-40de-944b-e07fc1f90ae7?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"details": { "nominal_capacity": 10.0, "max_power": 5.0 },
"ownerships": []
}
]
Tip
When the meter has no resource on that day the call fails with 403 "Resources for meter with
meter_id: ... does not exist." (the platform's not-found status), not with an empty list. The
path community_id is not matched against the meter's community.
Get a Resource by ID¶
Returns the resource version valid on effective_at, with type details, ownerships and
total_ownership.
Auth / permissions: any community member or admin (member-scoped: 403 "Access denied" for a
resource the member does not own).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, resource_id |
path | UUID | Yes | Community and resource |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10?effective_at=2026-01-14" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"version_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716",
"start_date": "2026-01-14",
"end_date": null,
"details": { "nominal_capacity": 10.0, "max_power": 10.0 },
"total_ownership": 100.0,
"ownerships": [
{ "user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11", "perc_ownership": 100.0 }
]
}
Tip
details depends on the resource type (see the field tables in
Resources). A resource with no version on effective_at returns
403 "Resource with id: ... does not exist.".
Update a Resource¶
Creates or replaces a dated revision of the resource from start_date (or for
[start_date, end_date]). General fields, type details, meter assignment and ownerships are saved
together.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, resource_id |
path | UUID | Yes | Community and resource |
start_date |
body | date | Yes | First day the change applies |
end_date |
body | date | No | Last day the change applies |
name |
body | string | No | New name. Default: current name |
status |
body | enum | No | New status. Default: current status |
type |
body | enum | No | Accepted only if equal to the current type |
details |
body | object | No | Type-specific fields to change. Merged over the current values |
meter_id |
body | UUID or null | No | New meter. null = view-only for the period; omitted = keep current meter |
ownerships_payload |
body | array | No | Full list of shares for the period (user_id, perc_ownership, start_date, end_date) |
Example
Upgrading the battery to 10 kW from January 14:
curl -X PUT https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"details": { "max_power": 10.0 },
"start_date": "2026-01-14"
}'
Response (abridged)
{
"id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"name": "Battery 1",
"type": "STORAGE",
"status": "ACTIVE",
"meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"version_id": "5e4d3c2b-1a09-4f8e-8d7c-6b5a49382716",
"start_date": "2026-01-14",
"end_date": null,
"details": { "nominal_capacity": 10.0, "max_power": 10.0 }
}
Tip
- Days before January 14 keep the 5 kW version. Fields not sent are inherited from the version
valid on
start_date, anddetailsonly overrides the fields it contains. - When
ownerships_payloadis sent, members that currently have a share but are missing from the list lose it for the period; when omitted, ownerships are untouched. 422for a changedtype, an empty name, a total share above 100, anend_datebeforestart_date, or a meter that does not cover the period.409for a name already used in the community, or when the meter already has another resource in the period.- Unknown resource:
403.
End a Resource¶
Closes the resource's operational history from effective_at; earlier days remain available.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id, resource_id |
path | UUID | Yes | Community and resource |
effective_at |
query | date | Yes | First day the resource no longer exists |
Example
curl -X DELETE "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resources/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response
204 No Content on success. When ownerships still exist on or after effective_at, nothing is
deleted and the call answers 200 with:
{
"resource_id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"message": "Recurso está alocado a um ou mais membros. Por favor remova a alocação."
}
Tip
The refusal is a 200 with a message, not an error status. End the ownerships first with
End an Ownership using the same effective_at, then delete the resource.
Ownerships¶
Base path: /core/api/communities/{community_id}/ownerships
An ownership gives a member a percentage (perc_ownership, greater than 0 and at most 100) of a
resource for a period. Compensation from transactions is split between owners in proportion to
their shares (Resources). The total of all shares of a
resource must not exceed 100% on any day.
Assign an Ownership¶
Gives the member a share of the resource for [start_date, end_date]. If the member already has an
ownership record on the resource, the call behaves like an update of that share for the period.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
user_id |
path | UUID | Yes | Member who owns the share |
resource_id |
path | UUID | Yes | Resource |
perc_ownership |
body | float | Yes | Share in percent, greater than 0 and at most 100 |
start_date |
body | date | Yes | First day (inclusive) |
end_date |
body | date | No | Last day (inclusive) |
Example
curl -X POST https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/ownerships/5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"perc_ownership": 70,
"start_date": "2026-01-01"
}'
Response (abridged, 201 Created)
{
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"resource_id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"perc_ownership": 70.0
}
Tip
422whenperc_ownershipis not greater than 0,409when it is above 100. If the other owners plus the new share exceed 100% on any day of the period, the call fails with an unhandled error (500, "Resource ownership exceeds 100 percent on YYYY-MM-DD").- An unknown user or resource returns
403. - The response echoes the stable ownership record, not the dated version. Use
GETto read the versions.
List a Member's Ownerships¶
Lists the resource shares the member holds in this community on effective_at.
Auth / permissions: any community member or admin (not member-scoped: the user_id in the path
is not compared to the caller).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
user_id |
path | UUID | Yes | Member |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/ownerships/5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response
[
{
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"resource_id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"perc_ownership": 70.0,
"version_id": "2a3b4c5d-6e7f-4081-92a3-b4c5d6e7f809",
"start_date": "2026-01-01",
"end_date": null
}
]
Tip
Shares on resources of other communities are not returned. An empty list means the member has no valid share on that day.
Update an Ownership¶
Sets the member's share to perc_ownership for [start_date, end_date], keeping the rest of the
share's history.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
user_id, resource_id |
path | UUID | Yes | Member and resource |
perc_ownership |
body | float | Yes | New share in percent (greater than 0, at most 100) |
start_date |
body | date | Yes | First day the new share applies |
end_date |
body | date | No | Last day the new share applies |
Example
curl -X PUT https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/ownerships/5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"perc_ownership": 50,
"start_date": "2026-07-01"
}'
Response (abridged)
{
"user_id": "5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11",
"resource_id": "0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10",
"perc_ownership": 50.0,
"version_id": null,
"start_date": null,
"end_date": null
}
Tip
- The 100% rule is checked on every day of the period against the other owners (
500with "Resource ownership exceeds 100 percent on YYYY-MM-DD" when it would be exceeded). A share of 0 or less is422, above 100 is409. - The response shows the stable record, so its dated fields are empty; read the dated shares with the list endpoint.
- An unknown user or resource returns
403.
End an Ownership¶
Ends the member's share of the resource from effective_at (open-ended removal). Earlier days
keep the share.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
user_id, resource_id |
path | UUID | Yes | Member and resource |
effective_at |
query | date | Yes | First day the share no longer applies |
Example
curl -X DELETE "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/ownerships/5d1f1a1c-2b6b-4a3e-9c0a-0e5f5c1a7b11/0c7e3a52-1f6b-4d2a-9a3b-3b1f7f9d2c10?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response
204 No Content.
Tip
Always returns 204 once the user and resource exist, even if the member had no share on that
day. Remove all shares before ending the resource (see
End a Resource).
RESP¶
Base path: /core/api/communities/{community_id}/resp
RESP (public grid) pairs say whether two CPEs are connected through the public grid only. Pairs are
created automatically, in both directions, when a CPE is created (see
Create a Meter). The is_active flag is dated. See
RESP configuration.
List RESP Pairs¶
Lists the RESP pairs valid on effective_at. Each pair of meters is returned once (the reverse
direction is merged into it).
Auth / permissions: any community member or admin (not member-scoped).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
effective_at |
query | date | No | Day to evaluate. Default: today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resp?effective_at=2026-06-01" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{
"id": "d4e5f6a7-b8c9-4d0e-8f1a-2b3c4d5e6f70",
"provider_meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"receiver_meter_id": "b3a1c2d4-5e6f-4789-a0b1-c2d3e4f5a6b7",
"is_active": true,
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"version_id": "e5f6a7b8-c9d0-4e1f-9a2b-3c4d5e6f7a81",
"start_date": "2026-01-01",
"end_date": null
}
]
Tip
The list is ordered with active pairs first. Which direction's id is returned for a pair
is not guaranteed, but PUT updates both directions, so either id can be used.
Update a RESP Pair¶
Sets is_active for a RESP pair from effective_at (or for [effective_at, end_date]), and
applies the same change to the opposite direction of the pair.
Auth / permissions: community admin or platform super-user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
resp_id |
path | UUID | Yes | RESP pair (as returned by the list) |
effective_at |
query | date | Yes | First day of the change |
end_date |
query | date | No | Last day of the change. Omit for open-ended |
| body | body | object | No | A full RESP object (provider_meter_id, receiver_meter_id, is_active, community_id, start_date); only its is_active is used. Omit the body to toggle |
Example
curl -X PUT "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/resp/d4e5f6a7-b8c9-4d0e-8f1a-2b3c4d5e6f70?effective_at=2026-07-01&end_date=2026-09-30" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider_meter_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"receiver_meter_id": "b3a1c2d4-5e6f-4789-a0b1-c2d3e4f5a6b7",
"is_active": false,
"community_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"start_date": "2026-07-01"
}'
Response
Tip
- Without a body the call toggles: the pair gets the opposite of its
is_activeoneffective_at. - If a body is sent it must be a complete RESP object (else
422); the dates inside it are ignored andeffective_at/end_datefrom the query are used. - Returns
403"RESP version with effective_date: ... does not exist." when the pair has no version valid oneffective_at. - Market sessions of the affected period are invalidated so they are recomputed.