Scans

Core solar analysis engine. Creates comprehensive solar potential assessments including panel placement, production forecasts, ROI calculations, and battery recommendations. See Payback Period, Self-Sufficiency, CO₂ Savings, Dynamic vs Fixed Tariffs, and Accuracy.


GET/v1/scans

List scans

Returns lightweight scan list items for table display. Includes all statuses (processing, completed, error). Supports JWT or API key authentication.

Query parameters

  • Name
    page
    Type
    number
    Description
    default: 1

    Page number (1-based)

  • Name
    limit
    Type
    number
    Description
    default: 20

    Items per page

  • Name
    dossierId
    Type
    string
    Description

    Filter scans by dossier ID. Only returns scans linked to this dossier.

Response

Request

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

Response

{
  "items": [
    {
      "id": "cml3ucftb0001yqzvr4jgakw5",
      "status": "completed",
      "createdAt": "2026-02-10T12:00:00Z",
      "goal": "cost-savings",
      "hasError": false,
      "errorMessage": "string",
      "hasSeenReport": false,
      "selfSufficiency": 0.68,
      "returnPeriod": 7.5,
      "co2SavedKg": 1250,
      "isAdjustment": false,
      "adjustmentCount": 0
    }
  ],
  "total": 42,
  "page": 1,
  "limit": 20,
  "totalPages": 3
}

POST/v1/scans

Submit solar scan

Submit a solar scan for optimization.

Required attributes

  • Name
    location
    Type
    LocationDto
    required
  • Name
    yearlyKwh
    Type
    number
    conditionally required
    Description

    Total annual electricity consumption of the property in kilowatt-hours (kWh/year). This is the single most important input — it determines how much energy needs to be supplied. You can find this value on your annual energy bill. Typical Dutch households consume 2,500-5,000 kWh/year depending on size and appliances. All-electric homes (heat pump, EV) can reach 8,000-15,000 kWh/year. See Accuracy for how this value affects result quality, and Payback Period for how savings are computed.

    Flow behavior:
    • inputMethod: 'known'required. The value is used to scale the standard load profile.
    • inputMethod: 'studio'ignored and overridden. The annual kWh is derived from the custom profile and this value is recalculated.
  • Name
    inputMethod
    Type
    string
    required
    Description

    How the consumption data was provided. Determines which payload construction flow is used.

    Accepted values:
    • "known" — you provide yearlyKwh from your energy bill. A standard residential load profile is scaled to this value. If you have existing solar panels (existingPv), you can optionally provide yearlyExportKwh (teruglevering) for more accurate gross load reconstruction.
    • "studio" — you provide a customProfileId referencing a previously created studio profile (via POST /custom-profiles). The load profile and annual consumption are derived entirely from the studio state. Fields yearlyKwh, yearlyExportKwh, and loadProfile are not used and must be omitted. See Accuracy for how input method affects result quality. One of: known, studio.

Optional attributes

  • Name
    yearlyExportKwh
    Type
    number
    conditionally required
    Description

    Annual grid export (teruglevering) in kWh/year, as shown on the energy bill. Used together with solar simulation to reconstruct hourly gross load from net meter data. Must not exceed yearlyKwh. See Accuracy for how this improves gross load reconstruction.

    Flow behavior:
    • inputMethod: 'known' + existingPvused. Distributes annual export across hours using the estimated solar production shape for more accurate gross load reconstruction.
    • inputMethod: 'known' without existingPvrejected (validation error). You cannot have grid export without solar panels.
    • inputMethod: 'studio'rejected (validation error). Export data comes from the studio profile.
  • Name
    loadProfile
    Type
    string
    conditionally required
    Description
    default: standard

    Consumption pattern template to use for the hourly load distribution. The template defines WHEN during the day/year electricity is consumed (the shape), while yearlyKwh defines HOW MUCH is consumed in total. Use "standard" for a typical residential pattern. If omitted, the default is used.

    Flow behavior:
    • inputMethod: 'known'used. Scales this profile to match yearlyKwh.
    • inputMethod: 'studio'rejected (validation error). The studio profile provides its own hourly shape via customProfileId.
  • Name
    customProfileId
    Type
    string
    conditionally required
    Description

    ID of a previously uploaded custom consumption profile to use for this scan. Upload your hourly measurement data via POST /studio-profiles to receive this ID. The profile should contain 8,760 hourly consumption values (one per hour of the year). When provided, this results in a much more accurate analysis based on actual measured data. See Accuracy for rating details.

    Important: If the studio profile was created from a CSV upload that contains export (feed-in / teruglevering) data, the profile must have a solar layer before it can be used here. The system needs solar production simulation data from the solar layer to reconstruct gross consumption from net metered values.

    Flow behavior:
    • inputMethod: 'studio'required. The entire load profile is derived from this profile.
    • inputMethod: 'known'rejected (validation error). Known consumption uses yearlyKwh + loadProfile instead.
  • Name
    existingPv
    Type
    ExistingPvDto[]
  • Name
    newPv
    Type
    NewPvDto[]
  • Name
    tariff
    Type
    TariffDto
  • Name
    electricBattery
    Type
    ElectricBatteryDto
  • Name
    goal
    Type
    string
    Description
    default: cost-savings

    Optimization goal that determines how the system is sized. "self-sufficiency" — maximize the amount of energy produced and consumed on-site, even if it is not the most cost-effective. The optimizer will try to install the maximum solar capacity and include battery storage to minimize grid dependency. "cost-savings" — find the configuration that minimizes total energy costs over the analysis period. The optimizer balances installation costs against long-term savings. If omitted, "cost-savings" is used as the default. See Payback Period for how goal affects cost assumptions, and Self-Sufficiency for the self-sufficiency metric details.

  • Name
    renewableElectricityMinFraction
    Type
    number
    conditionally required
    Description

    Minimum fraction of electricity that must come from on-site renewable sources (0-1). For example, 0.7 means at least 70% of consumption must be met by solar + battery. Only used when goal is "renewable-minimum".

  • Name
    analysisYears
    Type
    number
    Description
    default: 25 years

    Project lifetime / analysis period in years (10–30). Determines how far into the future the financial projections extend. A longer period captures more savings but also more uncertainty. If omitted, the default is used.

  • Name
    copiedFromId
    Type
    string
    Description

    ID of the parent scan to create a free adjustment from. The parent must be a completed scan belonging to the same project. Only fields matching the organization's configured adjustableSteps may differ from the parent. Adjustments are free and do not count toward scan quota or billing. If the referenced scan is itself an adjustment, the server resolves to the root original scan.

  • Name
    includePvMaintenanceCosts
    Type
    boolean
    Description
    default: false

    Include annual PV maintenance costs in the calculation. When true, REopt applies its default O&M cost (~$18/kW/yr). When false or omitted, om_cost_per_kw is set to 0.

  • Name
    includeBatteryMaintenanceCosts
    Type
    boolean
    Description
    default: false

    Include annual battery maintenance costs in the calculation. When true, om_cost_fraction_of_installed_cost is set to 2.5% per year. When false or omitted, om_cost_fraction_of_installed_cost is set to 0.

Response

Request

POST
/v1/scans
curl -X POST https://api.enhub.nl/v1/scans \
  -H "x-api-key: {your-api-key}" \
  -H "Content-Type: application/json" \
  -d '{
  "location": {
    "lat": 52.3676,
    "lon": 4.9041
  },
  "yearlyKwh": 3500,
  "yearlyExportKwh": 800,
  "loadProfile": "standard",
  "inputMethod": "known",
  "customProfileId": "string",
  "existingPv": [
    {
      "name": "existing_pv_1",
      "panelCount": 10,
      "panelPowerWatts": 400,
      "tiltAngle": 35,
      "orientationAngle": 180,
      "systemLosses": 14
    }
  ],
  "newPv": [
    {
      "name": "new_pv_1",
      "minPanelCount": 0,
      "maxPanelCount": 10,
      "panelPowerWatts": 400,
      "tiltAngle": 35,
      "orientationAngle": 180,
      "costPerKwp": 1000,
      "systemLosses": 14
    }
  ],
  "tariff": {
    "type": "flat",
    "flatEurPerKwh": 0.28,
    "feedInEurPerKwh": 0.1,
    "taxesIncluded": true
  },
  "electricBattery": {
    "powerRatingKw": 10,
    "capacityKwh": 10,
    "minCapacityKwh": 5,
    "minPowerRatingKw": 5,
    "minimumChargeLevel": 20,
    "roundtripEfficiency": 92,
    "costPerKwh": 550,
    "brandName": "Tesla",
    "modelName": "Powerwall 3"
  },
  "goal": "self-sufficiency",
  "renewableElectricityMinFraction": 0.5,
  "analysisYears": 25,
  "copiedFromId": "cm5k2l3m4000008l8a1b2c3d4",
  "includePvMaintenanceCosts": true,
  "includeBatteryMaintenanceCosts": true
}'

Response

{
  "id": "cml3ucftb0001yqzvr4jgakw5",
  "status": "processing",
  "errorMessage": "Optimization failed due to invalid input",
  "createdAt": "2026-02-27T12:00:00.000Z"
}

GET/v1/scans/:id/adjustments

Get scan adjustments

Returns the list of adjustment scans created from this scan.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

Response

[
  {
    "id": "cml3ucftb0001yqzvr4jgakw5",
    "status": "completed",
    "createdAt": "2026-02-10T12:00:00Z",
    "goal": "cost-savings",
    "hasError": false,
    "errorMessage": "string",
    "hasSeenReport": false,
    "selfSufficiency": 0.68,
    "returnPeriod": 7.5,
    "co2SavedKg": 1250,
    "isAdjustment": false,
    "adjustmentCount": 0
  }
]

GET/v1/scans/shared/:token

Get shared scan by token

Returns the full report for a publicly shared scan. No authentication required. The scan must have sharing enabled.

Path parameters

  • Name
    token
    Type
    string
    required
    Description

    No description available.

Response

Request

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

Response

{
  "scanId": "string",
  "report": {
    "id": "cml3ucftb0001yqzvr4jgakw5",
    "status": "optimal",
    "createdAt": "2026-02-01T12:00:00Z",
    "latitude": 52.37,
    "longitude": 4.89,
    "goal": "self-sufficiency",
    "tariffType": "flat",
    "hasError": true,
    "overview": {
      "kpi": {
        "yearlyUsageKwh": 3500,
        "selfSufficiency": 0.68,
        "selfSufficiencyBaseline": 0,
        "selfSufficiencyImprovement": 0.18,
        "yearlySavings": 140,
        "returnPeriod": 7.5
      },
      "selfConsumption": {
        "selfConsumption": 62,
        "selfSufficiency": 68,
        "yearlyGridPurchaseKwh": 2100,
        "yearlyFeedInKwh": 620
      },
      "energyFlow": {
        "yearlyUsageKwh": 3500,
        "solarYearlyOutputKwh": 2000,
        "yearlyGridPurchaseKwh": 2100,
        "yearlyFeedInKwh": 620,
        "directlyUsedSolarKwh": 1380,
        "batteryCapacityKwh": 6
      },
      "financialSummary": {
        "firstYearElectricityCost": 800,
        "firstYearSavings": 140,
        "totalOwnershipCost": 15000,
        "totalProjectSavings": 2500
      },
      "lifecycleCostBreakdown": {
        "energyBill": 12000,
        "batteryInvestment": 3600,
        "replacementCost": 1200,
        "solarMaintenanceCost": 500,
        "batteryMaintenanceCost": 660,
        "feedInRevenue": -800,
        "totalCost": 15000
      }
    },
    "solar": {
      "existingSystems": [
        {
          "name": "...",
          "type": "...",
          "roofDirection": "...",
          "installedCapacityKwp": "...",
          "panelCount": "...",
          "panelPowerRatedWatts": "...",
          "tiltDeg": "...",
          "azimuthDeg": "...",
          "losses": "...",
          "lifetimeYears": "...",
          "yearlyOutputKwh": "...",
          "capacityFactor": "...",
          "specificYieldKwhPerKwp": "...",
          "co2SavedKg": "..."
        }
      ],
      "newSystems": [
        {
          "name": "...",
          "type": "...",
          "roofDirection": "...",
          "installedCapacityKwp": "...",
          "panelCount": "...",
          "panelPowerRatedWatts": "...",
          "tiltDeg": "...",
          "azimuthDeg": "...",
          "losses": "...",
          "lifetimeYears": "...",
          "yearlyOutputKwh": "...",
          "capacityFactor": "...",
          "specificYieldKwhPerKwp": "...",
          "co2SavedKg": "..."
        }
      ],
      "totalCapacityKwp": 4.8,
      "totalYearlyOutputKwh": 4000,
      "peakOutputKw": 3.2,
      "directConsumption": 62,
      "toGrid": 15,
      "hasSolarPanelsCurrently": true,
      "wantsNewSolarPanels": true
    },
    "battery": {
      "specs": {
        "powerKw": 3,
        "capacityKwh": 6,
        "roundtripEfficiency": 89.9,
        "minChargeLevel": 20,
        "brandName": "Tesla",
        "modelName": "Powerwall 3"
      },
      "performance": {
        "annualSavings": 0,
        "cyclesPerYear": 210,
        "stateOfHealth": 0,
        "gridChargingEnabled": true
      },
      "costs": {
        "purchaseCost": 3600,
        "replacementCost": 0,
        "systemReturnPeriod": 25.7
      },
      "isFeasible": true,
      "wasRequested": true
    },
    "electricityGrid": {
      "annualEnergySuppliedKwh": 1800,
      "annualEnergySuppliedKwhBau": 2600,
      "peakGridDemandKw": 4.8,
      "peakGridDemandKwBau": 5.6
    },
    "financial": {
      "isPositiveOutcome": true,
      "netPresentValue": 2500,
      "investment": {
        "batteryPurchaseCost": 3600,
        "replacementCostNetPresentValue": 1200,
        "solarMaintenanceCost": 500,
        "batteryMaintenanceCost": 660,
        "totalInvestment": 5000,
        "totalInvestmentAfterIncentives": 4500
      },
      "yearOne": {
        "energyBill": 800,
        "feedInRevenue": 150,
        "maintenanceCosts": 50,
        "savingsVsBaseline": 140
      },
      "lifecycle": {
        "energyBill": 12000,
        "feedInRevenue": 800,
        "totalCost": 15000,
        "savingsVsBaseline": 2500
      },
      "parameters": {
        "evaluationPeriod": 25,
        "discountRate": 5,
        "baselineFirstYearCost": 1200,
        "baselineTotalCost": 20000
      },
      "costComparison": {
        "firstYearBaseline": 1200,
        "firstYearOptimized": 800,
        "projectedBaseline": 20000,
        "projectedOptimized": 15000
      },
      "cashflowSummary": {
        "breakEvenYear": 8,
        "endBalance": 5000,
        "avgAnnualReturn": 8.5
      }
    },
    "sustainability": {
      "energyBalance": {
        "totalConsumptionKwh": 3500,
        "solarProductionKwh": 2000,
        "gridPurchaseKwh": 2100,
        "gridFeedInKwh": 620
      },
      "co2Emissions": {
        "gridCarbonIntensity": 0.4,
        "co2SavedTotalKg": 330,
        "co2FromGridImportKg": 840,
        "co2AvoidedByExportKg": 0
      },
      "selfSufficiency": {
        "renewableShare": 68,
        "selfConsumption": 62,
        "directlyUsedRenewableKwh": 1380,
        "netGridDependencyKwh": 1480
      },
      "equivalents": {
        "treesEquivalent": 15,
        "carKmAvoided": 2750,
        "flightsAvoided": 1.3,
        "projectedCo2Savings": 8.25
      },
      "energyMix": {
        "ownGenerationKwh": 2000,
        "gridPurchaseKwh": 2100,
        "renewableShare": 68
      }
    },
    "isShared": true,
    "shareToken": "string"
  },
  "chartData": {
    "consumption": [
      0
    ],
    "solarUsedOnsite": [
      0
    ],
    "solarExported": [
      0
    ],
    "solarStored": [
      0
    ],
    "solarWasted": [
      0
    ],
    "solarProduction": [
      0
    ],
    "gridUsedOnsite": [
      0
    ],
    "gridStored": [
      0
    ],
    "baselineGridConsumption": [
      0
    ],
    "batteryUsedOnsite": [
      0
    ],
    "batteryLevel": [
      0
    ],
    "batteryLevelStats": [
      {
        "min": 20,
        "max": 95,
        "average": 65
      }
    ],
    "tariffType": "flat",
    "tariffRates": [
      {
        "min": 20,
        "max": 95,
        "average": 65
      }
    ],
    "labels": [
      "string"
    ],
    "intervalType": "day",
    "startDate": "2026-01-15T00:00:00.000Z",
    "endDate": "2026-01-16T00:00:00.000Z",
    "monthlyEnergyCosts": [
      0
    ],
    "monthlyDemandCosts": [
      0
    ],
    "monthlyFixedCosts": [
      0
    ],
    "yearlyElectricityCost": 800,
    "yearlyCashflows": [
      0
    ],
    "cumulativeCashflows": [
      0
    ],
    "monthlyCo2SavingsKg": [
      0
    ]
  },
  "brandingLogo": "string",
  "brandingDisplayName": "string",
  "brandingEnabled": true
}

GET/v1/scans/:id/branding

Get organization branding for a scan

Returns the branding logo URL and display name for the organization that owns this scan.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

GET/v1/scans/:id

Get scan by ID

Returns ScanDto for pending/error scans, FullReportDto for completed (optimal) scans. Supports JWT or API key authentication. Anonymous: 3 requests/min per IP.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

Response

{
  "id": "cml3ucftb0001yqzvr4jgakw5",
  "status": "optimal",
  "createdAt": "2026-02-01T12:00:00Z",
  "latitude": 52.37,
  "longitude": 4.89,
  "goal": "self-sufficiency",
  "tariffType": "flat",
  "hasError": true,
  "overview": {
    "kpi": {
      "yearlyUsageKwh": 3500,
      "selfSufficiency": 0.68,
      "selfSufficiencyBaseline": 0,
      "selfSufficiencyImprovement": 0.18,
      "yearlySavings": 140,
      "returnPeriod": 7.5
    },
    "selfConsumption": {
      "selfConsumption": 62,
      "selfSufficiency": 68,
      "yearlyGridPurchaseKwh": 2100,
      "yearlyFeedInKwh": 620
    },
    "energyFlow": {
      "yearlyUsageKwh": 3500,
      "solarYearlyOutputKwh": 2000,
      "yearlyGridPurchaseKwh": 2100,
      "yearlyFeedInKwh": 620,
      "directlyUsedSolarKwh": 1380,
      "batteryCapacityKwh": 6
    },
    "financialSummary": {
      "firstYearElectricityCost": 800,
      "firstYearSavings": 140,
      "totalOwnershipCost": 15000,
      "totalProjectSavings": 2500
    },
    "lifecycleCostBreakdown": {
      "energyBill": 12000,
      "batteryInvestment": 3600,
      "replacementCost": 1200,
      "solarMaintenanceCost": 500,
      "batteryMaintenanceCost": 660,
      "feedInRevenue": -800,
      "totalCost": 15000
    }
  },
  "solar": {
    "existingSystems": [
      {
        "name": "roof_south_1",
        "type": "existing",
        "roofDirection": "south",
        "installedCapacityKwp": 2.4,
        "panelCount": 6,
        "panelPowerRatedWatts": 400,
        "tiltDeg": 35,
        "azimuthDeg": 180,
        "losses": 0.14,
        "lifetimeYears": 25,
        "yearlyOutputKwh": 2000,
        "capacityFactor": 9.5,
        "specificYieldKwhPerKwp": 833,
        "co2SavedKg": 150
      }
    ],
    "newSystems": [
      {
        "name": "roof_south_1",
        "type": "existing",
        "roofDirection": "south",
        "installedCapacityKwp": 2.4,
        "panelCount": 6,
        "panelPowerRatedWatts": 400,
        "tiltDeg": 35,
        "azimuthDeg": 180,
        "losses": 0.14,
        "lifetimeYears": 25,
        "yearlyOutputKwh": 2000,
        "capacityFactor": 9.5,
        "specificYieldKwhPerKwp": 833,
        "co2SavedKg": 150
      }
    ],
    "totalCapacityKwp": 4.8,
    "totalYearlyOutputKwh": 4000,
    "peakOutputKw": 3.2,
    "directConsumption": 62,
    "toGrid": 15,
    "hasSolarPanelsCurrently": true,
    "wantsNewSolarPanels": true
  },
  "battery": {
    "specs": {
      "powerKw": 3,
      "capacityKwh": 6,
      "roundtripEfficiency": 89.9,
      "minChargeLevel": 20,
      "brandName": "Tesla",
      "modelName": "Powerwall 3"
    },
    "performance": {
      "annualSavings": 0,
      "cyclesPerYear": 210,
      "stateOfHealth": 0,
      "gridChargingEnabled": true
    },
    "costs": {
      "purchaseCost": 3600,
      "replacementCost": 0,
      "systemReturnPeriod": 25.7
    },
    "isFeasible": true,
    "wasRequested": true
  },
  "electricityGrid": {
    "annualEnergySuppliedKwh": 1800,
    "annualEnergySuppliedKwhBau": 2600,
    "peakGridDemandKw": 4.8,
    "peakGridDemandKwBau": 5.6
  },
  "financial": {
    "isPositiveOutcome": true,
    "netPresentValue": 2500,
    "investment": {
      "batteryPurchaseCost": 3600,
      "replacementCostNetPresentValue": 1200,
      "solarMaintenanceCost": 500,
      "batteryMaintenanceCost": 660,
      "totalInvestment": 5000,
      "totalInvestmentAfterIncentives": 4500
    },
    "yearOne": {
      "energyBill": 800,
      "feedInRevenue": 150,
      "maintenanceCosts": 50,
      "savingsVsBaseline": 140
    },
    "lifecycle": {
      "energyBill": 12000,
      "feedInRevenue": 800,
      "totalCost": 15000,
      "savingsVsBaseline": 2500
    },
    "parameters": {
      "evaluationPeriod": 25,
      "discountRate": 5,
      "baselineFirstYearCost": 1200,
      "baselineTotalCost": 20000
    },
    "costComparison": {
      "firstYearBaseline": 1200,
      "firstYearOptimized": 800,
      "projectedBaseline": 20000,
      "projectedOptimized": 15000
    },
    "cashflowSummary": {
      "breakEvenYear": 8,
      "endBalance": 5000,
      "avgAnnualReturn": 8.5
    }
  },
  "sustainability": {
    "energyBalance": {
      "totalConsumptionKwh": 3500,
      "solarProductionKwh": 2000,
      "gridPurchaseKwh": 2100,
      "gridFeedInKwh": 620
    },
    "co2Emissions": {
      "gridCarbonIntensity": 0.4,
      "co2SavedTotalKg": 330,
      "co2FromGridImportKg": 840,
      "co2AvoidedByExportKg": 0
    },
    "selfSufficiency": {
      "renewableShare": 68,
      "selfConsumption": 62,
      "directlyUsedRenewableKwh": 1380,
      "netGridDependencyKwh": 1480
    },
    "equivalents": {
      "treesEquivalent": 15,
      "carKmAvoided": 2750,
      "flightsAvoided": 1.3,
      "projectedCo2Savings": 8.25
    },
    "energyMix": {
      "ownGenerationKwh": 2000,
      "gridPurchaseKwh": 2100,
      "renewableShare": 68
    }
  },
  "isShared": true,
  "shareToken": "string"
}

GET/v1/scans/:id/status

Get scan status

Returns lightweight status info for polling. Use this to check scan progression. The recommended way to receive scan status updates is via Webhooks.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

Response

{
  "id": "cml3ucftb0001yqzvr4jgakw5",
  "status": "processing",
  "errorMessage": "Optimization failed due to invalid input",
  "createdAt": "2026-02-27T12:00:00.000Z"
}

GET/v1/scans/:id/breakdown

Get breakdown data for a scan

Returns time-series data for visualization. Supports day/week/month/year intervals. Use the fields parameter to filter which properties are included in the response. Supports JWT or API key authentication.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Query parameters

  • Name
    startDate
    Type
    string
    Description

    Start date (ISO 8601 format)

  • Name
    interval
    Type
    string
    Description

    Aggregation interval (default: day) One of: day, week, month, year.

  • Name
    extended
    Type
    boolean
    Description

    Include full hourly SOC data

  • Name
    fields
    Type
    string
    Description

    Comma-separated list of fields to include in response (e.g., "consumption,solarProduction,batteryLevel"). Available fields: consumption, solarUsedOnsite, solarExported, solarStored, solarWasted, solarProduction, gridUsedOnsite, gridStored, baselineGridConsumption, batteryUsedOnsite, batteryLevel, batteryLevelStats, tariffType, tariffRates, labels, intervalType, startDate, endDate, monthlyEnergyCosts, monthlyDemandCosts, monthlyFixedCosts, yearlyElectricityCost, yearlyCashflows, cumulativeCashflows, monthlyCo2SavingsKg. If omitted, all fields are returned.

Response

Request

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

Response

{
  "consumption": [
    0
  ],
  "solarUsedOnsite": [
    0
  ],
  "solarExported": [
    0
  ],
  "solarStored": [
    0
  ],
  "solarWasted": [
    0
  ],
  "solarProduction": [
    0
  ],
  "gridUsedOnsite": [
    0
  ],
  "gridStored": [
    0
  ],
  "baselineGridConsumption": [
    0
  ],
  "batteryUsedOnsite": [
    0
  ],
  "batteryLevel": [
    0
  ],
  "batteryLevelStats": [
    {
      "min": 20,
      "max": 95,
      "average": 65
    }
  ],
  "tariffType": "flat",
  "tariffRates": [
    {
      "min": 20,
      "max": 95,
      "average": 65
    }
  ],
  "labels": [
    "string"
  ],
  "intervalType": "day",
  "startDate": "2026-01-15T00:00:00.000Z",
  "endDate": "2026-01-16T00:00:00.000Z",
  "monthlyEnergyCosts": [
    0
  ],
  "monthlyDemandCosts": [
    0
  ],
  "monthlyFixedCosts": [
    0
  ],
  "yearlyElectricityCost": 800,
  "yearlyCashflows": [
    0
  ],
  "cumulativeCashflows": [
    0
  ],
  "monthlyCo2SavingsKg": [
    0
  ]
}

POST/v1/scans/:id/share

Enable sharing for a scan

Generates a public share token for the scan. The scan must be completed. Requires paid organization.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

POST
/v1/scans/:id/share
curl -X POST https://api.enhub.nl/v1/scans/{id}/share \
  -H "x-api-key: {your-api-key}"

Response

{
  "isShared": true,
  "shareToken": "string"
}

DELETE/v1/scans/:id

Delete scan

Endpoint for DELETE /v1/scans/{id}.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

DELETE/v1/scans/:id/share

Disable sharing for a scan

Revokes the public share token for the scan. The scan will no longer be accessible via the share link.

Path parameters

  • Name
    id
    Type
    string
    required
    Description

    No description available.

Response

Request

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

Response

{
  "isShared": true,
  "shareToken": "string"
}

Was this page helpful?