{"openapi":"3.1.0","info":{"title":"Energy Portugal API","version":"0.1.0","description":"Compare current fixed-price Portuguese electricity offers from versioned ERSE datasets. Supply costs are not presented as complete electricity bills."},"servers":[{"url":"https://energy.diasmorais.com"}],"tags":[{"name":"Comparison","description":"Deterministic fixed-price offer comparison."},{"name":"Offers","description":"Active-dataset offer and supplier exploration."},{"name":"Dataset","description":"ERSE dataset provenance and freshness."}],"paths":{"/compare":{"get":{"tags":["Comparison"],"operationId":"compareElectricityOffersByQuery","summary":"Compare electricity offers using a shareable URL","description":"Read-only browser and language-model-friendly adapter over the same comparison service used by REST and MCP. Time-of-use consumption must be supplied explicitly.","parameters":[{"name":"power_kva","in":"query","required":true,"description":"Contracted BTN power in kVA.","schema":{"type":"number","example":6.9}},{"name":"tariff","in":"query","required":false,"description":"Tariff structure to compare.","schema":{"type":"string","enum":["simple","bi","tri","best"],"default":"simple"}},{"name":"annual_kwh","in":"query","required":false,"description":"Aggregate annual consumption for simple or best.","schema":{"type":"number","exclusiveMinimum":0,"example":5000}},{"name":"kwh","in":"query","required":false,"description":"Observed-period consumption; use with days and simple tariff.","schema":{"type":"number","exclusiveMinimum":0}},{"name":"days","in":"query","required":false,"description":"Observed-period days; annualises kwh or supplied time-of-use period values.","schema":{"type":"integer","minimum":1,"maximum":366}},{"name":"peak_kwh","in":"query","required":false,"description":"Annual peak consumption for bi or tri tariff.","schema":{"type":"number","minimum":0}},{"name":"shoulder_kwh","in":"query","required":false,"description":"Annual shoulder consumption for tri tariff.","schema":{"type":"number","minimum":0}},{"name":"off_peak_kwh","in":"query","required":false,"description":"Annual off-peak consumption for bi or tri tariff.","schema":{"type":"number","minimum":0}},{"name":"customer","in":"query","required":false,"description":"Customer type.","schema":{"type":"string","enum":["domestic","business"],"default":"domestic"}},{"name":"group_by","in":"query","required":false,"description":"Keep the cheapest result per supplier or rank every offer.","schema":{"type":"string","enum":["supplier","offer"],"default":"supplier"}},{"name":"top","in":"query","required":false,"description":"Maximum results to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":5}},{"name":"supply","in":"query","required":false,"description":"ERSE supply type: electricity-only offers, or offers bundled with natural gas.","schema":{"type":"string","enum":["any","electricity","dual"],"default":"any"}}],"responses":{"200":{"description":"Ranked offers with dataset provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareResponse"}}}},"400":{"description":"The comparison input is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"503":{"description":"No active ERSE dataset is available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/electricity/compare":{"get":{"tags":["Comparison"],"operationId":"compareElectricityOffersByRestQuery","summary":"Compare electricity offers using query parameters","description":"GET equivalent for clients that cannot issue POST requests. Supplying days annualises aggregate or time-of-use period consumption without inferring any split.","parameters":[{"name":"power_kva","in":"query","required":true,"description":"Contracted BTN power in kVA.","schema":{"type":"number","example":6.9}},{"name":"tariff","in":"query","required":false,"description":"Tariff structure to compare.","schema":{"type":"string","enum":["simple","bi","tri","best"],"default":"simple"}},{"name":"annual_kwh","in":"query","required":false,"description":"Aggregate annual consumption for simple or best.","schema":{"type":"number","exclusiveMinimum":0,"example":5000}},{"name":"kwh","in":"query","required":false,"description":"Observed-period consumption; use with days and simple tariff.","schema":{"type":"number","exclusiveMinimum":0}},{"name":"days","in":"query","required":false,"description":"Observed-period days; annualises kwh or supplied time-of-use period values.","schema":{"type":"integer","minimum":1,"maximum":366}},{"name":"peak_kwh","in":"query","required":false,"description":"Annual peak consumption for bi or tri tariff.","schema":{"type":"number","minimum":0}},{"name":"shoulder_kwh","in":"query","required":false,"description":"Annual shoulder consumption for tri tariff.","schema":{"type":"number","minimum":0}},{"name":"off_peak_kwh","in":"query","required":false,"description":"Annual off-peak consumption for bi or tri tariff.","schema":{"type":"number","minimum":0}},{"name":"customer","in":"query","required":false,"description":"Customer type.","schema":{"type":"string","enum":["domestic","business"],"default":"domestic"}},{"name":"group_by","in":"query","required":false,"description":"Keep the cheapest result per supplier or rank every offer.","schema":{"type":"string","enum":["supplier","offer"],"default":"supplier"}},{"name":"top","in":"query","required":false,"description":"Maximum results to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":5}},{"name":"supply","in":"query","required":false,"description":"ERSE supply type: electricity-only offers, or offers bundled with natural gas.","schema":{"type":"string","enum":["any","electricity","dual"],"default":"any"}}],"responses":{"200":{"description":"Ranked offers with dataset provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareResponse"}}}},"400":{"description":"The comparison input is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"503":{"description":"No active ERSE dataset is available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Comparison"],"operationId":"compareElectricityOffers","summary":"Compare electricity offers","description":"Ranks currently valid fixed-price offers for one consumption profile and contracted BTN power. REST and MCP use the same pricing service.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareRequest"},"examples":{"simple":{"value":{"annual_kwh":6400,"power_kva":6.9,"tariff":"simple","customer":"domestic","top":5}},"bi":{"value":{"annual_kwh":{"peak":3100,"off_peak":3300},"power_kva":6.9,"tariff":"bi","customer":"domestic","top":5}},"tri":{"value":{"annual_kwh":{"peak":1500,"shoulder":2500,"off_peak":3000},"power_kva":6.9,"tariff":"tri","customer":"domestic","top":5}},"observedPeriod":{"value":{"consumption":{"kwh":529,"days":31},"power_kva":6.9,"tariff":"simple","customer":"domestic","top":5}}}}}},"responses":{"200":{"description":"Ranked offers with dataset provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareResponse"}}}},"400":{"description":"The comparison input is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"503":{"description":"No active ERSE dataset is available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/status":{"get":{"tags":["Dataset"],"operationId":"getDatasetStatus","summary":"Get active dataset status","responses":{"200":{"description":"Dataset freshness and provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}}}}},"/v1/electricity/offers/{id}":{"get":{"tags":["Offers"],"operationId":"getElectricityOffer","summary":"Get one active electricity offer","parameters":[{"name":"id","in":"path","required":true,"description":"ERSE external offer ID or internal numeric offer ID.","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"The normalised offer, prices, conditions, and original ERSE data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferDetails"}}}},"404":{"description":"The offer is not present in the active dataset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/electricity/suppliers":{"get":{"tags":["Offers"],"operationId":"listElectricitySuppliers","summary":"List suppliers in the active dataset","responses":{"200":{"description":"Active suppliers and their offer counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierList"}}}}}}}},"components":{"schemas":{"CompareRequest":{"oneOf":[{"type":"object","properties":{"power_kva":{"type":"number"},"customer":{"default":"domestic","type":"string","enum":["domestic","business"]},"top":{"default":5,"type":"integer","minimum":1,"maximum":50},"group_by":{"default":"supplier","type":"string","enum":["supplier","offer"]},"supply":{"default":"any","type":"string","enum":["any","electricity","dual"]},"tariff":{"type":"string","const":"simple"},"annual_kwh":{"type":"number","exclusiveMinimum":0},"consumption":{"type":"object","properties":{"kwh":{"type":"number","exclusiveMinimum":0},"days":{"type":"integer","minimum":1,"maximum":366}},"required":["kwh","days"],"additionalProperties":false}},"required":["power_kva","customer","top","group_by","supply","tariff"],"additionalProperties":false},{"type":"object","properties":{"power_kva":{"type":"number"},"customer":{"default":"domestic","type":"string","enum":["domestic","business"]},"top":{"default":5,"type":"integer","minimum":1,"maximum":50},"group_by":{"default":"supplier","type":"string","enum":["supplier","offer"]},"supply":{"default":"any","type":"string","enum":["any","electricity","dual"]},"tariff":{"type":"string","const":"bi"},"annual_kwh":{"type":"object","properties":{"peak":{"type":"number","minimum":0},"off_peak":{"type":"number","minimum":0}},"required":["peak","off_peak"],"additionalProperties":false}},"required":["power_kva","customer","top","group_by","supply","tariff","annual_kwh"],"additionalProperties":false},{"type":"object","properties":{"power_kva":{"type":"number"},"customer":{"default":"domestic","type":"string","enum":["domestic","business"]},"top":{"default":5,"type":"integer","minimum":1,"maximum":50},"group_by":{"default":"supplier","type":"string","enum":["supplier","offer"]},"supply":{"default":"any","type":"string","enum":["any","electricity","dual"]},"tariff":{"type":"string","const":"tri"},"annual_kwh":{"type":"object","properties":{"peak":{"type":"number","minimum":0},"shoulder":{"type":"number","minimum":0},"off_peak":{"type":"number","minimum":0}},"required":["peak","shoulder","off_peak"],"additionalProperties":false}},"required":["power_kva","customer","top","group_by","supply","tariff","annual_kwh"],"additionalProperties":false},{"type":"object","properties":{"power_kva":{"type":"number"},"customer":{"default":"domestic","type":"string","enum":["domestic","business"]},"top":{"default":5,"type":"integer","minimum":1,"maximum":50},"group_by":{"default":"supplier","type":"string","enum":["supplier","offer"]},"supply":{"default":"any","type":"string","enum":["any","electricity","dual"]},"tariff":{"type":"string","const":"best"},"annual_kwh":{"anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"object","properties":{"peak":{"type":"number","minimum":0},"off_peak":{"type":"number","minimum":0}},"required":["peak","off_peak"],"additionalProperties":false},{"type":"object","properties":{"peak":{"type":"number","minimum":0},"shoulder":{"type":"number","minimum":0},"off_peak":{"type":"number","minimum":0}},"required":["peak","shoulder","off_peak"],"additionalProperties":false}]}},"required":["power_kva","customer","top","group_by","supply","tariff","annual_kwh"],"additionalProperties":false}]},"DatasetProvenance":{"type":"object","required":["id","source","source_date","imported_at","sha256"],"properties":{"id":{"type":"integer"},"source":{"type":"string","example":"ERSE"},"source_date":{"type":["string","null"],"format":"date"},"imported_at":{"type":"string","format":"date-time"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}}},"StatusDataset":{"allOf":[{"$ref":"#/components/schemas/DatasetProvenance"},{"type":"object","required":["last_checked_at","offer_count"],"properties":{"last_checked_at":{"type":["string","null"],"format":"date-time"},"offer_count":{"type":"integer","minimum":0}}}]},"StatusResponse":{"type":"object","required":["ok","dataset"],"properties":{"ok":{"type":"boolean"},"dataset":{"oneOf":[{"$ref":"#/components/schemas/StatusDataset"},{"type":"null"}]}}},"Supplier":{"type":"object","required":["name","website"],"properties":{"name":{"type":"string"},"website":{"type":["string","null"]}}},"OfferSummary":{"type":"object","required":["id","name","url"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":["string","null"]}}},"CostComponents":{"type":"object","required":["annual_energy_cost_eur","annual_power_cost_eur","mandatory_charges_eur","discounts_eur"],"properties":{"annual_energy_cost_eur":{"type":"number","multipleOf":0.01},"annual_power_cost_eur":{"type":"number","multipleOf":0.01},"mandatory_charges_eur":{"type":"number","multipleOf":0.01},"discounts_eur":{"type":"number","multipleOf":0.01}}},"ComparisonResult":{"type":"object","required":["rank","supplier","offer","tariff","pricing_model","annual_supply_cost_eur","estimated_annual_bill_eur","monthly_average_supply_cost_eur","components","prices","conditions","difference_from_cheapest_eur"],"properties":{"rank":{"type":"integer","minimum":1},"supplier":{"$ref":"#/components/schemas/Supplier"},"offer":{"$ref":"#/components/schemas/OfferSummary"},"supply":{"type":["string","null"],"enum":["electricity","dual",null],"description":"ERSE Fornecimento: electricity only, or bundled with natural gas."},"tariff":{"type":"string","enum":["simple","bi","tri"]},"pricing_model":{"type":"string","enum":["fixed"]},"annual_supply_cost_eur":{"type":"number","multipleOf":0.01,"description":"Energy, contracted power, mandatory offer charges, and quantifiable discounts."},"estimated_annual_bill_eur":{"type":["number","null"],"multipleOf":0.01,"description":"Complete estimated bill when taxes and common regulated charges can be reproduced; null in the MVP."},"monthly_average_supply_cost_eur":{"type":"number","multipleOf":0.01},"components":{"$ref":"#/components/schemas/CostComponents"},"prices":{"type":"object","additionalProperties":{"type":"number"}},"conditions":{"type":"array","items":{"type":"string"}},"difference_from_cheapest_eur":{"type":"number","multipleOf":0.01}}},"CompareResponse":{"type":"object","required":["input","dataset","results"],"properties":{"input":{"type":"object","additionalProperties":true},"dataset":{"$ref":"#/components/schemas/DatasetProvenance"},"results":{"type":"array","items":{"$ref":"#/components/schemas/ComparisonResult"}}}},"OfferDetails":{"type":"object","required":["supplier","offer","prices","conditions","discounts","charges","raw_erse"],"properties":{"supplier":{"type":"object","additionalProperties":true},"offer":{"type":"object","additionalProperties":true},"prices":{"type":"array","items":{"type":"object","additionalProperties":true}},"conditions":{"type":"array","items":{"type":"object","additionalProperties":true}},"discounts":{"type":"array","items":{"type":"object","additionalProperties":true}},"charges":{"type":"array","items":{"type":"object","additionalProperties":true}},"raw_erse":{"type":"object","additionalProperties":true}}},"SupplierList":{"type":"object","required":["suppliers"],"properties":{"suppliers":{"type":"array","items":{"type":"object","required":["id","external_id","name","website","offer_count"],"properties":{"id":{"type":"integer"},"external_id":{"type":["string","null"]},"name":{"type":"string"},"website":{"type":["string","null"]},"offer_count":{"type":"integer","minimum":0}}}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}},"ValidationError":{"allOf":[{"$ref":"#/components/schemas/Error"},{"type":"object","properties":{"issues":{"type":"array","items":{"type":"object","additionalProperties":true}}}}]}}}}