Scans

Scans are the soul of Enhub — comprehensive energy optimization reports that analyze your specific situation and provide tailored recommendations for solar panels, battery storage, and energy management. Each scan considers real-world factors including your location's solar irradiance, consumption patterns, electricity tariffs, and existing infrastructure to deliver actionable insights.


Understanding the Scan Process

Because energy optimization involves complex mathematical modeling and simulation of thousands of scenarios, scans are processed asynchronously. Here's how it works:

1. Submit Your Scan

When you create a scan via POST /v1/scan, you'll immediately receive a run_uuid — a unique identifier for tracking your scan. The optimization begins processing in the background.

2. Monitor Progress

You have two options to track your scan's progress:

  • WebSocket Connection (Recommended): Connect to our WebSocket service for real-time status updates. You'll receive instant notifications as your scan progresses, and the connection automatically closes when complete.

  • Polling: Use the GET /v1/scan/status endpoint to check status and progression percentage. Poll every 5-10 seconds until status becomes "optimal".

3. Retrieve Results

Once the status is "optimal" (100% complete), call GET /v1/scan with your run_uuid to retrieve the full optimization report including investment costs, payback period, recommended system configurations, and projected savings.

What Happens During Processing?

Behind the scenes, our optimization engine:

  • Simulates 8,760 hours of energy flows (one full year)
  • Evaluates thousands of system configurations
  • Calculates optimal battery charging/discharging schedules
  • Determines ideal solar panel quantities and orientations
  • Analyzes financial metrics including NPV, payback time, and lifetime savings
  • Models grid interaction and self-sufficiency levels

This typically takes 2-5 minutes depending on system complexity.


POST/v1/scan

Create a scan

  • Name
    goal
    Type
    string
    Required
    required
    Description

    Optimization target: choose self-sufficiency to maximize energy independence, or payback-time to minimize return on investment period.

    Impact on Cost Modeling: When set to "self-sufficiency", new solar panel installation costs are set to €0 in the optimization (since the goal is energy independence, not financial ROI). When set to "payback-time", realistic installation costs based on system size are applied to calculate payback period accurately.

  • Name
    tariff
    Type
    object
    Description

    Electricity tariff configuration for the site.

    • Name
      type
      Type
      string
      Required
      required
      Description

      Type of electricity tariff. Options: flat or dynamic.

    • Name
      flat_eur_per_kwh
      Type
      number
      Description

      Flat tariff rate in euros per kWh (required if type = "flat").

  • Name
    location
    Type
    object
    Description

    Geographic coordinates of the site (used for solar irradiance and weather data).

    • Name
      lon
      Type
      number
      Required
      required
      Description

      Longitude of the site.

    • Name
      lat
      Type
      number
      Required
      required
      Description

      Latitude of the site.

  • Name
    electricBattery
    Type
    object
    Optional
    optional
    Description

    Battery storage system configuration. If omitted, the optimization will not include battery storage.

    • Name
      capacity_kwh
      Type
      number
      Required
      required
      Description

      Battery storage capacity in kilowatt-hours (kWh). This determines how much energy the battery can store.

      Example: A 10 kWh battery can store enough energy to power a typical home for several hours.

    • Name
      power_rating_kw
      Type
      number
      Required
      required
      Description

      Battery power rating in kilowatts (kW). This determines how quickly the battery can charge or discharge.

      Example: A 5 kW power rating means the battery can deliver up to 5 kW of power at any moment.

    • Name
      total_cost
      Type
      number
      Optional
      optional
      Description

      Total installation cost in euros (€). When provided, this exact cost will be used in financial calculations.

      If omitted, costs are automatically calculated based on capacity using Netherlands market data (2025):

      • ≤5 kWh: €1,100 per kWh
      • ≤10 kWh: €925 per kWh
      • ≤20 kWh: €850 per kWh
      • ≤40 kWh: €600 per kWh
      • 40 kWh: €600 per kWh

      Example: A 10 kWh battery would cost approximately €9,250 if not specified.

    • Name
      min_capacity_kwh
      Type
      number
      Optional
      optional
      Description

      Minimum battery capacity (kWh) for optimization. Use this when you want the optimizer to find the ideal battery size within a range.

      Default: 0 (no minimum constraint)

    • Name
      min_power_rating_kw
      Type
      number
      Optional
      optional
      Description

      Minimum power rating (kW) for optimization.

      Default: 0 (no minimum constraint)

    • Name
      minimum_charge_level
      Type
      number
      Optional
      optional
      Description

      Minimum battery charge level as a percentage (0–100). This protects battery health by preventing deep discharge.

      Default: 10 (10% - battery won't discharge below this level)

      Example: Setting this to 20 means the battery always keeps at least 20% charge reserve.

    • Name
      roundtrip_efficiency
      Type
      number
      Optional
      optional
      Description

      Roundtrip efficiency as a percentage (0–100). This represents the total energy loss when charging and then discharging the battery.

      Default: 92 (92% - 8% energy loss per charge/discharge cycle)

      Example: If you charge 10 kWh into the battery, you'll get 9.2 kWh back out (with 92% efficiency).

    • Name
      discharge_efficiency
      Type
      number
      Optional
      optional
      Description

      Discharge efficiency as a percentage (0–100). Represents inverter losses when converting DC battery power to AC for home use.

      Default: 96 (96% - 4% loss during discharge)

    • Name
      charge_efficiency
      Type
      number
      Optional
      optional
      Description

      Charge efficiency as a percentage (0–100). Represents rectifier losses when converting AC power to DC for battery charging.

      Default: 96 (96% - 4% loss during charging)

  • Name
    yearly_kwh
    Type
    number
    Required
    required
    Description

    Total annual electricity consumption of the site in kilowatt-hours.

  • Name
    load_profile
    Type
    string
    Optional
    optional
    Description

    Load profile to use for the optimization.

    Standard profiles: Choose from "standard" (default), "coupleBothAtWork", "couple1home1work", or "3kidsbothwork".

    Custom profiles: If use_custom_load_profile is set to true, this must be the record_id returned from the Create a custom load profile endpoint.

    See the Load Profiles Guide for detailed information about each standard profile and how to create custom profiles.

    Default: "standard"

  • Name
    use_custom_load_profile
    Type
    boolean
    Optional
    optional
    Description

    Whether to use a custom load profile. When set to true, the load_profile field must contain the record_id of a custom profile created via the Create a custom load profile endpoint. When false or omitted, load_profile should be one of the standard profile names.

    Default: false

  • Name
    new_pv
    Type
    array
    Optional
    optional
    Description

    Solar panel systems to be installed. Each array entry represents a different roof section or orientation.

    • Name
      name
      Type
      string
      Required
      required
      Description

      Identifier for this solar installation (e.g., "south_roof", "garage_east").

    • Name
      panel_power_watts
      Type
      number
      Required
      required
      Description

      Power rating per solar panel in watts-peak (Wp).

      Example: 430 (for a 430W panel)

      Note: Combined with max_panel_count, this determines the total system capacity in kWp used for cost calculations. Formula: (panel_power_watts / 1000) × max_panel_count = kWp

    • Name
      min_panel_count
      Type
      number
      Optional
      optional
      Description

      Minimum number of panels for optimization. Use this to set a lower bound.

      Default: 0 (optimizer can choose zero panels)

    • Name
      max_panel_count
      Type
      number
      Required
      required
      Description

      Maximum number of panels that can fit in this location.

      Example: 12 (if your roof has space for 12 panels)

      Cost Calculation: This value (combined with panel_power_watts) determines the installation cost per kW used in optimization. Larger systems benefit from economies of scale:

      • ≤2 kWp: €1,200/kW
      • ≤4 kWp: €1,100/kW
      • ≤8 kWp: €1,000/kW
      • ≤16 kWp: €900/kW
      • >16 kWp: €800/kW

      Note: Cost calculation only applies when goal is "payback-time". When goal is "self-sufficiency", costs are set to €0 since the optimization focuses purely on energy independence rather than financial returns.

    • Name
      tilt_angle
      Type
      number
      Optional
      optional
      Description

      Panel tilt angle in degrees. 0° = flat/horizontal, 30° = typical sloped roof, 90° = vertical.

      Default: 35 (optimal for most locations in Netherlands)

      Tip: Roof slope typically determines this value.

    • Name
      orientation_angle
      Type
      number
      Optional
      optional
      Description

      Compass direction the panels face (azimuth). 180° = south (optimal), 90° = east, 270° = west, 0°/360° = north.

      Default: 180 (south-facing for maximum generation)

      Tip: South-facing panels generate most energy, but east/west can be valuable for morning/evening consumption.

    • Name
      system_losses
      Type
      number
      Optional
      optional
      Description

      Expected total system losses as a percentage (0-100). Includes wiring losses, shading, dirt/snow, inverter efficiency, and temperature effects.

      Default: 14 (14% total losses - industry standard)

      Range: Typically 10-20% depending on installation quality and shading.

  • Name
    existing_pv
    Type
    array
    Optional
    optional
    Description

    Solar panel systems already installed at your location. Include these so the optimizer accounts for their generation.

    Cost Modeling: Existing PV installations are treated as having zero installation cost (since they're already paid for). The optimizer considers their generation output but doesn't factor them into payback calculations or investment costs.

    • Name
      name
      Type
      string
      Required
      required
      Description

      Identifier for this existing installation (e.g., "main_roof", "shed").

    • Name
      panel_count
      Type
      number
      Required
      required
      Description

      Number of currently installed solar panels.

      Example: 10 (if you have 10 panels installed)

    • Name
      panel_power_watts
      Type
      number
      Required
      required
      Description

      Power rating per installed panel in watts-peak (Wp).

      Example: 400 (for 400W panels)

      Tip: Check your inverter specs or installation documents for this value.

    • Name
      tilt_angle
      Type
      number
      Optional
      optional
      Description

      Current panel tilt angle in degrees. 0° = flat, 30° = typical sloped roof, 90° = vertical.

      Default: 35

    • Name
      orientation_angle
      Type
      number
      Optional
      optional
      Description

      Compass direction your panels face. 180° = south, 90° = east, 270° = west, 0° = north.

      Default: 180 (south-facing)

    • Name
      system_losses
      Type
      number
      Optional
      optional
      Description

      Total system losses as a percentage (0-100). Includes all efficiency losses.

      Default: 14 (14% total losses)

Response Fields

  • Name
    run_uuid
    Type
    string
    Description

    Unique identifier for the created scan job. Use this UUID to poll for results via the GET /v1/scan endpoint. The scan will process asynchronously in the background.

Request

POST
/v1/scan
curl -X POST https://api.enhub.nl/v1/scan \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "goal": "self-sufficiency",
    "tariff": { "type": "flat", "flat_eur_per_kwh": 0.28 },
    "location": { "lon": 40.0, "lat": 40.0 },
    "electricBattery": { 
      "capacity_kwh": 10, 
      "power_rating_kw": 5,
      "minimum_charge_level": 10,
      "roundtrip_efficiency": 92
    },
    "yearly_kwh": 5000,
    "load_profile": "coupleBothAtWork",
    "use_custom_load_profile": false,
    "new_pv": [{ 
      "name": "roof_south", 
      "panel_power_watts": 430, 
      "max_panel_count": 12,
      "tilt_angle": 35, 
      "orientation_angle": 180,
      "system_losses": 14
    }],
    "existing_pv": [{ 
      "name": "garage_east", 
      "panel_count": 8,
      "panel_power_watts": 400, 
      "tilt_angle": 25, 
      "orientation_angle": 90,
      "system_losses": 14
    }]
  }'

Response

200
success
{
  "run_uuid": "123e4567-e89b-12d3-a456-426614174000"
}

Response

400
bad request
{
  "error": "failed to create scan",
  "message": "<REASON OR MESSAGE>"
}   

GET/v1/scan/status

Check scan status

Check the current status and progress of a scan. Use this endpoint to poll for scan completion, or use WebSocket Connection for real-time updates without polling.

Query Parameters

  • Name
    run-uuid
    Type
    string
    Required
    required
    Description

    The unique identifier returned when the scan was created. Use this to check the status of a specific scan.

Response Fields

  • Name
    run_uuid
    Type
    string
    Description

    The unique identifier for the scan.

  • Name
    status
    Type
    string
    Description

    Current scan status. Can be either "calculating" (scan is still processing) or "optimal" (scan completed successfully). When status is "optimal", you can call the /v1/scan endpoint to retrieve the full results.

  • Name
    progression
    Type
    number
    Description

    Completion percentage from 0 to 100. Indicates how much of the optimization has been completed.

Request

GET
/v1/scan/status
curl -X GET 'https://api.enhub.nl/v1/scan/status?run-uuid=123e4567-e89b-12d3-a456-426614174000' \
  -H "Authorization: Bearer {token}"

Response

200
calculating
{
  "run_uuid": "123e4567-e89b-12d3-a456-426614174000",
  "status": "calculating",
  "progression": 45
}

Response

200
completed
{
  "run_uuid": "123e4567-e89b-12d3-a456-426614174000",
  "status": "optimal",
  "progression": 100
}

Response

400
bad request
{
  "error": "scan not found or not accessible",
  "message": "<REASON OR MESSAGE>"
}   

GET/v1/scans

List scans

Retrieve a paginated list of all your scans. This endpoint returns metadata about each scan including status, progress, and load profile information, allowing you to browse and manage your optimization scans.

Query Parameters

  • Name
    page
    Type
    number
    Optional
    optional
    Description

    Page number to retrieve (1-indexed). Use this to navigate through multiple pages of results.

    Default: 1

  • Name
    per_page
    Type
    number
    Optional
    optional
    Description

    Number of scans to return per page. Maximum allowed is 100.

    Default: 20

Response Fields

  • Name
    scans
    Type
    array
    Description

    Array of scan objects. Each scan contains:

    • Name
      run_uuid
      Type
      string
      Description

      Unique identifier for the scan. Use this to retrieve detailed results or check status.

    • Name
      status
      Type
      string
      Description

      Current scan status. Either "calculating" (scan is processing) or "optimal" (scan completed successfully).

    • Name
      progression
      Type
      number
      Description

      Completion percentage from 0 to 100. Shows how much of the optimization has been completed.

    • Name
      has_error
      Type
      boolean
      Description

      Whether an error occurred during scan processing.

    • Name
      created
      Type
      string
      Description

      ISO 8601 timestamp when the scan was created.

    • Name
      load_profile
      Type
      string
      Description

      The load profile used for this scan. Either a standard profile name ("standard", "coupleBothAtWork", "couple1home1work", "3kidsbothwork") or a custom profile ID if use_custom_load_profile is true.

    • Name
      use_custom_load_profile
      Type
      boolean
      Description

      Whether a custom load profile was used for this scan.

  • Name
    pagination
    Type
    object
    Description

    Pagination metadata for navigating through results.

    • Name
      page
      Type
      number
      Description

      Current page number.

    • Name
      per_page
      Type
      number
      Description

      Number of scans per page.

    • Name
      total
      Type
      number
      Description

      Total number of scans available.

    • Name
      total_pages
      Type
      number
      Description

      Total number of pages available.

    • Name
      has_next
      Type
      boolean
      Description

      Whether there is a next page available.

    • Name
      has_prev
      Type
      boolean
      Description

      Whether there is a previous page available.

Request

GET
/v1/scans
# Get first page (default)
curl -X GET 'https://api.enhub.nl/v1/scans' \
  -H "Authorization: Bearer {token}"

# Get specific page with custom page size
curl -X GET 'https://api.enhub.nl/v1/scans?page=2&per_page=10' \
  -H "Authorization: Bearer {token}"

Response

200
success
{
  "scans": [
    {
      "run_uuid": "123e4567-e89b-12d3-a456-426614174000",
      "status": "optimal",
      "progression": 100,
      "has_error": false,
      "created": "2024-10-14T12:00:00Z",
      "load_profile": "coupleBothAtWork",
      "use_custom_load_profile": false
    },
    {
      "run_uuid": "987f6543-c21b-09e8-d765-123456789abc",
      "status": "calculating",
      "progression": 45,
      "has_error": false,
      "created": "2024-10-14T10:30:00Z",
      "load_profile": "abc123xyz789",
      "use_custom_load_profile": true
    },
    {
      "run_uuid": "456d7890-a12b-34c5-d678-901234567def",
      "status": "optimal",
      "progression": 100,
      "has_error": false,
      "created": "2024-10-13T15:20:00Z",
      "load_profile": "standard",
      "use_custom_load_profile": false
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 3,
    "total_pages": 1,
    "has_next": false,
    "has_prev": false
  }
}

Response

200
empty list
{
  "scans": [],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 0,
    "total_pages": 0,
    "has_next": false,
    "has_prev": false
  }
}

Response

401
unauthorized
{
  "error": "Authentication required",
  "message": null
}   

Response

500
server error
{
  "error": "Failed to fetch scans",
  "message": "<REASON OR MESSAGE>"
}   

GET/v1/scan/chart

Get scan chart data

Retrieve time-series energy flow data for visualizing how energy moves through your optimized system over a specific time period. This endpoint provides detailed breakdowns of solar generation, battery storage, grid interaction, and consumption patterns — essential for creating interactive charts and analyzing system behavior.

Query Parameters

  • Name
    run-uuid
    Type
    string
    Required
    required
    Description

    The unique identifier for the completed scan.

  • Name
    startDate
    Type
    string
    Optional
    optional
    Description

    Start date for the chart data period. Accepts multiple formats:

    • RFC3339: 2024-10-14T12:00:00Z
    • Date only: 2024-10-14
    • DateTime without timezone: 2024-10-14T12:00:00

    Default: Current date/time

  • Name
    interval
    Type
    string
    Optional
    optional
    Description

    Time aggregation interval for the data points. Determines the granularity and range of returned data.

    Options:

    • day: 24 hourly data points for a single day
    • week: 7 daily data points for a week
    • month: ~30 daily data points for a month
    • year: 12 monthly data points for a year

    Default: "day"

  • Name
    extended
    Type
    boolean
    Optional
    optional
    Description

    Whether to include extended battery state-of-charge data (full_soc_series). When true, returns granular SOC data for every simulation hour.

    Default: false

Response Fields

  • Name
    site_consumption
    Type
    array
    Description

    Total electricity consumption (load) in kilowatts (kW) for each time interval. Represents the site's energy demand throughout the period.

  • Name
    solar_total_generation
    Type
    array
    Description

    Total solar PV generation in kW for each interval. Sum of all PV energy produced by the system.

  • Name
    solar_direct_usage
    Type
    array
    Description

    Solar energy directly consumed by the load in kW. PV power that immediately meets on-site demand without storage or grid interaction.

  • Name
    solar_exported_to_grid
    Type
    array
    Description

    Solar energy exported to the grid in kW. Excess PV generation sent back to the utility network (often sold at feed-in tariff rates).

  • Name
    solar_stored_in_battery
    Type
    array
    Description

    Solar energy sent to battery storage in kW. PV power used to charge the battery for later use.

  • Name
    solar_curtailment
    Type
    array
    Description

    Solar energy curtailed (wasted) in kW. PV generation that couldn't be used due to system constraints (battery full, grid export limits, etc.).

  • Name
    grid_purchase
    Type
    array
    Description

    Grid electricity consumed by the load in kW. Energy purchased from the utility to meet demand when PV and battery are insufficient.

  • Name
    grid_purchase_baseline
    Type
    array
    Description

    Grid electricity that would be consumed in "Business As Usual" scenario (without the optimized system) in kW. Used for comparison to show savings.

  • Name
    grid_battery_charging
    Type
    array
    Description

    Grid electricity used to charge the battery in kW. Occurs when grid charging is economically advantageous (e.g., cheap off-peak rates with dynamic pricing).

  • Name
    battery_state_of_charge
    Type
    array
    Description

    Battery state of charge (SOC) statistics for each interval. Each element contains:

    • Name
      min
      Type
      number
      Description

      Minimum SOC percentage (0-100) during this interval.

    • Name
      max
      Type
      number
      Description

      Maximum SOC percentage (0-100) during this interval.

    • Name
      average
      Type
      number
      Description

      Average SOC percentage (0-100) during this interval.

    Returns empty objects {min: 0, max: 0, average: 0} if no battery is present in the system.

  • Name
    battery_state_of_charge_hourly
    Type
    array
    Description

    Granular hourly SOC data for the entire simulation period (8760 values for a year). Only included when extended=true. Useful for detailed battery behavior analysis but can be large. Empty array if no battery or extended=false.

  • Name
    tariff_type
    Type
    string
    Description

    Type of electricity tariff used in the optimization: "flat" or "dynamic".

  • Name
    dynamic_tariffs
    Type
    array
    Description

    Electricity tariff rates for each interval (only populated if tariff_type="dynamic"). Each element contains:

    • Name
      min
      Type
      number
      Description

      Minimum tariff rate (€/kWh) during this interval.

    • Name
      max
      Type
      number
      Description

      Maximum tariff rate (€/kWh) during this interval.

    • Name
      average
      Type
      number
      Description

      Average tariff rate (€/kWh) during this interval.

    Empty array or zero values if tariff_type="flat".

  • Name
    labels
    Type
    array
    Description

    Human-readable labels for each data point. Format depends on interval:

    • day: Hour labels like "00:00", "01:00", ..., "23:00" (24 entries)
    • week: Day names or dates (7 entries)
    • month: Date labels (28-31 entries)
    • year: Month names (12 entries)
  • Name
    interval_type
    Type
    string
    Description

    Echo of the requested interval type: "day", "week", "month", or "year".

  • Name
    start_date
    Type
    string
    Description

    ISO 8601 timestamp of the period start date.

  • Name
    end_date
    Type
    string
    Description

    ISO 8601 timestamp of the period end date.

Understanding Energy Flows

The chart data reveals how energy flows through your system:

  1. Solar Production: solar_total_generation shows when and how much your panels generate
  2. Direct Consumption: solar_direct_usage shows solar energy immediately consumed
  3. Battery Charging: solar_stored_in_battery shows when excess solar charges the battery
  4. Grid Export: solar_exported_to_grid shows when you're sending power back to the grid
  5. Grid Import: grid_purchase shows when you're buying from the grid
  6. Battery State: battery_state_of_charge shows how full your battery is over time

Energy Balance Equation:

site_consumption = solar_direct_usage + grid_purchase + (battery discharge)
solar_total_generation = solar_direct_usage + solar_stored_in_battery + solar_exported_to_grid + solar_curtailment

Request

GET
/v1/scan/chart
# Get today's hourly data (default)
curl -X GET 'https://api.enhub.nl/v1/scan/chart?run-uuid=123e4567-e89b-12d3-a456-426614174000' \
  -H "Authorization: Bearer {token}"

# Get specific day with extended battery data
curl -X GET 'https://api.enhub.nl/v1/scan/chart?run-uuid=123e4567-e89b-12d3-a456-426614174000&startDate=2024-10-14&interval=day&extended=true' \
  -H "Authorization: Bearer {token}"

# Get monthly aggregated data
curl -X GET 'https://api.enhub.nl/v1/scan/chart?run-uuid=123e4567-e89b-12d3-a456-426614174000&interval=month&startDate=2024-10-01' \
  -H "Authorization: Bearer {token}"

Response

200
daily data
{
  "site_consumption": [
    0.085, 0.084, 0.050, 0.079, 0.372, 0.414,
    0.560, 0.357, 0.362, 0.429, 0.417, 0.455,
    0.513, 0.398, 0.383, 0.420, 0.265, 0.592,
    1.111, 0.785, 0.553, 0.273, 0.233, 0.179
  ],
  "solar_total_generation": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0.018, 0.121, 0.238, 0.225, 0.580, 0.651,
    0.715, 0.421, 0.292, 0.020, 0.004, 0,
    0, 0, 0, 0
  ],
  "solar_direct_usage": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0.018, 0.121, 0.238, 0.225, 0.513, 0.398,
    0.383, 0.420, 0.265, 0.020, 0.004, 0,
    0, 0, 0, 0
  ],
  "solar_exported_to_grid": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0.067, 0.253, 0.332, 0.001,
    0.027, 0, 0, 0, 0, 0, 0, 0
  ],
  "solar_stored_in_battery": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
  ],
  "solar_curtailment": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
  ],
  "grid_purchase": [
    0.085, 0.084, 0.050, 0.079, 0.372, 0.414,
    0.560, 0.357, 0.344, 0.308, 0.179, 0.230,
    0, 0, 0, 0, 0, 0.573, 1.107, 0.785,
    0.553, 0.273, 0.233, 0.179
  ],
  "grid_purchase_baseline": [
    0.085, 0.084, 0.050, 0.079, 0.372, 0.414,
    0.560, 0.357, 0.362, 0.429, 0.417, 0.455,
    0.513, 0.398, 0.383, 0.420, 0.265, 0.592,
    1.111, 0.785, 0.553, 0.273, 0.233, 0.179
  ],
  "grid_battery_charging": [
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
  ],
  "battery_state_of_charge": [
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0},
    {"min": 0, "max": 0, "average": 0}
  ],
  "battery_state_of_charge_hourly": [],
  "tariff_type": "dynamic",
  "dynamic_tariffs": [
    {"min": 0.18659, "max": 0.18659, "average": 0.18659},
    {"min": 0.19657, "max": 0.19657, "average": 0.19657},
    {"min": 0.19924, "max": 0.19924, "average": 0.19924},
    {"min": 0.19150, "max": 0.19150, "average": 0.19150},
    {"min": 0.19875, "max": 0.19875, "average": 0.19875},
    {"min": 0.22205, "max": 0.22205, "average": 0.22205},
    {"min": 0.25212, "max": 0.25212, "average": 0.25212},
    {"min": 0.23420, "max": 0.23420, "average": 0.23420},
    {"min": 0.20778, "max": 0.20778, "average": 0.20778},
    {"min": 0.18531, "max": 0.18531, "average": 0.18531},
    {"min": 0.15626, "max": 0.15626, "average": 0.15626},
    {"min": 0.11547, "max": 0.11547, "average": 0.11547},
    {"min": 0.11043, "max": 0.11043, "average": 0.11043},
    {"min": 0.11041, "max": 0.11041, "average": 0.11041},
    {"min": 0.11950, "max": 0.11950, "average": 0.11950},
    {"min": 0.16171, "max": 0.16171, "average": 0.16171},
    {"min": 0.20133, "max": 0.20133, "average": 0.20133},
    {"min": 0.22451, "max": 0.22451, "average": 0.22451},
    {"min": 0.24444, "max": 0.24444, "average": 0.24444},
    {"min": 0.22400, "max": 0.22400, "average": 0.22400},
    {"min": 0.20156, "max": 0.20156, "average": 0.20156},
    {"min": 0.19947, "max": 0.19947, "average": 0.19947},
    {"min": 0.18937, "max": 0.18937, "average": 0.18937},
    {"min": 0.18288, "max": 0.18288, "average": 0.18288}
  ],
  "labels": [
    "00:00", "01:00", "02:00", "03:00", "04:00", "05:00",
    "06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
    "12:00", "13:00", "14:00", "15:00", "16:00", "17:00",
    "18:00", "19:00", "20:00", "21:00", "22:00", "23:00"
  ],
  "interval_type": "day",
  "start_date": "2024-10-14T00:00:00Z",
  "end_date": "2024-10-15T00:00:00Z"
}

Response

400
bad request
{
  "error": "Invalid interval. Must be one of: day, week, month, year",
  "message": null
}   

Response

500
server error
{
  "error": "Failed to get chart data",
  "message": null
}   

GET/v1/scan

Get scan result

Retrieve the full report results for a completed scan. The scan must have finished processing before results are available.

Query Parameters

  • Name
    run-uuid
    Type
    string
    Required
    required
    Description

    The unique identifier returned when the scan was created. Use this to fetch the results of a specific scan.

Response Fields

  • Name
    advice
    Type
    boolean
    Description

    Whether personalized advice is available for this scan.

  • Name
    max_years
    Type
    number
    Description

    Maximum analysis timeframe in years (typically 25 years for solar investments).

  • Name
    investment_costs
    Type
    number
    Description

    Total upfront investment cost in euros (€) for the recommended system.

  • Name
    self_sufficiency_pct
    Type
    number
    Description

    Energy self-sufficiency percentage (0-1). Indicates what portion of energy consumption is met by own generation.

  • Name
    payback_years
    Type
    number
    Description

    Payback period in years. Time until cumulative savings equal the initial investment.

  • Name
    yearly_savings
    Type
    number
    Description

    Average annual savings in euros (€) from the energy system.

  • Name
    trees_saved
    Type
    number
    Description

    Equivalent number of trees planted based on CO₂ savings (environmental impact metric).

  • Name
    co2_saved_in_tonnes
    Type
    number
    Description

    Total CO₂ emissions saved in metric tonnes over the analysis period.

  • Name
    npv
    Type
    number
    Description

    Net Present Value (NPV) in euros (€). Total financial value considering time value of money.

  • Name
    current_elec_usage
    Type
    number
    Description

    Current annual electricity usage in kWh before any system changes.

  • Name
    new_elec_usage
    Type
    number
    Description

    Projected annual electricity usage in kWh with the recommended system.

  • Name
    has_solar_panels_currently
    Type
    boolean
    Description

    Whether the site currently has solar panels installed.

  • Name
    has_or_wants_battery_currently
    Type
    boolean
    Description

    Whether the site currently has or wants battery storage.

  • Name
    wants_new_solar_panels
    Type
    boolean
    Description

    Whether new solar panels are being considered in the optimization.

  • Name
    current_solar_panels
    Type
    array
    Description

    Array of currently installed solar panel configurations.

    • Name
      power_in_wp
      Type
      number
      Description

      Power rating per panel in watts-peak (Wp).

    • Name
      amount
      Type
      number
      Description

      Number of panels in this configuration.

    • Name
      tilt
      Type
      number
      Description

      Tilt angle in degrees (0° = horizontal, 90° = vertical).

    • Name
      azimuth
      Type
      number
      Description

      Azimuth angle in degrees (180° = south, 90° = east, 270° = west, 0° = north).

    • Name
      losses
      Type
      number
      Description

      System losses as decimal (e.g., 0.14 = 14% losses).

    • Name
      name
      Type
      string
      Description

      Identifier for this solar panel configuration.

  • Name
    new_solar_panels
    Type
    array
    Description

    Array of newly recommended solar panel configurations (same structure as current_solar_panels).

  • Name
    total_solar_panels
    Type
    array
    Description

    Combined array of all solar panels (existing + new) after optimization (same structure as current_solar_panels).

  • Name
    battery
    Type
    object
    Optional
    optional
    Description

    Battery storage configuration if included in the optimization. null if no battery.

    • Name
      electric_storage_power_in_kw
      Type
      number
      Description

      Optimal battery power capacity in kilowatts (kW).

    • Name
      elecitric_storage_capacity_in_kwh
      Type
      number
      Description

      Optimal battery energy capacity in kilowatt-hours (kWh).

  • Name
    created_at
    Type
    string
    Description

    ISO 8601 timestamp when the scan was created (e.g., "2024-10-14T12:00:00Z").

  • Name
    latitude
    Type
    number
    Description

    Geographic latitude of the site.

  • Name
    longitude
    Type
    number
    Description

    Geographic longitude of the site.

  • Name
    formatted_address
    Type
    string
    Optional
    optional
    Description

    Human-readable address of the site (if available).

  • Name
    goal
    Type
    string
    Description

    Optimization goal used for this scan. One of: self-sufficiency, payback-time, or contract-comparison.

  • Name
    tariff_type
    Type
    string
    Description

    Type of electricity tariff used: flat or dynamic.

  • Name
    has_error
    Type
    boolean
    Description

    Whether an error occurred during scan processing.

  • Name
    user
    Type
    string
    Description

    User ID who created the scan.

  • Name
    user_email
    Type
    string
    Description

    Email address of the user who created the scan.

  • Name
    load_profile
    Type
    string
    Description

    The load profile used for this scan. Either a standard profile name ("standard", "coupleBothAtWork", "couple1home1work", "3kidsbothwork") or a custom profile ID if use_custom_load_profile is true.

  • Name
    use_custom_load_profile
    Type
    boolean
    Description

    Whether a custom load profile was used for this scan. When true, the load_profile field contains a custom profile ID. When false, it contains a standard profile name.

Request

GET
/v1/scan
curl -X GET 'https://api.enhub.nl/v1/scan?run-uuid=123e4567-e89b-12d3-a456-426614174000' \
  -H "Authorization: Bearer {token}"

Response

200
success
{
  "advice": true,
  "max_years": 25,
  "investment_costs": 12500.50,
  "self_sufficiency_pct": 0.78,
  "payback_years": 8.5,
  "yearly_savings": 1470.25,
  "trees_saved": 142,
  "co2_saved_in_tonnes": 32.5,
  "npv": 18750.00,
  "current_elec_usage": 5000,
  "new_elec_usage": 1100,
  "has_solar_panels_currently": false,
  "has_or_wants_battery_currently": true,
  "wants_new_solar_panels": true,
  "current_solar_panels": [],
  "new_solar_panels": [
    {
      "power_in_wp": 430,
      "amount": 8,
      "tilt": 35,
      "azimuth": 180,
      "losses": 0.14,
      "name": "roof_south"
    }
  ],
  "total_solar_panels": [
    {
      "power_in_wp": 430,
      "amount": 8,
      "tilt": 35,
      "azimuth": 180,
      "losses": 0.14,
      "name": "roof_south"
    }
  ],
  "battery": {
    "electric_storage_power_in_kw": 5.0,
    "elecitric_storage_capacity_in_kwh": 10.0
  },
  "created_at": "2024-10-14T12:00:00Z",
  "latitude": 52.1015441,
  "longitude": 5.1779992,
  "formatted_address": "Amsterdam, Netherlands",
  "goal": "self-sufficiency",
  "tariff_type": "flat",
  "has_error": false,
  "user": "user123",
  "user_email": "user@example.com",
  "load_profile": "coupleBothAtWork",
  "use_custom_load_profile": false
}

Response

400
bad request
{
  "error": "scan not found or not accessible",
  "message": "<REASON OR MESSAGE>"
}   

Response

500
not completed
{
  "error": "failed to get job result",
  "message": "Scan is not completed yet"
}   

Response

500
error
{
  "error": "failed to get job result",
  "message": "<REASON OR MESSAGE>"
}   

Was this page helpful?