Studio

User-uploaded energy consumption data from CSV imports or smart meters. Enables precise solar optimization based on actual historical usage. See Accuracy — Studio Profile.


GET/v1/studio-profiles

List studio profiles

List all studio profiles for the authenticated organization. Returns lightweight metadata (no hourly data).

Query parameters

  • Name
    page
    Type
    number
    Description
    default: 1

    Page number (1-based)

  • Name
    limit
    Type
    number
    Description
    default: 20

    Items per page

Response

Request

GET
/v1/studio-profiles
curl -G https://api.enhub.nl/v1/studio-profiles \
  -H "x-api-key: {your-api-key}"

Response

{
  "items": [
    {
      "id": "cm5k2l3m4000008l8a1b2c3d4",
      "name": "Profiel 1",
      "baseProfileType": "template",
      "baseProfileName": "Alleenstaand",
      "totalKwh": 3200,
      "peakKw": 4.2,
      "totalExportKwh": 1500,
      "peakExportKw": 3.5,
      "layerCount": 3,
      "hasSolarLayer": false,
      "year": 2026,
      "updatedAt": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 12,
  "page": 1,
  "limit": 20,
  "totalPages": 1
}

GET/v1/studio-profiles/presets

List available templates and layer presets

Returns the available household templates and layer presets with their default configurations.

Response

Request

GET
/v1/studio-profiles/presets
curl -G https://api.enhub.nl/v1/studio-profiles/presets \
  -H "x-api-key: {your-api-key}"

Response

{
  "templates": [
    {
      "id": "stel",
      "label": "Stel",
      "description": "Tweepersoons­huishouden, standaard verbruik",
      "annualKwh": 3200,
      "icon": "Users"
    }
  ],
  "layerPresets": [
    {
      "id": "ev",
      "name": "Elektrische auto",
      "icon": "Car",
      "color": "energy",
      "maxKw": 7,
      "defaultHourlyKw": [
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0.5,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        0.5,
        0,
        0,
        0
      ]
    }
  ]
}

POST/v1/studio-profiles

Create new studio profile

Create a new empty studio profile. The name defaults to "Profiel N" based on the number of existing profiles in the project.

Optional attributes

  • Name
    name
    Type
    string
    Description

    Display name for the profile

  • Name
    year
    Type
    number
    Description

    Profile year

  • Name
    lat
    Type
    number
    Description

    Latitude for solar production calculations (default 52.09)

  • Name
    lon
    Type
    number
    Description

    Longitude for solar production calculations (default 5.12)

Response

Request

POST
/v1/studio-profiles
curl -X POST https://api.enhub.nl/v1/studio-profiles \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Profiel 1",
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12
}'

Response (201 Created)

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

GET/v1/studio-profiles/:id

Fetch complete studio profile

Fetches the complete studio profile including base profile, layers with configs and computed data, and the final result array.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

GET
/v1/studio-profiles/:id
curl -G https://api.enhub.nl/v1/studio-profiles/{id} \
  -H "x-api-key: {your-api-key}"

Response

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z",
  "baseline": {
    "sourceType": "template",
    "name": "string",
    "templateId": "string",
    "annualKwh": 0,
    "annualExportKwh": 0
  },
  "layers": [
    {
      "id": "string",
      "name": "string",
      "type": "string",
      "enabled": true,
      "icon": "string",
      "color": "string",
      "schedule": [
        [
          "..."
        ]
      ],
      "maxKw": 0,
      "solarConfig": {
        "roofSurfaces": [
          "..."
        ],
        "panelCount": 0,
        "panelPowerWatts": 0,
        "tilt": 0,
        "azimuth": 0,
        "losses": 0,
        "systemCapacityKw": 0,
        "annualProductionKwh": 0
      }
    }
  ]
}

GET/v1/studio-profiles/:id/chart

Get chart data for a studio profile

Returns aggregated chart data (week, month, or year view) for the profile. Includes both baseline and combined (with layers) series.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Query parameters

  • Name
    view
    Type
    string
    required
    Description

    Chart view type. production/export return solar/export data with a sub-view parameter. One of: week, month, year, production, export.

  • Name
    index
    Type
    number
    Description

    Index: week 0-51, month 0-11

Response

Request

GET
/v1/studio-profiles/:id/chart
curl -G https://api.enhub.nl/v1/studio-profiles/{id}/chart \
  -H "x-api-key: {your-api-key}"

GET/v1/studio-profiles/:id/export-csv

Export profile as CSV

Download the combined result as a CSV file with 8760 hourly kWh values.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

GET
/v1/studio-profiles/:id/export-csv
curl -G https://api.enhub.nl/v1/studio-profiles/{id}/export-csv \
  -H "x-api-key: {your-api-key}"

POST/v1/studio-profiles/:id/duplicate

Duplicate studio profile

Create a copy of a studio profile, including its state file. The name defaults to "{original name} (kopie)".

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Optional attributes

  • Name
    name
    Type
    string
    Description

    Name for the duplicated profile

Response

Request

POST
/v1/studio-profiles/:id/duplicate
curl -X POST https://api.enhub.nl/v1/studio-profiles/{id}/duplicate \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Profiel 1 (kopie)"
}'

Response (201 Created)

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

POST/v1/studio-profiles/:id/base

Set base profile from template

Set a template-based base profile for the studio profile. Auto-recomputes the result. Replaces any existing base profile.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Required attributes

  • Name
    templateId
    Type
    string
    required
    Description

    Template ID: alleenstaand, stel, thuiswerkers-kinderen, groot-gezin

Optional attributes

  • Name
    annualKwh
    Type
    number
    Description

    Override annual kWh (rescales the template shape)

Response

Request

POST
/v1/studio-profiles/:id/base
curl -X POST https://api.enhub.nl/v1/studio-profiles/{id}/base \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "templateId": "stel",
  "annualKwh": 3500
}'

Response (201 Created)

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

POST/v1/studio-profiles/:id/base/upload

Set base profile from CSV upload

Upload a P1/HomeWizard/Fluvius CSV to set the base profile. The file is parsed server-side. Auto-detects format. Daily-resolution files are rejected.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

POST
/v1/studio-profiles/:id/base/upload
curl -X POST https://api.enhub.nl/v1/studio-profiles/{id}/base/upload \
  -H "x-api-key: {your-api-key}"

Response (201 Created)

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

POST/v1/studio-profiles/:id/layers

Add a layer to the profile

Add a new adjustment, solar, or EV layer from a preset. Solar layers auto-fetch production data. EV layers auto-run simulation. Only one solar layer and one EV layer per profile. Base profile must be set first.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Required attributes

  • Name
    presetId
    Type
    string
    required
    Description

    Preset ID: ev, warmtepomp, zwembad, custom, solar

Optional attributes

  • Name
    name
    Type
    string
    Description

    Custom name for the layer

  • Name
    enabled
    Type
    boolean
    Description

    Whether the layer is enabled (default true)

  • Name
    schedule
    Type
    boolean[][]
    Description

    7×12 boolean schedule matrix (Mon-Sun × Jan-Dec). Outer array = 7 days (Mon-Sun), inner array = 12 months (Jan-Dec).

  • Name
    hourlyKw
    Type
    number[]
    Description

    24-value hourly kW draw pattern (index 0 = midnight, index 23 = 11pm)

  • Name
    maxKw
    Type
    number
    Description

    Maximum kW for the layer

  • Name
    solarConfig
    Type
    SolarConfigDto
  • Name
    evConfig
    Type
    EvConfigDto

Response

Request

POST
/v1/studio-profiles/:id/layers
curl -X POST https://api.enhub.nl/v1/studio-profiles/{id}/layers \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "presetId": "ev",
  "name": "string",
  "enabled": true,
  "schedule": [
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ]
  ],
  "hourlyKw": [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    3.5,
    3.5,
    3.5,
    3.5,
    0,
    0
  ],
  "maxKw": 0,
  "solarConfig": {
    "roofSurfaces": [
      {
        "id": "string",
        "panelCount": 0,
        "panelPowerWatts": 0,
        "systemCapacityKw": 0,
        "tilt": 0,
        "azimuth": 0,
        "losses": 0,
        "annualProductionKwh": 0
      }
    ],
    "panelCount": 0,
    "panelPowerWatts": 0,
    "tilt": 0,
    "azimuth": 0,
    "losses": 0,
    "systemCapacityKw": 0,
    "annualProductionKwh": 0
  },
  "evConfig": {
    "count": 1,
    "batteryKwh": 60,
    "dailyConsumptionKwh": 12,
    "arrivalHour": 18,
    "departureHour": 8,
    "chargerPowerKw": 11
  }
}'

Response (201 Created)

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

PUT/v1/studio-profiles/:id

Save studio profile

Full save of the studio profile editor state. Uploads the complete state (base profile, layers with configs + computed data, result array). Also updates DB summary stats and writes the result to the profile JSONB column for scan compatibility.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Required attributes

  • Name
    studioState
    Type
    StudioStateDto
    required

Optional attributes

  • Name
    year
    Type
    number
    Description

    Profile year

Response

Request

PUT
/v1/studio-profiles/:id
curl -X PUT https://api.enhub.nl/v1/studio-profiles/{id} \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "studioState": {
    "baseProfile": {
      "type": "template",
      "templateId": "string",
      "name": "Alleenstaand",
      "description": "string",
      "annualKwh": 2500,
      "data": [
        0
      ],
      "exportData": [
        0
      ],
      "originalData": [
        0
      ]
    },
    "layers": [
      {
        "id": "string",
        "type": "ev_charger",
        "name": "Elektrische auto",
        "enabled": true,
        "config": null,
        "data": [
          "..."
        ]
      }
    ],
    "result": [
      0
    ],
    "exportResult": [
      0
    ],
    "productionResult": [
      0
    ]
  },
  "year": 2026
}'

Response

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

PATCH/v1/studio-profiles/:id

Rename studio profile

Update the display name of a studio profile.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Required attributes

  • Name
    name
    Type
    string
    required
    Description

    Updated display name for the profile

Response

Request

PATCH
/v1/studio-profiles/:id
curl -X PATCH https://api.enhub.nl/v1/studio-profiles/{id} \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Mijn thuisprofiel"
}'

Response

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

PATCH/v1/studio-profiles/:id/layers/:layerId

Update a layer

Partially update an existing layer. Solar config changes trigger a production data re-fetch. EV config changes trigger a re-simulation. Auto-recomputes the result.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

  • Name
    layerId
    Type
    string
    required
    Description

    No description available.

Optional attributes

  • Name
    name
    Type
    string
    Description

    Layer name

  • Name
    enabled
    Type
    boolean
    Description

    Whether the layer is enabled

  • Name
    schedule
    Type
    boolean[][]
    Description

    7×12 boolean schedule matrix (Mon-Sun × Jan-Dec). Outer array = 7 days (Mon-Sun), inner array = 12 months (Jan-Dec).

  • Name
    hourlyKw
    Type
    number[]
    Description

    24-value hourly kW draw pattern (index 0 = midnight, index 23 = 11pm)

  • Name
    maxKw
    Type
    number
    Description

    Maximum kW for the layer

  • Name
    solarConfig
    Type
    SolarConfigDto
  • Name
    evConfig
    Type
    EvConfigDto

Response

Request

PATCH
/v1/studio-profiles/:id/layers/:layerId
curl -X PATCH https://api.enhub.nl/v1/studio-profiles/{id}/layers/{layerId} \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "enabled": true,
  "schedule": [
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ],
    [
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true,
      true
    ]
  ],
  "hourlyKw": [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    3.5,
    3.5,
    3.5,
    3.5,
    0,
    0
  ],
  "maxKw": 0,
  "solarConfig": {
    "roofSurfaces": [
      {
        "id": "string",
        "panelCount": 0,
        "panelPowerWatts": 0,
        "systemCapacityKw": 0,
        "tilt": 0,
        "azimuth": 0,
        "losses": 0,
        "annualProductionKwh": 0
      }
    ],
    "panelCount": 0,
    "panelPowerWatts": 0,
    "tilt": 0,
    "azimuth": 0,
    "losses": 0,
    "systemCapacityKw": 0,
    "annualProductionKwh": 0
  },
  "evConfig": {
    "count": 1,
    "batteryKwh": 60,
    "dailyConsumptionKwh": 12,
    "arrivalHour": 18,
    "departureHour": 8,
    "chargerPowerKw": 11
  }
}'

Response

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

DELETE/v1/studio-profiles/:id

Delete studio profile

Delete a studio profile and state file. If this profile is referenced by any scans, those references will be set to null.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

DELETE
/v1/studio-profiles/:id
curl -X DELETE https://api.enhub.nl/v1/studio-profiles/{id} \
  -H "x-api-key: {your-api-key}"

DELETE/v1/studio-profiles/:id/layers/:layerId

Remove a layer

Remove a layer from the profile. Auto-recomputes the result.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

  • Name
    layerId
    Type
    string
    required
    Description

    No description available.

Response

Request

DELETE
/v1/studio-profiles/:id/layers/:layerId
curl -X DELETE https://api.enhub.nl/v1/studio-profiles/{id}/layers/{layerId} \
  -H "x-api-key: {your-api-key}"

Response

{
  "id": "cm5k2l3m4000008l8a1b2c3d4",
  "name": "Profiel 1",
  "baseProfileType": "template",
  "baseProfileName": "Alleenstaand",
  "totalKwh": 3200,
  "peakKw": 4.2,
  "totalExportKwh": 1500,
  "peakExportKw": 3.5,
  "layerCount": 3,
  "hasSolarLayer": false,
  "year": 2026,
  "lat": 52.09,
  "lon": 5.12,
  "userId": "string",
  "organizationId": "string",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

Was this page helpful?