Settlement API¶
Base path: /core/api/communities/{community_id}/sessions/settlement
Settlement is the post-clearing financial computation of each member's revenues and costs per 15-minute ISP (see Settlement concepts and the Settlement Guide). Settlement itself runs automatically after market clearing, so this API is read-only for results and offers three groups of endpoints:
- Metrics: pre-aggregated KPIs per community, per member and per resource.
- Dynamic query: a flexible endpoint to read any of the 8 settlement output tables.
- Billing guides: asynchronous Excel / PDF reports, plus listing, downloading and deleting the generated files (see also File Exports).
All routes require an authenticated, verified user who belongs to the community (or a platform
admin). Because POST and DELETE are "unsafe" methods, a community member receives
403 Community members can only perform read operations on every POST/DELETE route below,
including the dynamic query and the file download. Only community admins and platform admins can use them.
Dates are plain YYYY-MM-DD dates and ranges are inclusive of the whole end_date. Monetary
values are in EUR and energy values in kWh, per 15-minute ISP, summed over the requested range.
Timestamps follow the platform time zone (Europe/Lisbon).
Endpoint summary¶
| Method | Path | Purpose |
|---|---|---|
GET |
/core/api/communities/{community_id}/sessions/settlement/settlement-kpis |
Community savings KPIs for a period |
GET |
/core/api/communities/{community_id}/sessions/settlement/settlement-metrics |
Per-member settlement totals for a period |
GET |
/core/api/communities/{community_id}/sessions/settlement/settlement-resource-metrics |
Per-resource revenue totals and share for a period |
POST |
/core/api/communities/{community_id}/sessions/settlement/outputs/query |
Dynamic query of the settlement output tables |
GET |
/core/api/communities/{community_id}/sessions/settlement/billing-guides/members |
Members that can be included in a billing guide |
POST |
/core/api/communities/{community_id}/sessions/settlement/billing-guides/excel |
Start generation of an Excel billing guide (async) |
POST |
/core/api/communities/{community_id}/sessions/settlement/billing-guides/pdf |
Start generation of a PDF billing guide (async) |
GET |
/core/api/communities/{community_id}/sessions/settlement/billing-guides |
List generated billing guide files |
POST |
/core/api/communities/{community_id}/sessions/settlement/billing-guides/{file_name} |
Download a generated billing guide file |
DELETE |
/core/api/communities/{community_id}/sessions/settlement/billing-guides/{file_name} |
Delete a generated billing guide file |
Routes from older docs that do not exist
Earlier versions of this page described GET .../sessions/settlements/{session_id},
GET .../settlement/metrics/kpis and GET .../settlement/metrics/members. These are not served by
the backend. Use the endpoints in the table above; the query parameters are start_date and
end_date (dates), not start_datetime / end_datetime.
Metrics¶
Get Settlement KPIs¶
Returns three community-level KPIs summed over the period, computed from the member-level settlement
output (rev_total, rev_total_no_csc, rev_total_pow). See
Revenue & Cost Fields for the meaning of each field.
Auth / permissions: any member of the community, community admin or platform admin. The result is community-wide and is not restricted to the caller's own data.
| 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 | Yes | Last day of the period (inclusive) |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/settlement-kpis?start_date=2025-01-01&end_date=2025-01-31" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
Tip
savings = sum(rev_total) - sum(rev_total_no_csc) (EUR; positive means members save by participating in the REC).
savings_perc = savings / abs(sum(rev_total_no_csc)) * 100, and is 0 when sum(rev_total_no_csc) is 0.
If there is no settlement data in the range, all values are 0.
Get Member Settlement Metrics¶
Returns one entry per member, keyed by member (user) UUID, with the member's settlement energy and revenue fields summed over the period plus its savings.
Auth / permissions: any member of the community, community admin or platform admin. For a community member the result is automatically restricted to the caller's own entry; admins see all members.
| 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 | Yes | Last day of the period (inclusive) |
effective_at |
query | date | No | Date used to resolve which resources the caller owned (members only). Defaults to today |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/settlement-metrics?start_date=2025-01-01&end_date=2025-01-31" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
{
"7c9e6679-7425-40de-944b-e07fc1f90ae7": {
"savings": 4.82,
"savings_perc_proportional": 5.6,
"rev_total_pow": -0.9,
"rev_pow": -0.4,
"e_sup": 210.5,
"e_pur": 95.2,
"e_sale": 0.0,
"e_sur": 12.1,
"rev_sup": -31.6,
"rev_pur": -9.1,
"rev_sale": 0.0,
"rev_sur": 0.8,
"rev_slc_soc": -1.2,
"rev_lem_fee": 0.0
}
}
Tip
savings = rev_total - rev_total_no_csc per member. savings_perc_proportional is the member's savings as a
share (%) of the absolute total community savings for the period, so shares add up to 100% across all members
(it is 0.0 when the community total is 0). Energy fields are kWh, revenue fields EUR. When a member has no
settlement data in the period the response is an empty object {}.
Get Resource Settlement Metrics¶
Returns, for each resource, the total revenue (rev_total, EUR) over the period and the resource's
share of the community resource revenue total (rev_total_perc), keyed by resource UUID.
Auth / permissions: any member of the community, community admin or platform admin. Not restricted to the caller's own resources.
| 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 | Yes | Last day of the period (inclusive) |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/settlement-resource-metrics?start_date=2025-01-01&end_date=2025-01-31" \
-H "Authorization: Bearer $TOKEN"
Response (abridged, as built by the handler)
Response model mismatch
The route's declared response model (SettlementResourceMetricsResponseSchema) requires resource_id and
resource_name, but the handler only returns rev_total and rev_total_perc. FastAPI validates the
returned value against the declared model, so this endpoint is likely to fail with 500 until the schema or
handler is aligned. Treat the example above as the intended payload, not a verified one.
Tip
rev_total_perc = rev_total / sum(rev_total over all resources) * 100, so it is relative to the community
total in the period (a negative or zero total yields unusual percentages).
Dynamic query¶
Query Settlement Outputs (Dynamic)¶
An optional, flexible endpoint for retrieving settlement results without being tied to a
fixed response shape. Instead of calling one endpoint per level (member, resource, CPE, REC), you
describe in a single JSON body which output tables, which fields, and which entities you want,
and the response contains only that. It is a POST because the fields parameter is a nested object,
which cannot be expressed as flat query-string parameters.
Auth / permissions: community admin or platform admin only (it is a POST, so community members get 403).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
start_date |
body | date (YYYY-MM-DD) |
Yes | First day of the range |
end_date |
body | date (YYYY-MM-DD) |
Yes | Last day of the range, inclusive. Must be >= start_date |
outputs |
body | "ALL" or list of output types |
No (default "ALL") |
Which output tables to query |
fields |
body | "ALL" or object |
No (default "ALL") |
Which data fields to return, per output type |
meters |
body | "ALL" or list of UUIDs |
No (default "ALL") |
Filter CPE rows to these meters |
resources |
body | "ALL" or list of UUIDs |
No (default "ALL") |
Filter resource-related rows to these resources |
members |
body | "ALL" or list of UUIDs |
No (default "ALL") |
Filter member-related rows to these members |
Passing "ALL" to any parameter skips that filter or selects everything.
Output types
| Output type | Granularity | Identity columns |
|---|---|---|
cpes |
Per smart meter | datetime_timestamp, cpe_id |
cpes_bilateral |
Per provider/receiver meter pair | datetime_timestamp, provider_cpe_id, receiver_cpe_id |
members |
Per member | datetime_timestamp, user_id |
members_resources |
Per member and resource | datetime_timestamp, user_id, resource_id |
members_resources_bilateral |
Per provider/receiver member-resource pair | datetime_timestamp, provider_user_id, provider_resource_id, receiver_user_id, receiver_resource_id |
resources |
Per resource | datetime_timestamp, resource_id |
resources_bilateral |
Per provider/receiver resource pair | datetime_timestamp, provider_resource_id, receiver_resource_id |
rec |
Community aggregate | datetime_timestamp |
Selecting fields. fields is either "ALL" or an object that maps an output type to "ALL" or a list of
field names. Output types left out of the object default to "ALL".
Selectable fields per output type:
| Output type | Fields |
|---|---|
cpes |
e_lem, e_pur, e_inj, e_con, e_flx_dlv, e_flx_imb, e_alc, e_sur, e_sur_no_csc, e_sup, e_sup_no_csc, e_slc, allocation_coefficient, rev_flx, rev_sur, rev_sur_no_csc, rev_sup, rev_sup_no_csc, rev_slc_soc, rev_slc_dso, rev_total, rev_pow, rev_total_pow |
cpes_bilateral |
e_alc, e_slc, allocation_coefficient |
members |
e_sup, e_sur, e_pur, e_sale, rev_sale, rev_pur, rev_lem_fee, rev_lem_trd, rev_sur, rev_sup, rev_slc_soc, rev_total, rev_total_no_csc, rev_flx, rev_lem, rev_sur_no_csc, rev_sup_no_csc, rev_pow, rev_total_pow, rev_total_pow_no_csc |
members_resources |
e_sur, e_sup, e_slc, rev_lem_fee, rev_lem_trd, rev_sur, rev_sup, rev_slc_soc, e_lem, rev_flx, rev_sur_no_csc, rev_total, rev_pow, rev_total_pow |
members_resources_bilateral |
rev_lem_trd, e_lem |
resources |
e_lem_alc, e_lem, e_inj, e_con, e_flx_dlv, e_flx_imb, e_sur, e_sur_no_csc, e_sup, e_sup_no_csc, e_slc, rev_flx, rev_sur, rev_sur_no_csc, rev_sup, rev_sup_no_csc, rev_slc_soc, rev_total, rev_pow, rev_total_pow |
resources_bilateral |
e_lem_alc, e_lem |
rec |
e_inj, e_con, e_flx_dlv, e_flx_imb, e_sur, e_slc, rev_lem_fee, rev_flx, rev_sur, rev_slc |
Field meanings are in Revenue & Cost Fields and Energy Fields.
Entity filters
| Filter | Applies to |
|---|---|
meters |
cpes and cpes_bilateral. For cpes_bilateral the meter may be on either the provider or the receiver side |
resources |
resources, resources_bilateral, members_resources and members_resources_bilateral. Bilateral tables match either side |
members |
members, members_resources and members_resources_bilateral. Bilateral tables match either side |
rec is a community-level aggregate, so entity filters have no effect on it.
Example
curl -X POST \
https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/outputs/query \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2025-01-01",
"end_date": "2025-01-31",
"outputs": ["cpes", "cpes_bilateral"],
"fields": {
"cpes": ["e_lem", "e_pur"],
"cpes_bilateral": "ALL"
},
"meters": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"]
}'
Response (abridged)
data has one key per requested output type, each holding a list of rows (one per 15-minute ISP).
Every row contains the identity columns of its output type, followed by the requested fields.
UUIDs are serialised as strings and datetime_timestamp as an ISO-8601 string. session_id and
community_id are omitted, as they are implied by the request.
{
"data": {
"cpes": [
{
"datetime_timestamp": "2025-01-01T00:00:00",
"cpe_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"e_lem": 0.12,
"e_pur": 0.05
}
],
"cpes_bilateral": [
{
"datetime_timestamp": "2025-01-01T00:00:00",
"provider_cpe_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"receiver_cpe_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"e_alc": 0.03,
"e_slc": 0.03,
"allocation_coefficient": 0.25
}
]
}
}
Tip
- A key in
fieldsmust also be among the requestedoutputs. An empty list (or[""]) is treated as"ALL". - An unknown field name for an output type, a
fieldskey that is not inoutputs, orend_date < start_datereturns 422 Unprocessable Entity; the message lists the valid field names. - An output type with no rows in the range is returned as an empty list.
- Prefer this endpoint for integrations, dashboards or analyses that need arbitrary combinations of fields or entities over a custom period, since it avoids transferring columns you do not need. The full schema is in the OpenAPI reference.
Billing guides¶
A billing guide is a per-period financial report (revenues, costs and energy per member, resource,
transaction and REC) generated as an Excel workbook or a PDF. Generation is asynchronous: the POST returns a
Celery task_id, and the finished file appears in the community's file folder, from where it can be listed,
downloaded and deleted. The end-to-end flow is in File Exports.
List Billable Members¶
Lists the members that can be selected for a billing guide in a period: those holding an active MEMBER
membership on at least one day of the range. Use the returned id values as user_ids when generating a guide.
Auth / permissions: community admin or platform admin (403 Community admin access required otherwise).
| 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 | Yes | Last day of the period. Must be >= start_date |
Example
curl "https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides/members?start_date=2025-01-01&end_date=2025-01-31" \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{ "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "name": "Alice Silva", "email": "alice@example.com" }
]
Tip
The list is ordered by name and is based on dated membership versions, so a member
who left mid-period still appears. end_date < start_date returns 422 (end_date precedes start_date).
Generate Billing Guide (Excel)¶
Queues the generation of an .xlsx billing guide for the period. Returns immediately with a task id.
Auth / permissions: community admin or platform admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
start_date |
body | date | Yes | First day of the report |
end_date |
body | date | Yes | Last day of the report |
user_ids |
body | list of UUID | No | Members to include. null or [] means all members |
sheets |
body | list of string | Yes in practice | Sheets to include, using the exact names below |
language |
body | en | pt | es |
No (default en) |
Language of the workbook template and sheet names |
Valid sheets values:
Member | Total: totals per memberMember-Resource | Total: totals per member and resourceMember-Resource | Distinct: per-interval detail per member and resourceTransactions | Total: totals of the transactionsTransactions | Distinct: per-interval transaction detailREC Total: community aggregate
Example
curl -X POST \
https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides/excel \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2025-01-01",
"end_date": "2025-01-31",
"user_ids": [],
"sheets": ["Member | Total", "Transactions | Total", "REC Total"],
"language": "pt"
}'
Response (abridged)
Tip
- Poll
GET /core/api/communities/{community_id}/tasks/{task_id}?group_task=false(statePENDING,STARTED,SUCCESS,FAILURE...), or list the billing guides until the new file appears. OnFAILUREtheerrorfield carries the reason. - The response is a plain
200, not202. sheetsis not defaulted: leaving it out makes the background task fail with a generic error. Unknown sheet names are ignored.user_idsmay be taken from List Billable Members.- The file name is generated as
<hash>_<community_name>_<member_count>_<sheet_count>_<YYYYMMDD>_<YYYYMMDD>.xlsx(member_countis0when all members are included). - Request validation errors (invalid dates or
language) return 422 before the task is queued.
Generate Billing Guide (PDF)¶
Same request and response as the Excel version, but produces a .pdf file.
Auth / permissions: community admin or platform admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
start_date |
body | date | Yes | First day of the report |
end_date |
body | date | Yes | Last day of the report |
user_ids |
body | list of UUID | No | Members to include. null or [] means all members |
sheets |
body | list of string | Yes in practice | Same values as the Excel endpoint |
language |
body | en | pt | es |
No (default en) |
Language of the report |
Example
curl -X POST \
https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides/pdf \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"start_date": "2025-01-01",
"end_date": "2025-01-31",
"user_ids": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"],
"sheets": ["Member | Total", "REC Total"],
"language": "en"
}'
Response (abridged)
Tip
The two ... | Distinct sheets are not meant for PDF output and are silently dropped from the request; the file name's
sheet count reflects the sheets that remain. Large ranges or many members can take 30-120 seconds.
List Billing Guides¶
Lists the generated files in the community's folder (.xlsx, .xlsm, .xltx, .xltm and .pdf), newest first.
Auth / permissions: community admin or platform admin (403 Community admin access required otherwise).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
Example
curl https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides \
-H "Authorization: Bearer $TOKEN"
Response (abridged)
[
{ "name": "9f3a1c2e_Community_Name_0_3_20250101_20250131.xlsx", "creation_time": "2025-02-03T10:15:42.123456" }
]
Tip
Returns [] when the community has no generated files yet. name is what you pass as {file_name} to the download and delete
routes. The folder is shared by every file of the community with a supported extension, not only billing guides, and
creation_time is the file's creation time on the server (no time zone marker).
Download Billing Guide¶
Downloads a previously generated file as a binary stream (application/octet-stream).
Auth / permissions: community admin or platform admin. The route is a POST, so community members get 403.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
file_name |
path | string | Yes | File name as returned by List Billing Guides |
Example
curl -X POST \
"https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides/9f3a1c2e_Community_Name_0_3_20250101_20250131.xlsx" \
-H "Authorization: Bearer $TOKEN" \
-o billing-guide.xlsx
Response
The file bytes, with Content-Disposition set to the file name. There is no JSON body.
Tip
This is a POST (not a GET) in the current backend, despite what older docs said. Errors: 400 Invalid file name when the name would resolve outside the community folder (path traversal is rejected).
A non-existent file is meant to return 404, but the handler constructs FileNotFound with a message argument that the
exception class does not accept, so the server currently answers 500 instead.
Delete Billing Guide¶
Permanently deletes a generated billing guide file from the community folder.
Auth / permissions: community admin or platform admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
community_id |
path | UUID | Yes | Community |
file_name |
path | string | Yes | File name as returned by List Billing Guides |
Example
curl -X DELETE \
"https://<host>/core/api/communities/3fa85f64-5717-4562-b3fc-2c963f66afa6/sessions/settlement/billing-guides/9f3a1c2e_Community_Name_0_3_20250101_20250131.xlsx" \
-H "Authorization: Bearer $TOKEN"
Response
Tip
Deletion cannot be undone. Errors: 400 Invalid file name for path-traversal attempts. A non-existent file is meant to return 404, but the same
FileNotFound construction problem as in the download route currently yields 500.