Login

Locations, Areas, and Price Signals

This guide covers how to set up locations with areas, activate zones, and push price signals. These are prerequisites for flex shape computation.

Copy linkLocations and Areas

Locations represent physical sites where assets are installed. Each location has two geographic classification fields, both set by you:

  • zone — the electricity bidding zone the location belongs to (e.g., NO1, SE3, FI). This is the top-level grouping for flex shapes.
  • area — the sub-area within the zone. Areas are how you scope price signals to groups of locations. The area value is opaque to Enode; use whatever grouping is meaningful to your integration (forecast areas, grid areas, metering grid areas, etc.).

Copy linkCreating a Location

POST /users/{userId}/locations
Content-Type: application/json

{
  "name": "Household A",
  "latitude": 59.911,
  "longitude": 10.753,
  "timezoneName": "Europe/Oslo",
  "zone": "NO1",
  "area": "FA_12"
}

{
  "id": "4eaeb363-296d-4ccc-a973-7805e6f400bd",
  "userId": "b3a49e7c-8c9a-4b1f-8f4a-2e5d3c6a7b8c",
  "name": "Household A",
  "latitude": 59.911,
  "longitude": 10.753,
  "timezoneName": "Europe/Oslo",
  "zone": "NO1",
  "area": "FA_12",
  "createdAt": "2024-06-14T10:00:00Z"
}

Both zone and area are required.

Copy linkSingle-Area Zones

If your market has a single pricing zone with no meaningful geographic subdivisions, set the area to the same value as the zone:

{
  "zone": "BE",
  "area": "BE"
}

This keeps the model uniform — you push one price signal to one area. No special configuration is needed.

Copy linkUpdating a Location

PUT /locations/{locationId}
Content-Type: application/json

{
  "zone": "NO2",
  "area": "FA_13"
}

All fields on the update payload are optional. You can update zone and area independently of other location fields.

Copy linkHow Zone and Area Are Used

The zone is the top-level grouping — flex shapes are queried per zone (GET /flex/shape/{zoneId}).

The area is how price signals are scoped to locations. Each location has exactly one area, so there is no ambiguity about which price applies. Areas serve two purposes:

  • Price signals — prices are pushed per area, and each location receives the price signal for its area
  • Shape filtering — query the flex shape endpoint with an area parameter to get shapes for a geographic subset of a zone

Copy linkZone Activation

Before price signals can be pushed or flex shapes computed for a zone, the zone must be activated. Activation sets the currency that all subsequent price signal and tariff data must use.

POST /flex/zones/{zoneId}
Content-Type: application/json

{
  "currency": "EUR"
}

{
  "id": "NO1",
  "currency": "EUR",
  "createdAt": "2024-06-14T10:00:00Z",
  "updatedAt": "2024-06-14T10:00:00Z"
}

Activation requires:

  1. At least one location exists in the zone.
  2. All locations have an area. Since prices are always pushed per area, every location must have an area before the zone can accept price signals.

The currency is validated on every subsequent price signal push and tariff formula configuration, ensuring all price inputs for a zone use the same currency.

Copy linkListing Zones

GET /flex/zones

Returns all activated zones.

Copy linkDiscovering Areas

Areas are not explicitly created — they exist implicitly as values on locations. Use this endpoint to see all areas in a zone, how many locations each has, and whether a price signal has been pushed:

GET /flex/zones/NO1/areas

{
  "zoneId": "NO1",
  "areas": [
    { "areaId": "FA_12", "locationCount": 142, "hasPriceSignal": true },
    { "areaId": "FA_13", "locationCount": 89, "hasPriceSignal": true },
    { "areaId": "FA12", "locationCount": 3, "hasPriceSignal": false }
  ]
}

Copy linkPrice Signals

Price signals represent the wholesale price signal — day-ahead prices, forecasted day-ahead prices, or forecasted imbalance prices. From the API's perspective these are all the same data type: a timeseries of prices over future time slots. The distinction matters only for how often you update them.

Copy linkPushing Price Signals

Push a price signal for an area within a zone:

PUT /flex/price-signals/{zoneId}/areas/{areaId}
Content-Type: application/json

{
  "currency": "EUR",
  "to": "2024-06-16T00:00:00Z",
  "values": [
    { "at": "2024-06-15T00:00:00Z", "price": 0.045 },
    { "at": "2024-06-15T01:00:00Z", "price": 0.038 },
    { "at": "2024-06-15T02:00:00Z", "price": 0.029 },
    { "at": "2024-06-15T06:00:00Z", "price": 0.052 },
    { "at": "2024-06-15T12:00:00Z", "price": 0.089 },
    { "at": "2024-06-15T18:00:00Z", "price": 0.142 }
  ]
}

Each location receives the price signal for its area. If multiple areas share the same prices, use the bulk endpoint to push once for all of them.

Copy linkBulk Push

Push the same price signal to multiple areas in one call:

PUT /flex/price-signals/{zoneId}/areas
Content-Type: application/json

{
  "areas": ["FA_01", "FA_02", "FA_03"],
  "currency": "EUR",
  "to": "2024-06-16T00:00:00Z",
  "values": [
    { "at": "2024-06-15T00:00:00Z", "price": 0.045 },
    { "at": "2024-06-15T01:00:00Z", "price": 0.038 }
  ]
}

Each area gets its own stored price signal — this is a convenience to reduce HTTP calls.

Copy linkPush Format

Timestamps are UTC. Each value defines the price from its timestamp until the next value (step function). The body specifies a replacement window — all existing data in the window is replaced with the provided values.

  • At least one value is required
  • Values must be ordered chronologically
  • The first value's at defines the start of the replacement window
  • Data outside [firstValue.at, to) is untouched
  • Currency must match the zone's configured currency

The currency field in the push payload is validated against the zone's configured currency. This serves as an explicit confirmation, catching integration bugs where a system is accidentally pointed at the wrong zone.

Copy linkWhat Happens on Push

Each price signal push updates the optimization target for all assets at locations in that area. The system incorporates the new prices into scheduling decisions as follows:

  • Future schedules reflect the updated prices immediately. Any time slot where a command has not yet been sent is free to change at no cost.
  • Currently executing commands are not interrupted unless the price change is significant enough to justify it. The system accounts for the cost and reliability of sending new commands — a small price fluctuation will not cause unnecessary churn, while a large price spike will trigger re-scheduling where it makes economic sense.
  • Each asset is evaluated independently. An asset with a strong track record of responding to commands may be re-scheduled more readily than one with a patchy history, even if both are in the same area.

Push forecasts as often as you have updated data. Frequent small updates are preferred over infrequent large ones — the system is designed to handle high-frequency price updates efficiently.

Copy linkReading Price Signals

Retrieve the current price signal for an area over a time range:

GET /flex/price-signals/{zoneId}/areas/{areaId}?from=2024-06-15T00:00:00Z&to=2024-06-16T00:00:00Z

{
  "zoneId": "NO1",
  "areaId": "FA_12",
  "currency": "EUR",
  "from": "2024-06-15T00:00:00Z",
  "to": "2024-06-16T00:00:00Z",
  "values": [
    { "at": "2024-06-15T00:00:00Z", "price": 0.045 },
    { "at": "2024-06-15T01:00:00Z", "price": 0.038 },
    { "at": "2024-06-15T02:00:00Z", "price": 0.029 },
    { "at": "2024-06-15T06:00:00Z", "price": 0.052 },
    { "at": "2024-06-15T12:00:00Z", "price": 0.089 },
    { "at": "2024-06-15T18:00:00Z", "price": 0.142 }
  ]
}

Copy linkEndpoint Reference

Task Method Endpoint
Create locationPOST/users/{userId}/locations
Update locationPUT/locations/{locationId}
Activate zonePOST/flex/zones/{zoneId}
Get zoneGET/flex/zones/{zoneId}
List zonesGET/flex/zones
List areas in zoneGET/flex/zones/{zoneId}/areas
Push price signalPUT/flex/price-signals/{zoneId}/areas/{areaId}
Push price signal (bulk)PUT/flex/price-signals/{zoneId}/areas
Read price signalGET/flex/price-signals/{zoneId}/areas/{areaId}
Next: Segments and Flex Shape

Define household segments and retrieve the flex shape forecast

Was this article helpful?