Customer Data Service

Endpoint docs

Base paths

REST reference

The dashboard UI calls its same-origin server proxy at /api/rest/v1. Direct Customer Data Service calls use /rest/v1. The dashboard keeps upstream access tokens in HttpOnly cookies and attaches Authorization: Bearer <jwt> from the server proxy. Direct protected API calls still require that header. Auth failures return 401.

Endpoints

POST /rest/v1/auth/token

Creates an access token from username and password.

JSON body

FieldTypeRequired
usernamestringyes
passwordstringyes

Returns

{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2026-06-03T12:00:00Z",
  "session_expires_at": "2026-06-03T23:00:00Z"
}
POST /rest/v1/auth/refresh

Renews an unexpired bearer token within the session window. Refreshes are capped by session_expires_at; once the session expires, the user must log in again.

Headers

NameValueRequired
AuthorizationBearer <jwt>yes

Returns

Same shape as /auth/token.

GET /rest/v1/auth/permissions

Returns bid groups and asset IDs available to the authenticated user.

Returns

{
  "bid_groups": ["DemoGroup"],
  "asset_ids": ["asset-demo-001"]
}
GET /rest/v1/finance/asset-revenue

Returns revenue rows for one accessible asset and UTC interval. Requests for assets outside the authenticated user's permissions return 403.

Query parameters

NameTypeRequiredExample
asset_idstringyesasset-demo-001
start_utcRFC3339 timestampyes2026-01-01T00:00:00Z
end_utcRFC3339 timestampyes2026-01-02T00:00:00Z

Returns

{
  "rows": [{
    "delivery_start_utc": "2026-01-01T00:00:00Z",
    "product": "FCR",
    "auction": "DAY_AHEAD",
    "asset_id": "asset-demo-001",
    "delivery_area": "DK2",
    "resolution": "PT1H",
    "qty": 1.25,
    "qty_unit": "MW",
    "revenue_eur": 12.5,
    "twig_share_percentage": 50,
    "twig_share_revenue_eur": 6.25,
    "updated_utc": "2026-01-01T12:00:00Z"
  }]
}
GET /rest/v1/finance/asset-revenue-date

Returns preaggregated revenue rows for one accessible asset and CET/CEST delivery dates. Requests for assets outside the authenticated user's permissions return 403.

Query parameters

NameTypeRequiredExample
asset_idstringyesasset-demo-001
start_dateCET dateyes2026-01-01
end_dateCET dateyes2026-01-02

Returns

[
  {
    "date": "2026-01-01",
    "revenues": [
      {
        "date": "2026-01-01",
        "product": "FCR_N",
        "auction": "SD2_EARLY",
        "qty": 3,
        "qty_unit": "MW",
        "revenue_eur": 30
      }
    ]
  }
]
GET Market price endpoints

Returns market price rows for the auction fixed by the endpoint path.

Endpoints

AuctionPath
DA/rest/v1/finance/day-ahead-prices
IDA1/rest/v1/finance/ida1-prices
IDA2/rest/v1/finance/ida2-prices
IDA3/rest/v1/finance/ida3-prices

Query parameters

NameTypeRequiredExample
dateYYYY-MM-DDyes2025-12-01
delivery_areastringyesDK2
resolutionPT15M or PT1HyesPT1H

Returns

{
  "rows": [{
    "delivery_start_utc": "2025-12-01T00:00:00Z",
    "delivery_area": "DK2",
    "product": "dk2.h00.q0",
    "auction": "DA",
    "resolution": "PT1H",
    "price_eur": 42.5,
    "price_unit": "EUR/MWh"
  }]
}
GET Market volume endpoints

Returns market quantity rows for the auction fixed by the endpoint path.

Endpoints

AuctionPath
DA/rest/v1/finance/day-ahead-volumes
IDA1/rest/v1/finance/ida1-volumes
IDA2/rest/v1/finance/ida2-volumes
IDA3/rest/v1/finance/ida3-volumes

Query parameters

Same as market prices: date, delivery_area, and resolution.

Returns

{
  "rows": [{
    "delivery_start_utc": "2025-12-01T00:00:00Z",
    "delivery_area": "DK2",
    "product": "dk2.h00.q0",
    "auction": "DA",
    "resolution": "PT1H",
    "quantity_mwh": 12.5,
    "quantity_unit": "MWh"
  }]
}
GET /rest/v1/finance/capacity-market-prices

Returns fixed-shape capacity-market prices from market-data-service. The API always requests all supported PT1H capacity prices upstream.

Product filters are not accepted; old products and anc_products query parameters return 400. Missing upstream rows or upstream NaN values are returned as null.

Query parameters

NameTypeRequiredExample
dateYYYY-MM-DDyes2025-12-01
delivery_areastringyesDK2

Returns

{
  "rows": [{
    "delivery_start_utc": "2025-11-30T23:00:00Z",
    "delivery_area": "DK2",
    "resolution": "PT1H",
    "price_unit": "EUR/MW",
    "fcr_price_eur_mw": null,
    "fcr_d_up_sd2_early_price_eur_mw": 9.25,
    "fcr_d_up_sd1_late_price_eur_mw": null,
    "fcr_d_up_avg_price_eur_mw": null,
    "fcr_d_down_sd2_early_price_eur_mw": null,
    "fcr_d_down_sd1_late_price_eur_mw": null,
    "fcr_d_down_avg_price_eur_mw": null,
    "fcr_n_sd2_early_price_eur_mw": null,
    "fcr_n_sd1_late_price_eur_mw": null,
    "fcr_n_avg_price_eur_mw": null,
    "ffr_price_eur_mw": null,
    "afrr_up_price_eur_mw": null,
    "afrr_down_price_eur_mw": null,
    "mfrr_up_price_eur_mw": null,
    "mfrr_down_price_eur_mw": null
  }]
}
GET /rest/v1/finance/imbalance-prices

Returns imbalance prices and optional balancing/aFRR/mFRR source prices. Nullable source fields are null when market-data-service has no value for that source row. Internal source paths and ingestion timestamps are intentionally not exposed.

Query parameters

NameTypeRequiredExample
dateYYYY-MM-DDyes2025-12-01
delivery_areastringyesDK2
resolutionPT15M or PT1HyesPT15M

Returns

{
  "rows": [{
    "delivery_start_utc": "2025-12-01T00:00:00Z",
    "delivery_area": "DK2",
    "resolution": "PT15M",
    "imbalance_price_eur_mwh": 42.5,
    "balancing_up_price_eur_mwh": 111.1,
    "balancing_down_price_eur_mwh": null,
    "afrr_up_eam_vwap_eur_mwh": null,
    "afrr_down_eam_vwap_eur_mwh": 12.3,
    "mfrr_up_eam_eur_mwh": null,
    "mfrr_down_eam_eur_mwh": null
  }]
}
ERR Error responses

Auth failures return 401. Asset permission failures return 403. Validation failures return 400 with problem-style JSON; market-data-service INVALID_ARGUMENT errors also return 400. Unsupported finance sources return 501, upstream service failures return 502, and unexpected JSON encoding failures return 500.

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "detail": "Invalid request",
  "errors": [{"message": "resolution must be PT15M or PT1H"}]
}