Skip to content

Energy Management API

Base path: /core/api/communities/{community_id}/energy_management

All endpoints require a valid Keycloak Bearer token.


Module Discovery

List all modules

GET /core/api/communities/{community_id}/energy_management/modules

Returns all registered EMS modules with metadata (category, maturity, capabilities).

Get a module's config schema

GET /core/api/communities/{community_id}/energy_management/modules/{module_type}/schema

Returns the JSON Schema for the module's config_data field. Use this before creating a configuration to know which fields are required.


Activate an Optimization Module

Creating a configuration is how you activate a module for a community. Only one configuration per module_type is allowed per community.

POST /core/api/communities/{community_id}/energy_management/configs
Field Type Default Description
module_type string Required. See Optimization for the full list
horizon integer 24 Optimization window in hours
delta_t number 1.0 Time resolution in hours (0.25 = 15 min)
strict_pos_coeffs boolean true Enforce strictly positive allocation coefficients
total_share_coeffs boolean false Use total share coefficients
config_data object {} Module-specific parameters — see each module's page
curl -X POST \
  https://<host>/core/api/communities/{community_id}/energy_management/configs \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "module_type": "OSTEC_SIMPLE",
    "horizon": 24,
    "delta_t": 1.0,
    "strict_pos_coeffs": true,
    "total_share_coeffs": false,
    "config_data": {
      "solver": "CPLEX",
      "l_extra": 10.0,
      "l_market_buy": 500.0,
      "l_market_sell": -500.0
    }
  }'
curl -X POST \
  https://<host>/core/api/communities/{community_id}/energy_management/configs \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "module_type": "OSTEC_PROMOTOR",
    "horizon": 24,
    "delta_t": 1.0,
    "config_data": {
      "type_coef": "coef_prop",
      "type_method": "PYOMO",
      "percentage": 1.0,
      "l_lem_mnh_value": 0.01
    }
  }'
curl -X POST \
  https://<host>/core/api/communities/{community_id}/energy_management/configs \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "module_type": "GDBN_BEFLEXIBLE",
    "horizon": 24,
    "delta_t": 1.0,
    "config_data": {
      "external_zone_id": "GDBN-ZONE-42",
      "l_flex_init": 0.01,
      "l_flex_increment": 0.01,
      "divisible": true
    }
  }'

Response (all modules):

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "community_id": "...",
  "module_type": "OSTEC_SIMPLE",
  "horizon": 24,
  "delta_t": 1.0,
  "strict_pos_coeffs": true,
  "total_share_coeffs": false,
  "config_data": { "solver": "CPLEX", "l_extra": 10.0 },
  "is_active": true,
  "created_at": "2026-04-17T10:00:00Z",
  "updated_at": "2026-04-17T10:00:00Z",
  "last_run_at": null,
  "last_run_status": null,
  "last_error": null,
  "run_count": 0
}

Save the id — you need it to trigger calculations.


Manage Configurations

GET    /core/api/communities/{community_id}/energy_management/configs
GET    /core/api/communities/{community_id}/energy_management/configs/{config_id}
PATCH  /core/api/communities/{community_id}/energy_management/configs/{config_id}
DELETE /core/api/communities/{community_id}/energy_management/configs/{config_id}

To disable a module without deleting it:

curl -X PATCH \
  https://<host>/core/api/communities/{community_id}/energy_management/configs/{config_id} \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Trigger a Calculation

POST /core/api/communities/{community_id}/energy_management/configs/{config_id}/calculate
Query param Type Default Description
target_date YYYY-MM-DD tomorrow Day-ahead optimization date

The configuration must have is_active = true.

Synchronous response (most modules):

{
  "message": "Calculation completed successfully",
  "config_id": "...",
  "module_type": "OSTEC_SIMPLE",
  "result_summary": { "status": "success", "setpoints_count": 96 }
}

Asynchronous response (OSTEC_PROMOTOR):

{
  "message": "Calculation dispatched to background worker",
  "config_id": "...",
  "module_type": "OSTEC_PROMOTOR",
  "target_date": "2026-04-18",
  "async": true
}

For async modules, poll GET /configs/{config_id} and check last_run_status: RUNNINGSUCCESS or FAILED (check last_error on failure).


Query Setpoints

GET /core/api/communities/{community_id}/energy_management/setpoints
  ?module_type=OSTEC_SIMPLE
  &start_datetime=2026-04-18T00:00:00Z
  &end_datetime=2026-04-18T23:59:59Z
  &resource_id=<uuid>
  &limit=100
  &offset=0

setpoint_type values: CONSUME (charge/consume) · INJECT (discharge/export)


Receive External Setpoints (GDBN)

Modules with external_setpoint_reception capability accept setpoints pushed by external services.

curl -X POST \
  "https://<host>/core/api/communities/{community_id}/energy_management/setpoints/external/GDBN_BEFLEXIBLE/batch" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "resource_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "meter_id": "660e8400-e29b-41d4-a716-446655440001",
      "datetime_timestamp": "2024-01-15T10:00:00Z",
      "setpoint_value": 5.2,
      "setpoint_type": "CONSUME",
      "metadata": { "source": "GDBN_BEFLEXIBLE" }
    }
  ]'

Duplicate setpoints (same resource + timestamp + config) are upserted.


Receive External Flexibility Offers (GDBN)

POST /core/api/communities/{community_id}/energy_management/offers/external/{module_type}
POST /core/api/communities/{community_id}/energy_management/offers/external/{module_type}/batch