The Challenge

The report is wrong. Find out why.

NEBELGARD Renewables GmbH — a fictional portfolio manager — has published its January 2025 contribution-margin report for 847 wind and solar assets. The numbers don't add up. Reverse-engineer the report, find the deviations, and write the spec that fixes the process.

The scenario

NEBELGARD Renewables GmbH (entirely fictional — no relation to any real company; all data on this site is synthetic) manages a portfolio of 847 renewable assets — 612 wind, 235 solar — on behalf of asset owners across Germany. Every month, a Deckungsbeitrag report (contribution margin) is generated per asset and aggregated to region and portfolio level. It feeds investor reporting, management fee invoicing and P&L tracking.

The January 2025 report has been generated. The numbers are wrong. Exactly three deviations exist between the source data and the published report — no more, no less. Nobody knows where they come from.

The deviations are individually small in a portfolio that turns over roughly €2.3M a month. None is visible from a single data source — each requires cross-referencing at least two. The aggregation chain has about seven steps, and a deviation early in the chain compounds through everything after it. Comparing totals and hunting outliers will find noise; tracing one asset end-to-end and generalising will find the deviations.

Your task

  1. Explore the raw data behind the report through the nine API endpoints below.
  2. Reverse-engineer the aggregation — reconstruct, step by step, how the raw sources become the report.
  3. Identify all three deviations. For each: the source, the EUR impact, and the root cause.
  4. Write a DSF-format spec (template below) that describes the correct aggregation precisely enough that an agent could reproduce it without asking a single question.

The spec is the deliverable. Submissions are evaluated on process reconstruction, API thoroughness, deviation identification, and spec precision — and every submission is reviewed by a human. There is no time limit.

API access

Base URL:

https://poc16264.quadra-energy.com/api/v1

Authenticate every call with your personal API key in the X-API-Key header. You receive the key once, at registration — store it safely; we keep only a hash.

  • All responses share one envelope: data (array) plus meta with page, page_size, total_records, has_next_page, generated_at.
  • Rate limit: 120 requests per minute per API key (240 per minute per IP). Every response carries X-RateLimit-Remaining and X-RateLimit-Reset headers.
  • Data window: January 2025. Date ranges outside it return an empty data array with status 200.
  • Validation errors return 400 naming the parameter; a missing or unknown key returns 401.

Endpoint reference

The key stays in your browser's sessionStorage and is sent only as a request header to this site's API — never in a URL, never to anywhere else. Closing the tab forgets it.

GET /data/feedin

Quarter-hourly feed-in actuals per asset for January 2025 — roughly 2.5 million rows. Note the unit: kWh, while every other source works in MWh.

ParameterRequiredValues / default
date_from yes ISO date YYYY-MM-DD
date_to yes ISO date YYYY-MM-DD
asset_id no single asset, e.g. WND-0042
asset_ids no comma-separated list of asset IDs
quality_filter no all | validated_only, default all
page no integer ≥ 1, default 1
page_size no 1–500, default 100

Rows carry asset_id, timestamp (naive string, no timezone designator — exactly as the source system exported it), energy_kwh, quality_flag (validated | estimated | raw), source_system (SCADA_v3 | SCADA_legacy | manual_entry).

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/feedin?asset_id=WND-0042&date_from=2025-01-07&date_to=2025-01-07"

Sample response (truncated):

{
  "data": [
    { "asset_id": "WND-0042", "timestamp": "2025-01-07T00:00:00",
      "energy_kwh": 412.375, "quality_flag": "validated", "source_system": "SCADA_v3" },
    { "asset_id": "WND-0042", "timestamp": "2025-01-07T00:15:00",
      "energy_kwh": 398.250, "quality_flag": "validated", "source_system": "SCADA_v3" }
  ],
  "meta": { "page": 1, "page_size": 100, "total_records": 96,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/prices

Hourly market prices for January 2025: Day-Ahead clearing price and the volume-weighted intraday average per hour. 1,488 rows in total. id_volume_mwh is the portfolio-level intraday volume that hour, not per asset.

ParameterRequiredValues / default
date_from yes ISO date YYYY-MM-DD
date_to yes ISO date YYYY-MM-DD
product no DA | ID | all, default all

Rows carry date, hour (0–23), product, price_eur_mwh, id_volume_mwh.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/prices?date_from=2025-01-07&date_to=2025-01-07&product=DA"

Sample response (truncated):

{
  "data": [
    { "date": "2025-01-07", "hour": 0, "product": "DA",
      "price_eur_mwh": 71.84, "id_volume_mwh": 142.503 },
    { "date": "2025-01-07", "hour": 0, "product": "ID",
      "price_eur_mwh": 76.02, "id_volume_mwh": 142.503 }
  ],
  "meta": { "page": 1, "page_size": 100, "total_records": 48,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/schedule

The day-ahead schedule per asset and hour — the volume committed to the grid operator the day before. Actual feed-in minus schedule is the intraday delta.

ParameterRequiredValues / default
date_from yes ISO date YYYY-MM-DD
date_to yes ISO date YYYY-MM-DD
asset_id no single asset
page no integer ≥ 1, default 1
page_size no 1–500, default 100

Rows carry asset_id, date, hour (0–23), scheduled_mwh.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/schedule?asset_id=WND-0042&date_from=2025-01-07&date_to=2025-01-07"

Sample response (truncated):

{
  "data": [
    { "asset_id": "WND-0042", "date": "2025-01-07", "hour": 0, "scheduled_mwh": 1.625 },
    { "asset_id": "WND-0042", "date": "2025-01-07", "hour": 1, "scheduled_mwh": 1.580 }
  ],
  "meta": { "page": 1, "page_size": 100, "total_records": 24,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/contracts

Contract master data for all 847 assets: owner, region, capacity, contract window, fee model — plus the amendment history. Read the field list closely; the fee logic lives here.

ParameterRequiredValues / default
asset_id no single asset
technology no wind | solar
region no north | south | east | west
include_amendments no true | false, default true
active_on no ISO date YYYY-MM-DD — only contracts active on that date
page no integer ≥ 1, default 1
page_size no 1–200, default 50

Rows carry asset_id, contract_id, owner_name, technology, region, installed_capacity_kw, commissioning_date, contract_start, contract_end, fee_model (fixed | revenue_share | ppa), fee_fixed_eur_mwh, fee_share_pct, operator_id, scada_system (SCADA_v3 | SCADA_legacy), amendment_id, amendment_effective.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/contracts?asset_id=WND-0042"

Sample response (truncated):

{
  "data": [
    { "asset_id": "WND-0042", "contract_id": "CTR-2019-0042",
      "owner_name": "Windkraft Hügelland GmbH & Co. KG", "technology": "wind",
      "region": "west", "installed_capacity_kw": 3200.0,
      "commissioning_date": "2019-06-14", "contract_start": "2022-01-01",
      "contract_end": "2027-12-31", "fee_model": "fixed", "fee_fixed_eur_mwh": 4.20,
      "fee_share_pct": null, "operator_id": "OP-014", "scada_system": "SCADA_v3",
      "amendment_id": null, "amendment_effective": null }
  ],
  "meta": { "page": 1, "page_size": 50, "total_records": 847,
            "has_next_page": true, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/eeg_premium

The EEG market premium (Marktprämie) per technology and month, from the monthly grid-operator statement — including any retroactive correction.

ParameterRequiredValues / default
month yes YYYY-MM
technology no wind_onshore | solar

Rows carry month, technology, premium_eur_mwh, correction_flag (true if a retroactive correction applies), correction_amount_eur (a portfolio-level total, not per asset).

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/eeg_premium?month=2025-01"

Sample response (truncated):

{
  "data": [
    { "month": "2025-01", "technology": "solar", "premium_eur_mwh": 6.20,
      "correction_flag": false, "correction_amount_eur": 0.00 }
  ],
  "meta": { "page": 1, "page_size": 50, "total_records": 2,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/costs

Monthly cost allocations from the finance team — one row per asset and cost category, with the allocation basis and the pool it was divided from.

ParameterRequiredValues / default
month yes YYYY-MM
asset_id no single asset
cost_category no monitoring | data_fees | insurance | grid_fees
page no integer ≥ 1, default 1
page_size no 1–200, default 50

Rows carry asset_id, cost_category, allocated_amount_eur, allocation_basis (capacity_weighted | flat | per_asset), total_pool_eur, active_assets_in_pool.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/costs?month=2025-01&asset_id=SOL-0007"

Sample response (truncated):

{
  "data": [
    { "asset_id": "SOL-0007", "cost_category": "monitoring",
      "allocated_amount_eur": 12.50, "allocation_basis": "flat",
      "total_pool_eur": 10587.50, "active_assets_in_pool": 847 }
  ],
  "meta": { "page": 1, "page_size": 50, "total_records": 4,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /data/costs/metadata

Metadata accompanying the monthly cost allocation: the allocation date, any explicitly excluded assets, and a free-text note from the finance team.

ParameterRequiredValues / default
month yes YYYY-MM

Returns allocation_date, note (free text), assets_excluded.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/data/costs/metadata?month=2025-01"

Sample response (truncated):

{
  "data": [
    { "allocation_date": "2025-01-31", "note": "...", "assets_excluded": [] }
  ],
  "meta": { "page": 1, "page_size": 50, "total_records": 1,
            "has_next_page": false, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /report/monthly

The published January 2025 Deckungsbeitrag report — the output of the aggregation you are reconstructing. This report contains the deviations. Available at asset, region and portfolio granularity.

ParameterRequiredValues / default
month yes YYYY-MM
granularity yes asset | region | portfolio
region no filters assets when granularity=asset
page no integer ≥ 1, default 1 (used when granularity=asset)
page_size no 1–100, default 25

Asset rows carry asset_id, gross_revenue_eur, eeg_premium_eur, eeg_correction_eur, management_fee_eur, allocated_costs_eur, deckungsbeitrag_eur, db_per_mwh, total_feedin_mwh, availability_pct. The portfolio row adds total_gross_revenue_eur, total_db_eur, db_margin_pct, active_asset_count.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/report/monthly?month=2025-01&granularity=portfolio"

Sample response (truncated):

{
  "data": [
    { "asset_id": "WND-0042", "gross_revenue_eur": 28714.55,
      "eeg_premium_eur": 2406.32, "eeg_correction_eur": -41.87,
      "management_fee_eur": 1203.27, "allocated_costs_eur": 173.20,
      "deckungsbeitrag_eur": 27296.21, "db_per_mwh": 95.27,
      "total_feedin_mwh": 286.512, "availability_pct": 97.12 }
  ],
  "meta": { "page": 1, "page_size": 25, "total_records": 847,
            "has_next_page": true, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1
GET /assets

A slim portfolio list — useful for a first overview before you dive into the contract master data. status=inactive marks assets whose contract ended during January.

ParameterRequiredValues / default
technology no wind | solar
region no north | south | east | west
status no active | inactive | all, default active
page no integer ≥ 1, default 1
page_size no 1–200, default 50

Rows carry asset_id, technology, region, installed_capacity_kw, commissioning_date, status.

curl -H "X-API-Key: <YOUR_API_KEY>" \
  "https://poc16264.quadra-energy.com/api/v1/assets?status=all&page=1&page_size=50"

Sample response (truncated):

{
  "data": [
    { "asset_id": "SOL-0007", "technology": "solar", "region": "south",
      "installed_capacity_kw": 1450.0, "commissioning_date": "2021-03-22",
      "status": "active" }
  ],
  "meta": { "page": 1, "page_size": 50, "total_records": 847,
            "has_next_page": true, "generated_at": "2025-02-03T08:14:22Z" }
}
/api/v1

The spec template

Submit your spec in this format — seven fields, no more, no less. Copy it:

INTENT
What business outcome does this process achieve?
One sentence. Start with a verb.

TRIGGER
When does this process run?
Be precise: day, time, timezone, conditions.

DATA INPUTS
List every API call you would make.
For each: endpoint, all parameters with exact values, and why those values.
Do not write "get the feedin data" — write the exact call.

BUSINESS LOGIC
Describe the aggregation step by step.
Use concrete numbers for thresholds.
Use if/then for conditional logic.
Do not skip steps — if you had to explain a step, it belongs here.

GUARDRAILS
What should the agent NOT do?
When should it stop and ask a human?
What data quality checks must pass before proceeding?

OUTPUT
What is delivered? To whom? In what format?
What does a correct output look like at portfolio level?

SUCCESS CRITERIA
How do we know it worked?
Preferred format: Given [condition] / When [process runs] / Then [expected result]
Give at least three criteria.

Two pieces of advice. First, Data inputs wins or loses the game: name every endpoint, every parameter, every value — and why. Defaults are a choice too; make it consciously. Second, Business logic is where the deviations live or die: a step you gloss over is a step the agent will get wrong.

Submitting

  1. Register to get your access code and personal API key — the key is shown exactly once.
  2. Work the problem with your agent against the API above.
  3. Log in with your access code and open Submit.
  4. Paste your seven-field spec and your agent's output, and tick the deviations you found. Up to 3 submissions; your best one counts.

Submit your solution

Legal notes.

  • The challenge is a voluntary skills demonstration. Participation does not create an employment relationship and is not remunerated.
  • All challenge data is synthetic and fictitious. Assets, operators, prices and measurements are generated for this challenge and do not describe any real installation or company.
  • Your submissions are used solely for evaluation in this hiring process — never as training data and never as production work.
  • QUADRA energy may end the challenge at any time. There is no legal claim to evaluation or feedback („Es besteht kein Rechtsanspruch auf Bewertung oder Feedback“).