Skip to content

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

GET /core/api/communities/{community_id}/sessions/settlement/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)

{
  "savings_perc": 12.4,
  "savings": 86.35,
  "rev_total_pow": -4.1
}

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

GET /core/api/communities/{community_id}/sessions/settlement/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

GET /core/api/communities/{community_id}/sessions/settlement/settlement-resource-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)

{
  "5b2c1e40-0c3a-4c52-9d0e-1f6a8d9b7a11": {
    "rev_total": 42.7,
    "rev_total_perc": 61.3
  }
}

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)

POST /core/api/communities/{community_id}/sessions/settlement/outputs/query

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".

"fields": {
  "cpes": ["e_lem", "e_pur"],
  "cpes_bilateral": "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 fields must also be among the requested outputs. An empty list (or [""]) is treated as "ALL".
  • An unknown field name for an output type, a fields key that is not in outputs, or end_date < start_date returns 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

GET /core/api/communities/{community_id}/sessions/settlement/billing-guides/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)

POST /core/api/communities/{community_id}/sessions/settlement/billing-guides/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 member
  • Member-Resource | Total: totals per member and resource
  • Member-Resource | Distinct: per-interval detail per member and resource
  • Transactions | Total: totals of the transactions
  • Transactions | Distinct: per-interval transaction detail
  • REC 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)

{ "message": "Processing started", "task_id": "b1c6e8a2-3d4f-4e5a-9a7b-0c1d2e3f4a5b" }

Tip

  • Poll GET /core/api/communities/{community_id}/tasks/{task_id}?group_task=false (state PENDING, STARTED, SUCCESS, FAILURE...), or list the billing guides until the new file appears. On FAILURE the error field carries the reason.
  • The response is a plain 200, not 202.
  • sheets is not defaulted: leaving it out makes the background task fail with a generic error. Unknown sheet names are ignored. user_ids may be taken from List Billable Members.
  • The file name is generated as <hash>_<community_name>_<member_count>_<sheet_count>_<YYYYMMDD>_<YYYYMMDD>.xlsx (member_count is 0 when all members are included).
  • Request validation errors (invalid dates or language) return 422 before the task is queued.

Generate Billing Guide (PDF)

POST /core/api/communities/{community_id}/sessions/settlement/billing-guides/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)

{ "message": "Processing started", "task_id": "b1c6e8a2-3d4f-4e5a-9a7b-0c1d2e3f4a5b" }

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

GET /core/api/communities/{community_id}/sessions/settlement/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

POST /core/api/communities/{community_id}/sessions/settlement/billing-guides/{file_name}

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

DELETE /core/api/communities/{community_id}/sessions/settlement/billing-guides/{file_name}

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

{ "message": "File 9f3a1c2e_Community_Name_0_3_20250101_20250131.xlsx deleted successfully" }

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.