{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Jualink API","version":"1.0.0","description":"REST API for customers' apps, installers' and financing partners' systems. JSON in and out; successful responses are wrapped as { data, meta? } and errors as { error: { code, message, fields? } }. Human-readable guide: /developers."},"servers":[{"url":"https://jualink.com/api/v1"}],"tags":[{"name":"Platform","description":"Health, identity and reference data."},{"name":"Sizing","description":"Stateless solar estimates from the same engine as the website."},{"name":"Assessments","description":"Saved energy assessments for signed-in customers."},{"name":"Catalogue","description":"Verified products and installers. Public."},{"name":"Customer","description":"Quote requests, projects, payments, warranties, maintenance and notifications for a signed-in customer."},{"name":"Installer","description":"Leads, proposals and project updates for installer companies."},{"name":"Financing","description":"Applications sent to a financing partner, and the partner's decisions."},{"name":"Monitoring","description":"Monitoring devices and their readings."},{"name":"Staff","description":"Operations endpoints for platform administrators."}],"paths":{"/health":{"get":{"operationId":"health","summary":"Service health","description":"Checks the API and its database. Returns 503 when the database is unavailable.","tags":["Platform"],"security":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"database":{"type":"string","enum":["ok","unavailable"]},"time":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"apiVersion":{"type":"string"},"sizingEngine":{"type":"string"}},"required":["status","database","time","apiVersion","sizingEngine"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/openapi.json":{"get":{"operationId":"openapi","summary":"OpenAPI 3.1 document","description":"This API described as OpenAPI 3.1 (JSON Schema 2020-12). The document itself is returned, not wrapped in `data`.","tags":["Platform"],"security":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/me":{"get":{"operationId":"me","summary":"Who am I","description":"The user (or API key) the request is authenticated as. Any valid API key may call it.","tags":["Platform"],"security":[{"session":[]},{"apiKey":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"}},"required":["id","name","email","role"],"additionalProperties":false},"organization":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},{"type":"null"}]},"via":{"type":"string","enum":["session","api_key"]},"apiKey":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["id","name","prefix","scopes","expiresAt"],"additionalProperties":false},{"type":"null"}]}},"required":["user","organization","via","apiKey"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/countries":{"get":{"operationId":"countries","summary":"Active countries and regions","description":"Countries where the service is live or piloting, with region codes and sun-hour assumptions.","tags":["Platform"],"security":[],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"},"locale":{"type":"string"},"languages":{"type":"array","items":{"type":"string"}},"phonePrefix":{"type":"string"},"launchStatus":{"type":"string","enum":["ACTIVE","PILOT","PLANNED"]},"regions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"peakSunHours":{"type":"number"},"worstMonthSunHours":{"type":"number"}},"required":["id","code","name","peakSunHours","worstMonthSunHours"],"additionalProperties":false}}},"required":["id","code","name","currencyCode","locale","languages","phonePrefix","launchStatus","regions"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appliances":{"get":{"operationId":"appliances","summary":"Appliance catalogue","description":"Typical wattages and daily hours. With propertyType, appliances relevant to it come first.","tags":["Platform"],"security":[],"parameters":[{"name":"propertyType","in":"query","required":false,"schema":{"type":"string","enum":["HOME","SHOP","OFFICE","SCHOOL","CHURCH","MOSQUE","CLINIC","FARM","RESTAURANT","HOTEL","FACTORY","APARTMENT_BUILDING","OTHER"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"key":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"defaultWatts":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"defaultHoursDay":{"type":"number"},"defaultHoursNight":{"type":"number"},"isMotorLoad":{"type":"boolean"},"isCriticalDefault":{"type":"boolean"},"isThreePhase":{"type":"boolean"},"helpText":{"type":["string","null"]},"propertyTypes":{"type":"array","items":{"type":"string"}}},"required":["id","key","name","category","defaultWatts","surgeFactor","dutyCycle","defaultHoursDay","defaultHoursNight","isMotorLoad","isCriticalDefault","isThreePhase","helpText","propertyTypes"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sizing/estimate":{"post":{"operationId":"sizingEstimate","summary":"Estimate a solar system","description":"Runs the sizing engine with the country's configured prices and the region's sun hours. Nothing is stored. Mix catalogue items ({ key, quantity }) and custom ones ({ name, watts, quantity, hoursDay, hoursNight }).","tags":["Sizing"],"security":[],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"countryCode":{"type":"string","minLength":2,"maxLength":2,"description":"ISO code of an active country, e.g. NG"},"regionCode":{"type":"string","minLength":1,"maxLength":10,"description":"Region code from GET /countries, e.g. LA for Lagos"},"propertyType":{"type":"string","enum":["HOME","SHOP","OFFICE","SCHOOL","CHURCH","MOSQUE","CLINIC","FARM","RESTAURANT","HOTEL","FACTORY","APARTMENT_BUILDING","OTHER"]},"appliances":{"minItems":1,"maxItems":80,"type":"array","items":{"anyOf":[{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":60,"description":"Appliance key from GET /appliances"},"quantity":{"type":"integer","minimum":1,"maximum":500},"hoursDay":{"description":"Hours used 06:00–18:00; defaults to the catalogue value","type":"number","minimum":0,"maximum":12},"hoursNight":{"description":"Hours used 18:00–06:00; defaults to the catalogue value","type":"number","minimum":0,"maximum":12},"isCritical":{"description":"Keep running in the Essential option; defaults to the catalogue value","type":"boolean"}},"required":["key","quantity"],"description":"a catalogue appliance"},{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"watts":{"type":"integer","minimum":1,"maximum":100000,"description":"Running watts per unit"},"quantity":{"type":"integer","minimum":1,"maximum":500},"hoursDay":{"type":"number","minimum":0,"maximum":12},"hoursNight":{"type":"number","minimum":0,"maximum":12},"surgeFactor":{"default":1,"type":"number","minimum":1,"maximum":8},"dutyCycle":{"default":1,"type":"number","minimum":0.05,"maximum":1},"isCritical":{"default":false,"type":"boolean"},"isMotorLoad":{"default":false,"type":"boolean"},"isThreePhase":{"default":false,"type":"boolean"}},"required":["name","watts","quantity","hoursDay","hoursNight"],"description":"or an appliance of your own"}]}},"backupHours":{"default":12,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"batteryPreference":{"default":"NO_PREFERENCE","type":"string","enum":["NO_PREFERENCE","LITHIUM_LFP","LEAD_ACID"]},"hasThreePhaseSupply":{"default":false,"type":"boolean"}},"required":["countryCode","regionCode","propertyType","appliances"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"engineVersion":{"type":"string"},"load":{"type":"object","properties":{"applianceCount":{"type":"number"},"all":{"type":"object","properties":{"connectedLoadW":{"type":"number"},"peakLoadW":{"type":"number"},"surgeLoadW":{"type":"number"},"dailyEnergyWh":{"type":"number"},"dayEnergyWh":{"type":"number"},"nightEnergyWh":{"type":"number"},"averageDayLoadW":{"type":"number"},"averageNightLoadW":{"type":"number"},"largestMotorLoad":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"watts":{"type":"number"},"surgeFactor":{"type":"number"}},"required":["name","watts","surgeFactor"],"additionalProperties":false},{"type":"null"}]}},"required":["connectedLoadW","peakLoadW","surgeLoadW","dailyEnergyWh","dayEnergyWh","nightEnergyWh","averageDayLoadW","averageNightLoadW","largestMotorLoad"],"additionalProperties":false},"critical":{"type":"object","properties":{"connectedLoadW":{"type":"number"},"peakLoadW":{"type":"number"},"surgeLoadW":{"type":"number"},"dailyEnergyWh":{"type":"number"},"dayEnergyWh":{"type":"number"},"nightEnergyWh":{"type":"number"},"averageDayLoadW":{"type":"number"},"averageNightLoadW":{"type":"number"},"largestMotorLoad":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"watts":{"type":"number"},"surgeFactor":{"type":"number"}},"required":["name","watts","surgeFactor"],"additionalProperties":false},{"type":"null"}]}},"required":["connectedLoadW","peakLoadW","surgeLoadW","dailyEnergyWh","dayEnergyWh","nightEnergyWh","averageDayLoadW","averageNightLoadW","largestMotorLoad"],"additionalProperties":false},"hasThreePhaseLoads":{"type":"boolean"},"hasMedicalLoads":{"type":"boolean"},"lines":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"connectedW":{"type":"number"},"dailyWh":{"type":"number"},"dayWh":{"type":"number"},"nightWh":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isOccasional":{"type":"boolean"}},"required":["name","quantity","watts","connectedW","dailyWh","dayWh","nightWh","isCritical","isMotorLoad","isOccasional"],"additionalProperties":false}}},"required":["applianceCount","all","critical","hasThreePhaseLoads","hasMedicalLoads","lines"],"additionalProperties":false},"tiers":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"title":{"type":"string"},"summary":{"type":"string"},"coveredLoads":{"type":"string","enum":["critical","all"]},"coveredLoadNames":{"type":"array","items":{"type":"string"}},"dailyDemandKwh":{"type":"number"},"panelWatts":{"type":"number"},"panelCount":{"type":"number"},"panelArrayKw":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryModuleKwh":{"type":"number"},"batteryModules":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"rainySeasonCoveragePct":{"type":"number"},"autonomyHours":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"cost":{"type":"object","properties":{"currency":{"type":"string"},"equipment":{"type":"number"},"balanceOfSystem":{"type":"number"},"installation":{"type":"number"},"tax":{"type":"number"},"total":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","equipment","balanceOfSystem","installation","tax","total","min","max"],"additionalProperties":false},"monthlyPayment":{"anyOf":[{"type":"object","properties":{"amount":{"type":"number"},"deposit":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"},"label":{"type":"string"}},"required":["amount","deposit","termMonths","annualRatePct","label"],"additionalProperties":false},{"type":"null"}]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}}},"required":["tier","title","summary","coveredLoads","coveredLoadNames","dailyDemandKwh","panelWatts","panelCount","panelArrayKw","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryModuleKwh","batteryModules","batteryNominalKwh","batteryUsableKwh","dailyProductionKwh","worstMonthProductionKwh","rainySeasonCoveragePct","autonomyHours","runtimeHoursLow","runtimeHoursHigh","cost","monthlyPayment","requiresProfessionalAssessment","warnings"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"requiresProfessionalAssessment":{"type":"boolean"},"disclaimer":{"type":"string"}},"required":["engineVersion","load","tiers","assumptions","warnings","requiresProfessionalAssessment","disclaimer"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments":{"post":{"operationId":"createAssessment","summary":"Start an assessment","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"countryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"regionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"city":{"type":"string","minLength":2,"maxLength":80},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"propertyType":{"type":"string","enum":["HOME","SHOP","OFFICE","SCHOOL","CHURCH","MOSQUE","CLINIC","FARM","RESTAURANT","HOTEL","FACTORY","APARTMENT_BUILDING","OTHER"]},"bedrooms":{"type":"integer","minimum":0,"maximum":50},"businessName":{"type":"string","maxLength":120}},"required":["countryId","regionId","city","propertyType"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}":{"get":{"operationId":"getAssessment","summary":"Get an assessment","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER","ADMIN","SUPER_ADMIN"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}/appliances":{"put":{"operationId":"saveAppliances","summary":"Replace the appliance list","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appliances":{"minItems":1,"maxItems":80,"type":"array","items":{"type":"object","properties":{"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string","minLength":1,"maxLength":80},"quantity":{"type":"integer","minimum":1,"maximum":500},"watts":{"type":"integer","minimum":1,"maximum":100000},"hoursDay":{"type":"number","minimum":0,"maximum":12},"hoursNight":{"type":"number","minimum":0,"maximum":12},"surgeFactor":{"default":1,"type":"number","minimum":1,"maximum":8},"dutyCycle":{"default":1,"type":"number","minimum":0.05,"maximum":1},"isCritical":{"default":false,"type":"boolean"},"isMotorLoad":{"default":false,"type":"boolean"},"isThreePhase":{"default":false,"type":"boolean"}},"required":["name","quantity","watts","hoursDay","hoursNight"]}}},"required":["appliances"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}/usage":{"put":{"operationId":"saveUsage","summary":"Save backup and usage answers","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"backupHoursDesired":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"batteryPreference":{"default":"NO_PREFERENCE","type":"string","enum":["NO_PREFERENCE","LITHIUM_LFP","LEAD_ACID"]},"gridHoursPerDay":{"type":"number","minimum":0,"maximum":24},"hasGenerator":{"default":false,"type":"boolean"},"generatorLitresPerWeek":{"type":"number","minimum":0,"maximum":10000},"monthlyFuelSpend":{"type":"number","minimum":0},"monthlyGridSpend":{"type":"number","minimum":0},"hasThreePhaseSupply":{"default":false,"type":"boolean"},"operatingHoursStart":{"type":"integer","minimum":0,"maximum":23},"operatingHoursEnd":{"type":"integer","minimum":0,"maximum":24},"operatingDaysPerWeek":{"type":"integer","minimum":1,"maximum":7},"expansionPlans":{"type":"string","maxLength":500}},"required":["backupHoursDesired"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}/complete":{"post":{"operationId":"completeAssessment","summary":"Run the sizing engine and store the three options","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assessments/{id}/select-tier":{"post":{"operationId":"selectTier","summary":"Choose Essential, Recommended or Maximum","tags":["Assessments"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]}},"required":["tier"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"country":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["id","code","name","currencyCode"],"additionalProperties":false},"region":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"},"name":{"type":"string"}},"required":["id","code","name"],"additionalProperties":false},{"type":"null"}]},"city":{"type":["string","null"]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"businessName":{"type":["string","null"]},"backupHoursDesired":{"type":"number"},"batteryPreference":{"type":"string"},"gridHoursPerDay":{"type":["number","null"]},"hasGenerator":{"type":"boolean"},"hasThreePhaseSupply":{"type":"boolean"},"monthlyFuelSpend":{"type":["number","null"]},"monthlyGridSpend":{"type":["number","null"]},"appliances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"applianceId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"surgeFactor":{"type":"number"},"dutyCycle":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"},"isThreePhase":{"type":"boolean"}},"required":["id","applianceId","name","quantity","watts","hoursDay","hoursNight","surgeFactor","dutyCycle","isCritical","isMotorLoad","isThreePhase"],"additionalProperties":false}},"recommendations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tier":{"type":"string","enum":["ESSENTIAL","RECOMMENDED","MAXIMUM"]},"isSelected":{"type":"boolean"},"panelArrayKw":{"type":"number"},"panelCount":{"type":"number"},"panelWatts":{"type":"number"},"inverterKva":{"type":"number"},"inverterType":{"type":"string"},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"batteryVoltage":{"type":"number"},"batteryNominalKwh":{"type":"number"},"batteryUsableKwh":{"type":"number"},"dailyDemandKwh":{"type":"number"},"dailyProductionKwh":{"type":"number"},"worstMonthProductionKwh":{"type":"number"},"runtimeHoursLow":{"type":"number"},"runtimeHoursHigh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"},"monthlyPaymentEstimate":{"type":["number","null"]},"requiresProfessionalAssessment":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["info","caution","professional"]},"message":{"type":"string"}},"required":["code","severity","message"],"additionalProperties":false}},"engineVersion":{"type":"string"}},"required":["id","tier","isSelected","panelArrayKw","panelCount","panelWatts","inverterKva","inverterType","batteryChemistry","batteryVoltage","batteryNominalKwh","batteryUsableKwh","dailyDemandKwh","dailyProductionKwh","worstMonthProductionKwh","runtimeHoursLow","runtimeHoursHigh","costMin","costMax","currency","monthlyPaymentEstimate","requiresProfessionalAssessment","warnings","engineVersion"],"additionalProperties":false}},"assumptions":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"},"explanation":{"type":"string"}},"required":["key","label","value","explanation"],"additionalProperties":false}},"quoteRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}},"engineVersion":{"type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","country","region","city","propertyType","bedrooms","businessName","backupHoursDesired","batteryPreference","gridHoursPerDay","hasGenerator","hasThreePhaseSupply","monthlyFuelSpend","monthlyGridSpend","appliances","recommendations","assumptions","quoteRequests","engineVersion","completedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products":{"get":{"operationId":"products","summary":"Verified products","description":"Only products whose documentation the platform team reviewed (verificationStatus VERIFIED).","tags":["Catalogue"],"security":[],"parameters":[{"name":"category","in":"query","required":false,"schema":{"type":"string","enum":["SOLAR_PANEL","INVERTER","BATTERY","CHARGE_CONTROLLER","SOLAR_GENERATOR","MOUNTING","CABLE","PROTECTION","MONITORING","PACKAGE","ACCESSORY"]}},{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":80},"description":"Search in name, model and manufacturer"},{"name":"country","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":2},"description":"Only prices offered in this country"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"},"model":{"type":"string"},"category":{"type":"string"},"manufacturer":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"country":{"type":["string","null"]}},"required":["name","slug","country"],"additionalProperties":false},"description":{"type":["string","null"]},"specs":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"warrantyYears":{"type":["number","null"]},"performanceWarrantyYears":{"type":["number","null"]},"claimedCertifications":{"type":"array","items":{"type":"string"},"description":"As claimed by the supplier; the platform vouches only for what product verification recorded"},"imageUrl":{"type":["string","null"]},"verificationStatus":{"type":"string","const":"VERIFIED"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fromPrice":{"type":["number","null"]},"currency":{"type":["string","null"]},"inStock":{"type":"boolean"}},"required":["id","slug","name","model","category","manufacturer","description","specs","warrantyYears","performanceWarrantyYears","claimedCertifications","imageUrl","verificationStatus","verifiedAt","fromPrice","currency","inStock"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products/{slug}":{"get":{"operationId":"product","summary":"A verified product with supplier offers","tags":["Catalogue"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":160}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"},"model":{"type":"string"},"category":{"type":"string"},"manufacturer":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"country":{"type":["string","null"]}},"required":["name","slug","country"],"additionalProperties":false},"description":{"type":["string","null"]},"specs":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"warrantyYears":{"type":["number","null"]},"performanceWarrantyYears":{"type":["number","null"]},"claimedCertifications":{"type":"array","items":{"type":"string"},"description":"As claimed by the supplier; the platform vouches only for what product verification recorded"},"imageUrl":{"type":["string","null"]},"verificationStatus":{"type":"string","const":"VERIFIED"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fromPrice":{"type":["number","null"]},"currency":{"type":["string","null"]},"inStock":{"type":"boolean"},"supplier":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}]},"variants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"sku":{"type":"string"},"name":{"type":"string"},"offers":{"type":"array","items":{"type":"object","properties":{"supplier":{"type":"string"},"country":{"type":"string"},"region":{"type":["string","null"]},"price":{"type":"number"},"currency":{"type":"string"},"stockStatus":{"type":"string"},"leadTimeDays":{"type":["number","null"]}},"required":["supplier","country","region","price","currency","stockStatus","leadTimeDays"],"additionalProperties":false}}},"required":["id","sku","name","offers"],"additionalProperties":false}},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}}},"required":["id","slug","name","model","category","manufacturer","description","specs","warrantyYears","performanceWarrantyYears","claimedCertifications","imageUrl","verificationStatus","verifiedAt","fromPrice","currency","inStock","supplier","variants","documents"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/installers":{"get":{"operationId":"installers","summary":"Verified installers","tags":["Catalogue"],"security":[],"parameters":[{"name":"country","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"region","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":10},"description":"Region code; needs country"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"country":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},"verificationStatus":{"type":"string","const":"VERIFIED"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"yearsExperience":{"type":"number"},"specialties":{"type":"array","items":{"type":"string"}},"equipmentBrands":{"type":"array","items":{"type":"string"}},"offersMaintenance":{"type":"boolean"},"ratingAvg":{"type":["number","null"]},"ratingCount":{"type":"number"},"completedProjects":{"type":"number"},"serviceAreas":{"type":"array","items":{"type":"object","properties":{"regionCode":{"type":"string"},"regionName":{"type":"string"},"cities":{"type":"array","items":{"type":"string"}}},"required":["regionCode","regionName","cities"],"additionalProperties":false}},"verifiedCertifications":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"issuer":{"type":"string"}},"required":["name","issuer"],"additionalProperties":false}}},"required":["id","slug","name","description","country","verificationStatus","verifiedAt","yearsExperience","specialties","equipmentBrands","offersMaintenance","ratingAvg","ratingCount","completedProjects","serviceAreas","verifiedCertifications"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/installers/{slug}":{"get":{"operationId":"installer","summary":"A verified installer's public profile","tags":["Catalogue"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":160}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"country":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},"verificationStatus":{"type":"string","const":"VERIFIED"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"yearsExperience":{"type":"number"},"specialties":{"type":"array","items":{"type":"string"}},"equipmentBrands":{"type":"array","items":{"type":"string"}},"offersMaintenance":{"type":"boolean"},"ratingAvg":{"type":["number","null"]},"ratingCount":{"type":"number"},"completedProjects":{"type":"number"},"serviceAreas":{"type":"array","items":{"type":"object","properties":{"regionCode":{"type":"string"},"regionName":{"type":"string"},"cities":{"type":"array","items":{"type":"string"}}},"required":["regionCode","regionName","cities"],"additionalProperties":false}},"verifiedCertifications":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"issuer":{"type":"string"}},"required":["name","issuer"],"additionalProperties":false}},"website":{"type":["string","null"]},"portfolio":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"batteryKwh":{"type":["number","null"]},"location":{"type":["string","null"]},"completedOn":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["title","description","systemKw","batteryKwh","location","completedOn"],"additionalProperties":false}},"reviews":{"type":"array","items":{"type":"object","properties":{"rating":{"type":"number"},"title":{"type":["string","null"]},"body":{"type":"string"},"author":{"type":"string"},"installerResponse":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["rating","title","body","author","installerResponse","createdAt"],"additionalProperties":false}}},"required":["id","slug","name","description","country","verificationStatus","verifiedAt","yearsExperience","specialties","equipmentBrands","offersMaintenance","ratingAvg","ratingCount","completedProjects","serviceAreas","verifiedCertifications","website","portfolio","reviews"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/quote-requests":{"post":{"operationId":"createQuoteRequest","summary":"Ask matched installers for proposals","description":"Needs a completed assessment with a chosen option. consentToShare must be true: it records the customer's consent to share the assessment with matched installers.","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"assessmentId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"addressLine1":{"type":"string","minLength":3,"maxLength":160},"addressLine2":{"type":"string","maxLength":160},"landmark":{"type":"string","maxLength":160},"preferredStartDate":{"type":"string","format":"date-time"},"wantsFinancing":{"default":false,"type":"boolean"},"budgetMax":{"type":"number","exclusiveMinimum":0},"notes":{"type":"string","maxLength":2000},"consentToShare":{"type":"boolean","const":true}},"required":["assessmentId","addressLine1","consentToShare"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"invitedInstallers":{"type":"number"}},"required":["id","reference","status","expiresAt","invitedInstallers"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"quoteRequests","summary":"My quote requests","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"city":{"type":["string","null"]},"region":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},{"type":"null"}]},"wantsFinancing":{"type":"boolean"},"budgetMax":{"type":["number","null"]},"preferredStartDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"invitedInstallers":{"type":"number"},"proposals":{"type":"number"},"projectId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"recommendation":{"anyOf":[{"type":"object","properties":{"tier":{"type":"string"},"panelArrayKw":{"type":"number"},"inverterKva":{"type":"number"},"batteryNominalKwh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"}},"required":["tier","panelArrayKw","inverterKva","batteryNominalKwh","costMin","costMax","currency"],"additionalProperties":false},{"type":"null"}]}},"required":["id","reference","status","city","region","wantsFinancing","budgetMax","preferredStartDate","expiresAt","createdAt","invitedInstallers","proposals","projectId","recommendation"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/quote-requests/{id}":{"get":{"operationId":"quoteRequest","summary":"Compare proposals for a request","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER","ADMIN","SUPER_ADMIN"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"request":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"city":{"type":["string","null"]},"region":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},{"type":"null"}]},"wantsFinancing":{"type":"boolean"},"budgetMax":{"type":["number","null"]},"preferredStartDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"invitedInstallers":{"type":"number"},"proposals":{"type":"number"},"projectId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"recommendation":{"anyOf":[{"type":"object","properties":{"tier":{"type":"string"},"panelArrayKw":{"type":"number"},"inverterKva":{"type":"number"},"batteryNominalKwh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"}},"required":["tier","panelArrayKw","inverterKva","batteryNominalKwh","costMin","costMax","currency"],"additionalProperties":false},{"type":"null"}]},"country":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["code","name","currencyCode"],"additionalProperties":false}},"required":["id","reference","status","city","region","wantsFinancing","budgetMax","preferredStartDate","expiresAt","createdAt","invitedInstallers","proposals","projectId","recommendation","country"],"additionalProperties":false},"invitations":{"type":"array","items":{"type":"object","properties":{"installer":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"],"additionalProperties":false},"status":{"type":"string"},"matchReasons":{"type":"array","items":{"type":"string"}}},"required":["installer","status","matchReasons"],"additionalProperties":false}},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"isExpired":{"type":"boolean"},"installer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"},"verificationStatus":{"type":"string"},"ratingAvg":{"type":["number","null"]},"ratingCount":{"type":"number"},"completedProjects":{"type":"number"},"verifiedCertifications":{"type":"array","items":{"type":"string"}}},"required":["id","slug","name","verificationStatus","ratingAvg","ratingCount","completedProjects","verifiedCertifications"],"additionalProperties":false},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"},"batteryChemistry":{"type":"string"}},"required":["panelArrayKw","batteryKwh","inverterKva","batteryChemistry"],"additionalProperties":false},"equipmentCost":{"type":"number"},"materialsCost":{"type":"number"},"labourCost":{"type":"number"},"otherCost":{"type":"number"},"discount":{"type":"number"},"taxAmount":{"type":"number"},"total":{"type":"number"},"currency":{"type":"string"},"estimatedInstallDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"installDurationDays":{"type":["number","null"]},"validUntil":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"workmanshipWarrantyMonths":{"type":"number"},"maintenancePackage":{"type":["string","null"]},"maintenanceIncludedMonths":{"type":["number","null"]},"notes":{"type":["string","null"]},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"highlights":{"type":"array","items":{"type":"string"},"description":"Factual comparisons only, e.g. \"Lowest total price\""},"monthlyEstimate":{"anyOf":[{"type":"object","properties":{"deposit":{"type":"number"},"monthlyPayment":{"type":"number"},"termMonths":{"type":"number"},"totalRepayable":{"type":"number"}},"required":["deposit","monthlyPayment","termMonths","totalRepayable"],"additionalProperties":false},{"type":"null"}]},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["id","reference","status","isExpired","installer","system","equipmentCost","materialsCost","labourCost","otherCost","discount","taxAmount","total","currency","estimatedInstallDate","installDurationDays","validUntil","workmanshipWarrantyMonths","maintenancePackage","maintenanceIncludedMonths","notes","submittedAt","highlights","monthlyEstimate","items"],"additionalProperties":false}},"financingAssumption":{"anyOf":[{"type":"object","properties":{"label":{"type":"string"},"depositPct":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"}},"required":["label","depositPct","termMonths","annualRatePct"],"additionalProperties":false},{"type":"null"}]}},"required":["request","invitations","quotes","financingAssumption"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/quotes/{id}/accept":{"post":{"operationId":"acceptQuote","summary":"Accept a proposal and start the project","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects":{"get":{"operationId":"projects","summary":"My projects","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"installer":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"],"additionalProperties":false},"contractValue":{"type":"number"},"currency":{"type":"string"},"paymentMode":{"type":["string","null"]},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"milestones":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"status":{"type":"string"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["key","label","status","completedAt"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","installer","contractValue","currency","paymentMode","system","milestones","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects/{id}":{"get":{"operationId":"project","summary":"A project I'm part of","description":"For the customer, the awarded installer (session or projects:read key) and staff. Customer contact details are shown to the installer; financing details only to the customer and staff.","tags":["Customer"],"security":[{"session":[]},{"apiKey":["projects:read"]}],"x-roles":["CUSTOMER","INSTALLER","TECHNICIAN","ADMIN","SUPER_ADMIN"],"x-api-key-scopes":["projects:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"yourRole":{"type":"string","enum":["customer","installer","staff"]},"contractValue":{"type":"number"},"currency":{"type":"string"},"paymentMode":{"type":["string","null"]},"holdReason":{"type":["string","null"]},"installer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"],"additionalProperties":false},"customer":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["name","email","phone"],"additionalProperties":false},{"type":"null"}],"description":"Shown to the installer and staff"},"address":{"anyOf":[{"type":"object","properties":{"line1":{"type":"string"},"line2":{"type":["string","null"]},"landmark":{"type":["string","null"]},"city":{"type":"string"},"region":{"type":["string","null"]}},"required":["line1","line2","landmark","city","region"],"additionalProperties":false},{"type":"null"}]},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"},"batteryChemistry":{"type":"string"}},"required":["panelArrayKw","batteryKwh","inverterKva","batteryChemistry"],"additionalProperties":false},"milestones":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"status":{"type":"string"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["key","label","status","completedAt"],"additionalProperties":false}},"events":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["type","message","createdAt"],"additionalProperties":false}},"issues":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"category":{"type":"string"},"status":{"type":"string"},"description":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","category","status","description","createdAt"],"additionalProperties":false}},"inspection":{"anyOf":[{"type":"object","properties":{"status":{"type":"string"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["status","scheduledFor","completedAt"],"additionalProperties":false},{"type":"null"}]},"design":{"anyOf":[{"type":"object","properties":{"version":{"type":"number"},"status":{"type":"string"},"arrayKw":{"type":"number"},"inverterKva":{"type":"number"},"batteryBankKwh":{"type":"number"}},"required":["version","status","arrayKw","inverterKva","batteryBankKwh"],"additionalProperties":false},{"type":"null"}]},"installation":{"anyOf":[{"type":"object","properties":{"scheduledStart":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scheduledEnd":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"startedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"qcStatus":{"type":"string"},"acceptanceStatus":{"type":"string"},"equipment":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"manufacturer":{"type":"string"},"model":{"type":"string"},"serialNumber":{"type":"string"},"capacityLabel":{"type":["string","null"]},"warrantyYears":{"type":["number","null"]}},"required":["category","manufacturer","model","serialNumber","capacityLabel","warrantyYears"],"additionalProperties":false}}},"required":["scheduledStart","scheduledEnd","startedAt","completedAt","qcStatus","acceptanceStatus","equipment"],"additionalProperties":false},{"type":"null"}]},"passport":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"}},"required":["id","code"],"additionalProperties":false},{"type":"null"}]},"financing":{"type":"array","items":{"type":"object","properties":{"reference":{"type":"string"},"status":{"type":"string"},"partner":{"type":"string"}},"required":["reference","status","partner"],"additionalProperties":false},"description":"Customer and staff only; empty for installers"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","yourRole","contractValue","currency","paymentMode","holdReason","installer","customer","address","system","milestones","events","issues","inspection","design","installation","passport","financing","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payments":{"get":{"operationId":"payments","summary":"My payments","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"}},"required":["id","reference"],"additionalProperties":false},{"type":"null"}]},"purpose":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"provider":{"type":"string"},"method":{"type":["string","null"]},"status":{"type":"string"},"failureReason":{"type":["string","null"]},"paidAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","project","purpose","amount","currency","provider","method","status","failureReason","paidAt","createdAt"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/warranties":{"get":{"operationId":"warranties","summary":"Warranties on my systems","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string"},"provider":{"type":"string"},"coverage":{"type":"string"},"startsAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"endsAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"isActive":{"type":"boolean"},"passport":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string"}},"required":["id","code"],"additionalProperties":false},"equipment":{"anyOf":[{"type":"object","properties":{"category":{"type":"string"},"manufacturer":{"type":"string"},"model":{"type":"string"},"serialNumber":{"type":"string"}},"required":["category","manufacturer","model","serialNumber"],"additionalProperties":false},{"type":"null"}]},"installer":{"type":["string","null"]},"claims":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","createdAt"],"additionalProperties":false}}},"required":["id","type","provider","coverage","startsAt","endsAt","isActive","passport","equipment","installer","claims"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/warranty-claims":{"post":{"operationId":"createWarrantyClaim","summary":"Claim under a warranty","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"warrantyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"issue":{"type":"string","minLength":20,"maxLength":3000},"occurredAt":{"type":"string","format":"date-time"}},"required":["warrantyId","issue"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"warrantyId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"issue":{"type":"string"},"occurredAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","warrantyId","status","issue","occurredAt","createdAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/maintenance-requests":{"get":{"operationId":"maintenanceRequests","summary":"My maintenance requests","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"type":{"type":"string"},"description":{"type":"string"},"urgency":{"type":"string"},"status":{"type":"string"},"preferredDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"passportCode":{"type":["string","null"]},"assignedInstaller":{"type":["string","null"]},"visits":{"type":"array","items":{"type":"object","properties":{"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"findings":{"type":["string","null"]},"workDone":{"type":["string","null"]}},"required":["scheduledFor","completedAt","findings","workDone"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","type","description","urgency","status","preferredDate","passportCode","assignedInstaller","visits","createdAt"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createMaintenanceRequest","summary":"Request a maintenance visit","tags":["Customer"],"security":[{"session":[]}],"x-roles":["CUSTOMER"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"passportId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["SYSTEM_INSPECTION","PANEL_CLEANING","BATTERY_REPLACEMENT","INVERTER_REPAIR","SYSTEM_UPGRADE","TROUBLESHOOTING","PREVENTIVE_MAINTENANCE"]},"description":{"type":"string","minLength":10,"maxLength":3000},"urgency":{"default":"NORMAL","type":"string","enum":["LOW","NORMAL","HIGH"]},"preferredDate":{"type":"string","format":"date-time"}},"required":["passportId","type","description"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"type":{"type":"string"},"description":{"type":"string"},"urgency":{"type":"string"},"status":{"type":"string"},"preferredDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"passportCode":{"type":["string","null"]},"assignedInstaller":{"type":["string","null"]},"visits":{"type":"array","items":{"type":"object","properties":{"scheduledFor":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"completedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"findings":{"type":["string","null"]},"workDone":{"type":["string","null"]}},"required":["scheduledFor","completedAt","findings","workDone"],"additionalProperties":false}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","type","description","urgency","status","preferredDate","passportCode","assignedInstaller","visits","createdAt"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/notifications":{"get":{"operationId":"notifications","summary":"My notifications","description":"Available to every signed-in user, newest first.","tags":["Customer"],"security":[{"session":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":30,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"link":{"type":["string","null"]},"readAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","type","title","body","link","readAt","createdAt"],"additionalProperties":false}},"meta":{"type":"object","properties":{"unread":{"type":"number"}},"required":["unread"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/notifications/read":{"post":{"operationId":"markNotificationsRead","summary":"Mark notifications read","tags":["Customer"],"security":[{"session":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Mark one notification; omit to mark all as read","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"unread":{"type":"number"}},"required":["unread"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads":{"get":{"operationId":"leads","summary":"Quote-request leads for my company","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:read"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"invitationId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"matchScore":{"type":"number"},"matchReasons":{"type":"array","items":{"type":"string"}},"invitedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"viewedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"respondedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"quoteRequest":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"city":{"type":["string","null"]},"region":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"wantsFinancing":{"type":"boolean"},"budgetMax":{"type":["number","null"]},"preferredStartDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"backupHoursDesired":{"type":"number"},"recommendation":{"anyOf":[{"type":"object","properties":{"tier":{"type":"string"},"panelArrayKw":{"type":"number"},"inverterKva":{"type":"number"},"batteryNominalKwh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"}},"required":["tier","panelArrayKw","inverterKva","batteryNominalKwh","costMin","costMax","currency"],"additionalProperties":false},{"type":"null"}]}},"required":["id","reference","status","city","region","expiresAt","wantsFinancing","budgetMax","preferredStartDate","propertyType","bedrooms","backupHoursDesired","recommendation"],"additionalProperties":false},"yourProposal":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"}},"required":["id","status","total","currency"],"additionalProperties":false},{"type":"null"}]}},"required":["invitationId","status","matchScore","matchReasons","invitedAt","viewedAt","respondedAt","quoteRequest","yourProposal"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads/{invitationId}":{"get":{"operationId":"lead","summary":"A lead with the customer's assessment","description":"Opening a lead marks it viewed. The customer is identified by first name until they accept a proposal.","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:read"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:read"],"parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"invitationId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"matchScore":{"type":"number"},"matchReasons":{"type":"array","items":{"type":"string"}},"invitedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"viewedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"respondedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"quoteRequest":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"city":{"type":["string","null"]},"region":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"],"additionalProperties":false},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"wantsFinancing":{"type":"boolean"},"budgetMax":{"type":["number","null"]},"preferredStartDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"propertyType":{"type":"string"},"bedrooms":{"type":["number","null"]},"backupHoursDesired":{"type":"number"},"recommendation":{"anyOf":[{"type":"object","properties":{"tier":{"type":"string"},"panelArrayKw":{"type":"number"},"inverterKva":{"type":"number"},"batteryNominalKwh":{"type":"number"},"costMin":{"type":"number"},"costMax":{"type":"number"},"currency":{"type":"string"}},"required":["tier","panelArrayKw","inverterKva","batteryNominalKwh","costMin","costMax","currency"],"additionalProperties":false},{"type":"null"}]}},"required":["id","reference","status","city","region","expiresAt","wantsFinancing","budgetMax","preferredStartDate","propertyType","bedrooms","backupHoursDesired","recommendation"],"additionalProperties":false},"yourProposal":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"}},"required":["id","status","total","currency"],"additionalProperties":false},{"type":"null"}]},"customerFirstName":{"type":"string"},"notes":{"type":["string","null"]},"country":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"currencyCode":{"type":"string"}},"required":["code","name","currencyCode"],"additionalProperties":false},"appliances":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"number"},"watts":{"type":"number"},"hoursDay":{"type":"number"},"hoursNight":{"type":"number"},"isCritical":{"type":"boolean"},"isMotorLoad":{"type":"boolean"}},"required":["name","quantity","watts","hoursDay","hoursNight","isCritical","isMotorLoad"],"additionalProperties":false}},"bills":{"type":"array","items":{"type":"object","properties":{"periodStart":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"periodEnd":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"kwh":{"type":["number","null"]},"amount":{"type":["number","null"]},"currency":{"type":"string"}},"required":["periodStart","periodEnd","kwh","amount","currency"],"additionalProperties":false}},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}},"proposal":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"},"batteryChemistry":{"type":"string"}},"required":["panelArrayKw","batteryKwh","inverterKva","batteryChemistry"],"additionalProperties":false},"equipmentCost":{"type":"number"},"materialsCost":{"type":"number"},"labourCost":{"type":"number"},"otherCost":{"type":"number"},"discount":{"type":"number"},"taxAmount":{"type":"number"},"total":{"type":"number"},"currency":{"type":"string"},"estimatedInstallDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"installDurationDays":{"type":["number","null"]},"validUntil":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"workmanshipWarrantyMonths":{"type":"number"},"maintenancePackage":{"type":["string","null"]},"maintenanceIncludedMonths":{"type":["number","null"]},"notes":{"type":["string","null"]},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["id","reference","status","system","equipmentCost","materialsCost","labourCost","otherCost","discount","taxAmount","total","currency","estimatedInstallDate","installDurationDays","validUntil","workmanshipWarrantyMonths","maintenancePackage","maintenanceIncludedMonths","notes","submittedAt","items"],"additionalProperties":false},{"type":"null"}]}},"required":["invitationId","status","matchScore","matchReasons","invitedAt","viewedAt","respondedAt","quoteRequest","yourProposal","customerFirstName","notes","country","appliances","bills","documents","proposal"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads/{invitationId}/quote":{"post":{"operationId":"submitQuote","summary":"Send or revise a proposal","description":"Only verified installers. Totals and tax are computed server-side from the items.","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:write"]}],"x-roles":["INSTALLER"],"x-api-key-scopes":["projects:write"],"parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"panelArrayKw":{"type":"number","exclusiveMinimum":0,"maximum":10000},"batteryKwh":{"type":"number","minimum":0,"maximum":100000},"batteryChemistry":{"type":"string","enum":["LITHIUM_LFP","LEAD_ACID"]},"inverterKva":{"type":"number","exclusiveMinimum":0,"maximum":10000},"items":{"minItems":1,"type":"array","items":{"type":"object","properties":{"variantId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"category":{"type":"string","enum":["SOLAR_PANEL","INVERTER","BATTERY","CHARGE_CONTROLLER","SOLAR_GENERATOR","MOUNTING","CABLE","PROTECTION","MONITORING","PACKAGE","ACCESSORY"]},"description":{"type":"string","minLength":2,"maxLength":200},"brand":{"type":"string","maxLength":80},"model":{"type":"string","maxLength":80},"quantity":{"type":"number","exclusiveMinimum":0,"maximum":10000},"unitPrice":{"type":"number","minimum":0},"warrantyYears":{"type":"integer","minimum":0,"maximum":30}},"required":["category","description","quantity","unitPrice"]}},"labourCost":{"type":"number","minimum":0},"otherCost":{"default":0,"type":"number","minimum":0},"discount":{"default":0,"type":"number","minimum":0},"pricesIncludeTax":{"default":false,"type":"boolean"},"estimatedInstallDate":{"type":"string","format":"date-time"},"installDurationDays":{"type":"integer","minimum":1,"maximum":365},"validDays":{"default":21,"type":"integer","minimum":3,"maximum":90},"workmanshipWarrantyMonths":{"type":"integer","minimum":0,"maximum":240},"maintenancePackage":{"type":"string","maxLength":500},"maintenanceIncludedMonths":{"type":"integer","minimum":0,"maximum":120},"notes":{"type":"string","maxLength":3000}},"required":["panelArrayKw","batteryKwh","batteryChemistry","inverterKva","items","labourCost","workmanshipWarrantyMonths"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"},"validUntil":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","total","currency","validUntil"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/installer/projects":{"get":{"operationId":"installerProjects","summary":"Projects awarded to my company","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:read"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"address":{"anyOf":[{"type":"object","properties":{"line1":{"type":"string"},"line2":{"type":["string","null"]},"landmark":{"type":["string","null"]},"city":{"type":"string"},"region":{"type":["string","null"]}},"required":["line1","line2","landmark","city","region"],"additionalProperties":false},{"type":"null"}]},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"latestInspection":{"anyOf":[{"type":"object","properties":{"status":{"type":"string"},"scheduledFor":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["status","scheduledFor"],"additionalProperties":false},{"type":"null"}]},"installation":{"anyOf":[{"type":"object","properties":{"scheduledStart":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scheduledEnd":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"qcStatus":{"type":"string"},"acceptanceStatus":{"type":"string"}},"required":["scheduledStart","scheduledEnd","qcStatus","acceptanceStatus"],"additionalProperties":false},{"type":"null"}]},"contractValue":{"type":"number"},"currency":{"type":"string"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","customerName","address","system","latestInspection","installation","contractValue","currency","updatedAt"],"additionalProperties":false}}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects/{id}/equipment-ordered":{"post":{"operationId":"equipmentOrdered","summary":"Mark equipment ordered","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:write"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects/{id}/equipment-delivered":{"post":{"operationId":"equipmentDelivered","summary":"Mark equipment delivered","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:write"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/projects/{id}/equipment":{"post":{"operationId":"recordEquipment","summary":"Record installed equipment serial numbers","description":"After installation has started. A serial already recorded on another system is refused.","tags":["Installer"],"security":[{"session":[]},{"apiKey":["projects:write"]}],"x-roles":["INSTALLER","TECHNICIAN"],"x-api-key-scopes":["projects:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"minItems":1,"type":"array","items":{"type":"object","properties":{"category":{"type":"string","enum":["SOLAR_PANEL","INVERTER","BATTERY","CHARGE_CONTROLLER","MONITORING","PROTECTION","MOUNTING","ACCESSORY"]},"manufacturer":{"type":"string","minLength":1,"maxLength":80},"model":{"type":"string","minLength":1,"maxLength":80},"serialNumber":{"type":"string","minLength":3,"maxLength":80},"capacityLabel":{"type":"string","maxLength":40},"warrantyYears":{"type":"integer","minimum":0,"maximum":30},"variantId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["category","manufacturer","model","serialNumber"]}}},"required":["items"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/financing/applications":{"get":{"operationId":"applications","summary":"Applications sent to my organisation","description":"At most 200, most recently updated first. meta.counts has the pipeline counts per status.","tags":["Financing"],"security":[{"session":[]},{"apiKey":["financing:read"]}],"x-roles":["FINANCIER"],"x-api-key-scopes":["financing:read"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["SUBMITTED","UNDER_REVIEW","INFO_REQUIRED","APPROVED","REJECTED","OFFER_ACCEPTED","FUNDED","REPAYMENT_ACTIVE","COMPLETED","DELINQUENT","WITHDRAWN"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},"projectReference":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"systemCost":{"type":"number"},"depositAmount":{"type":"number"},"amountRequested":{"type":"number"},"termMonths":{"type":"number"},"currency":{"type":"string"},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","reference","status","customerName","product","projectReference","systemKw","systemCost","depositAmount","amountRequested","termMonths","currency","submittedAt","decidedAt","updatedAt"],"additionalProperties":false}},"meta":{"type":"object","properties":{"counts":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number"}}},"required":["counts"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/financing/applications/{id}":{"get":{"operationId":"application","summary":"One application","description":"Identity and bank numbers are masked unless ?reveal=true, which decrypts them while the customer's consent is active and writes an audit entry.","tags":["Financing"],"security":[{"session":[]},{"apiKey":["financing:read"]}],"x-roles":["FINANCIER"],"x-api-key-scopes":["financing:read"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"reveal","in":"query","required":false,"schema":{"type":"string","enum":["0","1","true","false"]},"description":"true returns decrypted identity and bank details (only while the customer's consent is active); every reveal is audited"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},"projectReference":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"systemCost":{"type":"number"},"depositAmount":{"type":"number"},"amountRequested":{"type":"number"},"termMonths":{"type":"number"},"currency":{"type":"string"},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"consent":{"type":"object","properties":{"active":{"type":"boolean"},"grantedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scope":{"type":"array","items":{"type":"string"}}},"required":["active","grantedAt","revokedAt","scope"],"additionalProperties":false},"customer":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["name","email","phone"],"additionalProperties":false,"description":"Contact details only while consent is active"},"applicant":{"type":"object","properties":{"employmentType":{"type":["string","null"]},"employerOrBusiness":{"type":["string","null"]},"yearsInRole":{"type":["number","null"]},"monthlyIncome":{"type":["number","null"]},"idType":{"type":["string","null"]},"idNumberMasked":{"type":["string","null"]},"bankName":{"type":["string","null"]},"accountNumberMasked":{"type":["string","null"]},"hasGuarantor":{"type":"boolean"},"creditCheckConsent":{"type":"boolean"}},"required":["employmentType","employerOrBusiness","yearsInRole","monthlyIncome","idType","idNumberMasked","bankName","accountNumberMasked","hasGuarantor","creditCheckConsent"],"additionalProperties":false},"infoRequest":{"type":["string","null"]},"decisionNotes":{"type":["string","null"]},"offers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"amount":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"},"interestMethod":{"type":"string"},"upfrontFees":{"type":"number"},"monthlyFee":{"type":"number"},"monthlyPayment":{"type":"number"},"totalRepayable":{"type":"number"},"conditions":{"type":["string","null"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","amount","termMonths","annualRatePct","interestMethod","upfrontFees","monthlyFee","monthlyPayment","totalRepayable","conditions","expiresAt","decidedAt","createdAt"],"additionalProperties":false}},"agreement":{"anyOf":[{"type":"object","properties":{"partnerLoanRef":{"type":"string"},"signedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fundedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"disbursedAmount":{"type":["number","null"]},"repaymentStatus":{"type":["string","null"]},"nextPaymentDueAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"outstandingBalance":{"type":["number","null"]}},"required":["partnerLoanRef","signedAt","fundedAt","disbursedAmount","repaymentStatus","nextPaymentDueAt","outstandingBalance"],"additionalProperties":false},{"type":"null"}]},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"installer":{"type":"string"},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"quote":{"type":"object","properties":{"reference":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["reference","total","currency","system","items"],"additionalProperties":false}},"required":["id","reference","status","installer","city","region","quote"],"additionalProperties":false},{"type":"null"}]},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}},"sensitive":{"anyOf":[{"type":"object","properties":{"idType":{"type":"string"},"idNumber":{"type":"string"},"bankName":{"type":"string"},"accountNumber":{"type":"string"},"guarantor":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"relationship":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}]}},"required":["idType","idNumber","bankName","accountNumber","guarantor"],"additionalProperties":false},{"type":"null"}],"description":"Only with ?reveal=true"}},"required":["id","reference","status","customerName","product","projectReference","systemKw","systemCost","depositAmount","amountRequested","termMonths","currency","submittedAt","decidedAt","updatedAt","consent","customer","applicant","infoRequest","decisionNotes","offers","agreement","project","documents","sensitive"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/financing/applications/{id}/decision":{"post":{"operationId":"decide","summary":"Review, request information, decline or make an offer","description":"Body by action: {action:\"start_review\"} | {action:\"request_info\", message} | {action:\"reject\", reason} | {action:\"offer\", amount, termMonths, annualRatePct, interestMethod, upfrontFees?, monthlyFee?, conditions?, expiresInDays?}.","tags":["Financing"],"security":[{"session":[]},{"apiKey":["financing:write"]}],"x-roles":["FINANCIER"],"x-api-key-scopes":["financing:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"action":{"type":"string","const":"start_review"}},"required":["action"]},{"type":"object","properties":{"action":{"type":"string","const":"request_info"},"message":{"type":"string","minLength":5,"maxLength":2000}},"required":["action","message"]},{"type":"object","properties":{"action":{"type":"string","const":"reject"},"reason":{"type":"string","minLength":3,"maxLength":2000}},"required":["action","reason"]},{"type":"object","properties":{"amount":{"type":"number","exclusiveMinimum":0},"termMonths":{"type":"integer","minimum":1,"maximum":120},"annualRatePct":{"type":"number","minimum":0,"maximum":200},"interestMethod":{"type":"string","enum":["REDUCING_BALANCE","FLAT"]},"upfrontFees":{"default":0,"type":"number","minimum":0},"monthlyFee":{"default":0,"type":"number","minimum":0},"conditions":{"type":"string","maxLength":2000},"expiresInDays":{"default":14,"type":"integer","minimum":1,"maximum":60},"action":{"type":"string","const":"offer"}},"required":["amount","termMonths","annualRatePct","interestMethod","action"]}]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},"projectReference":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"systemCost":{"type":"number"},"depositAmount":{"type":"number"},"amountRequested":{"type":"number"},"termMonths":{"type":"number"},"currency":{"type":"string"},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"consent":{"type":"object","properties":{"active":{"type":"boolean"},"grantedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scope":{"type":"array","items":{"type":"string"}}},"required":["active","grantedAt","revokedAt","scope"],"additionalProperties":false},"customer":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["name","email","phone"],"additionalProperties":false,"description":"Contact details only while consent is active"},"applicant":{"type":"object","properties":{"employmentType":{"type":["string","null"]},"employerOrBusiness":{"type":["string","null"]},"yearsInRole":{"type":["number","null"]},"monthlyIncome":{"type":["number","null"]},"idType":{"type":["string","null"]},"idNumberMasked":{"type":["string","null"]},"bankName":{"type":["string","null"]},"accountNumberMasked":{"type":["string","null"]},"hasGuarantor":{"type":"boolean"},"creditCheckConsent":{"type":"boolean"}},"required":["employmentType","employerOrBusiness","yearsInRole","monthlyIncome","idType","idNumberMasked","bankName","accountNumberMasked","hasGuarantor","creditCheckConsent"],"additionalProperties":false},"infoRequest":{"type":["string","null"]},"decisionNotes":{"type":["string","null"]},"offers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"amount":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"},"interestMethod":{"type":"string"},"upfrontFees":{"type":"number"},"monthlyFee":{"type":"number"},"monthlyPayment":{"type":"number"},"totalRepayable":{"type":"number"},"conditions":{"type":["string","null"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","amount","termMonths","annualRatePct","interestMethod","upfrontFees","monthlyFee","monthlyPayment","totalRepayable","conditions","expiresAt","decidedAt","createdAt"],"additionalProperties":false}},"agreement":{"anyOf":[{"type":"object","properties":{"partnerLoanRef":{"type":"string"},"signedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fundedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"disbursedAmount":{"type":["number","null"]},"repaymentStatus":{"type":["string","null"]},"nextPaymentDueAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"outstandingBalance":{"type":["number","null"]}},"required":["partnerLoanRef","signedAt","fundedAt","disbursedAmount","repaymentStatus","nextPaymentDueAt","outstandingBalance"],"additionalProperties":false},{"type":"null"}]},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"installer":{"type":"string"},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"quote":{"type":"object","properties":{"reference":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["reference","total","currency","system","items"],"additionalProperties":false}},"required":["id","reference","status","installer","city","region","quote"],"additionalProperties":false},{"type":"null"}]},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}},"sensitive":{"anyOf":[{"type":"object","properties":{"idType":{"type":"string"},"idNumber":{"type":"string"},"bankName":{"type":"string"},"accountNumber":{"type":"string"},"guarantor":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"relationship":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}]}},"required":["idType","idNumber","bankName","accountNumber","guarantor"],"additionalProperties":false},{"type":"null"}],"description":"Only with ?reveal=true"}},"required":["id","reference","status","customerName","product","projectReference","systemKw","systemCost","depositAmount","amountRequested","termMonths","currency","submittedAt","decidedAt","updatedAt","consent","customer","applicant","infoRequest","decisionNotes","offers","agreement","project","documents","sensitive"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/financing/applications/{id}/funded":{"post":{"operationId":"funded","summary":"Mark an accepted offer funded","description":"The disbursed amount must match the accepted offer. Records the disbursement against the project's payment schedule.","tags":["Financing"],"security":[{"session":[]},{"apiKey":["financing:write"]}],"x-roles":["FINANCIER"],"x-api-key-scopes":["financing:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"partnerLoanRef":{"type":"string","minLength":2,"maxLength":80},"disbursedAmount":{"type":"number","exclusiveMinimum":0},"signedAt":{"type":"string","format":"date-time"}},"required":["partnerLoanRef","disbursedAmount"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},"projectReference":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"systemCost":{"type":"number"},"depositAmount":{"type":"number"},"amountRequested":{"type":"number"},"termMonths":{"type":"number"},"currency":{"type":"string"},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"consent":{"type":"object","properties":{"active":{"type":"boolean"},"grantedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scope":{"type":"array","items":{"type":"string"}}},"required":["active","grantedAt","revokedAt","scope"],"additionalProperties":false},"customer":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["name","email","phone"],"additionalProperties":false,"description":"Contact details only while consent is active"},"applicant":{"type":"object","properties":{"employmentType":{"type":["string","null"]},"employerOrBusiness":{"type":["string","null"]},"yearsInRole":{"type":["number","null"]},"monthlyIncome":{"type":["number","null"]},"idType":{"type":["string","null"]},"idNumberMasked":{"type":["string","null"]},"bankName":{"type":["string","null"]},"accountNumberMasked":{"type":["string","null"]},"hasGuarantor":{"type":"boolean"},"creditCheckConsent":{"type":"boolean"}},"required":["employmentType","employerOrBusiness","yearsInRole","monthlyIncome","idType","idNumberMasked","bankName","accountNumberMasked","hasGuarantor","creditCheckConsent"],"additionalProperties":false},"infoRequest":{"type":["string","null"]},"decisionNotes":{"type":["string","null"]},"offers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"amount":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"},"interestMethod":{"type":"string"},"upfrontFees":{"type":"number"},"monthlyFee":{"type":"number"},"monthlyPayment":{"type":"number"},"totalRepayable":{"type":"number"},"conditions":{"type":["string","null"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","amount","termMonths","annualRatePct","interestMethod","upfrontFees","monthlyFee","monthlyPayment","totalRepayable","conditions","expiresAt","decidedAt","createdAt"],"additionalProperties":false}},"agreement":{"anyOf":[{"type":"object","properties":{"partnerLoanRef":{"type":"string"},"signedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fundedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"disbursedAmount":{"type":["number","null"]},"repaymentStatus":{"type":["string","null"]},"nextPaymentDueAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"outstandingBalance":{"type":["number","null"]}},"required":["partnerLoanRef","signedAt","fundedAt","disbursedAmount","repaymentStatus","nextPaymentDueAt","outstandingBalance"],"additionalProperties":false},{"type":"null"}]},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"installer":{"type":"string"},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"quote":{"type":"object","properties":{"reference":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["reference","total","currency","system","items"],"additionalProperties":false}},"required":["id","reference","status","installer","city","region","quote"],"additionalProperties":false},{"type":"null"}]},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}},"sensitive":{"anyOf":[{"type":"object","properties":{"idType":{"type":"string"},"idNumber":{"type":"string"},"bankName":{"type":"string"},"accountNumber":{"type":"string"},"guarantor":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"relationship":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}]}},"required":["idType","idNumber","bankName","accountNumber","guarantor"],"additionalProperties":false},{"type":"null"}],"description":"Only with ?reveal=true"}},"required":["id","reference","status","customerName","product","projectReference","systemKw","systemCost","depositAmount","amountRequested","termMonths","currency","submittedAt","decidedAt","updatedAt","consent","customer","applicant","infoRequest","decisionNotes","offers","agreement","project","documents","sensitive"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/financing/applications/{id}/repayment":{"post":{"operationId":"repayment","summary":"Report repayment status","tags":["Financing"],"security":[{"session":[]},{"apiKey":["financing:write"]}],"x-roles":["FINANCIER"],"x-api-key-scopes":["financing:write"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["REPAYMENT_ACTIVE","COMPLETED","DELINQUENT"]},"nextPaymentDueAt":{"type":"string","format":"date-time"},"outstandingBalance":{"type":"number","minimum":0},"note":{"type":"string","maxLength":500}},"required":["status"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"customerName":{"type":"string"},"product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"string"}},"required":["id","name","type"],"additionalProperties":false},"projectReference":{"type":["string","null"]},"systemKw":{"type":["number","null"]},"systemCost":{"type":"number"},"depositAmount":{"type":"number"},"amountRequested":{"type":"number"},"termMonths":{"type":"number"},"currency":{"type":"string"},"submittedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"consent":{"type":"object","properties":{"active":{"type":"boolean"},"grantedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"scope":{"type":"array","items":{"type":"string"}}},"required":["active","grantedAt","revokedAt","scope"],"additionalProperties":false},"customer":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["name","email","phone"],"additionalProperties":false,"description":"Contact details only while consent is active"},"applicant":{"type":"object","properties":{"employmentType":{"type":["string","null"]},"employerOrBusiness":{"type":["string","null"]},"yearsInRole":{"type":["number","null"]},"monthlyIncome":{"type":["number","null"]},"idType":{"type":["string","null"]},"idNumberMasked":{"type":["string","null"]},"bankName":{"type":["string","null"]},"accountNumberMasked":{"type":["string","null"]},"hasGuarantor":{"type":"boolean"},"creditCheckConsent":{"type":"boolean"}},"required":["employmentType","employerOrBusiness","yearsInRole","monthlyIncome","idType","idNumberMasked","bankName","accountNumberMasked","hasGuarantor","creditCheckConsent"],"additionalProperties":false},"infoRequest":{"type":["string","null"]},"decisionNotes":{"type":["string","null"]},"offers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"amount":{"type":"number"},"termMonths":{"type":"number"},"annualRatePct":{"type":"number"},"interestMethod":{"type":"string"},"upfrontFees":{"type":"number"},"monthlyFee":{"type":"number"},"monthlyPayment":{"type":"number"},"totalRepayable":{"type":"number"},"conditions":{"type":["string","null"]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"decidedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","status","amount","termMonths","annualRatePct","interestMethod","upfrontFees","monthlyFee","monthlyPayment","totalRepayable","conditions","expiresAt","decidedAt","createdAt"],"additionalProperties":false}},"agreement":{"anyOf":[{"type":"object","properties":{"partnerLoanRef":{"type":"string"},"signedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"fundedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"disbursedAmount":{"type":["number","null"]},"repaymentStatus":{"type":["string","null"]},"nextPaymentDueAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"outstandingBalance":{"type":["number","null"]}},"required":["partnerLoanRef","signedAt","fundedAt","disbursedAmount","repaymentStatus","nextPaymentDueAt","outstandingBalance"],"additionalProperties":false},{"type":"null"}]},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reference":{"type":"string"},"status":{"type":"string"},"installer":{"type":"string"},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"quote":{"type":"object","properties":{"reference":{"type":"string"},"total":{"type":"number"},"currency":{"type":"string"},"system":{"type":"object","properties":{"panelArrayKw":{"type":"number"},"batteryKwh":{"type":"number"},"inverterKva":{"type":"number"}},"required":["panelArrayKw","batteryKwh","inverterKva"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"description":{"type":"string"},"brand":{"type":["string","null"]},"model":{"type":["string","null"]},"quantity":{"type":"number"},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"warrantyYears":{"type":["number","null"]}},"required":["category","description","brand","model","quantity","unitPrice","lineTotal","warrantyYears"],"additionalProperties":false}}},"required":["reference","total","currency","system","items"],"additionalProperties":false}},"required":["id","reference","status","installer","city","region","quote"],"additionalProperties":false},{"type":"null"}]},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string"},"fileName":{"type":"string"},"url":{"type":"string","description":"Download path; needs a signed-in session that may see the file"}},"required":["id","kind","fileName","url"],"additionalProperties":false}},"sensitive":{"anyOf":[{"type":"object","properties":{"idType":{"type":"string"},"idNumber":{"type":"string"},"bankName":{"type":"string"},"accountNumber":{"type":"string"},"guarantor":{"anyOf":[{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"relationship":{"type":"string"}},"required":["name"],"additionalProperties":false},{"type":"null"}]}},"required":["idType","idNumber","bankName","accountNumber","guarantor"],"additionalProperties":false},{"type":"null"}],"description":"Only with ?reveal=true"}},"required":["id","reference","status","customerName","product","projectReference","systemKw","systemCost","depositAmount","amountRequested","termMonths","currency","submittedAt","decidedAt","updatedAt","consent","customer","applicant","infoRequest","decisionNotes","offers","agreement","project","documents","sensitive"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/admin/kpis":{"get":{"operationId":"kpis","summary":"Marketplace KPIs","tags":["Staff"],"security":[{"session":[]}],"x-roles":["ADMIN","SUPER_ADMIN"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"customers":{"type":"number"},"verifiedInstallers":{"type":"number"},"quoteRequests":{"type":"number"},"quoteRequests30":{"type":"number"},"conversionRate":{"type":"number"},"projectValueByCurrency":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"amount":{"type":"number"}},"required":["currency","amount"],"additionalProperties":false}},"totalProjectValue":{"type":"number"},"completedInstallations":{"type":"number"},"capacityKw":{"type":"number"},"storageKwh":{"type":"number"},"financedProjects":{"type":"number"},"revenueByCurrency":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"amount":{"type":"number"}},"required":["currency","amount"],"additionalProperties":false}},"queues":{"type":"object","properties":{"pendingInstallers":{"type":"number"},"pendingProducts":{"type":"number"},"openDisputes":{"type":"number"},"qcQueue":{"type":"number"},"releasesAwaiting":{"type":"number"},"openRisk":{"type":"number"}},"required":["pendingInstallers","pendingProducts","openDisputes","qcQueue","releasesAwaiting","openRisk"],"additionalProperties":false}},"required":["customers","verifiedInstallers","quoteRequests","quoteRequests30","conversionRate","projectValueByCurrency","totalProjectValue","completedInstallations","capacityKw","storageKwh","financedProjects","revenueByCurrency","queues"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/monitoring/devices":{"post":{"operationId":"registerDevice","summary":"Register a monitoring device on a Solar Passport","description":"For the system's owner, its installer (session or monitoring:write key) or staff. Returns the device token once; registering the same provider and externalId again rotates it.","tags":["Monitoring"],"security":[{"session":[]},{"apiKey":["monitoring:write"]}],"x-roles":["CUSTOMER","INSTALLER","TECHNICIAN","ADMIN","SUPER_ADMIN"],"x-api-key-scopes":["monitoring:write"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{1,39}$"},"externalId":{"type":"string","minLength":1,"maxLength":120},"displayName":{"type":"string","minLength":2,"maxLength":80},"passportId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["provider","externalId","displayName","passportId"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"device":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"passportId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"provider":{"type":"string"},"externalId":{"type":"string"},"displayName":{"type":"string"},"status":{"type":"string"},"lastSeenAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["id","passportId","provider","externalId","displayName","status","lastSeenAt"],"additionalProperties":false},"token":{"type":"string","description":"Shown once. Send it as `Authorization: Device <token>` with readings."},"rotated":{"type":"boolean","description":"true when an existing registration got a new token; the old one stopped working"}},"required":["device","token","rotated"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/monitoring/readings":{"post":{"operationId":"readings","summary":"Push readings from a device","description":"Authenticate with `Authorization: Device <token>`. Up to 500 readings per call; a reading for a time already stored is counted as a duplicate, so retries are safe. Power in W (gridPowerW + import / − export; batteryPowerW + charging / − discharging), batterySocPct 0–100.","tags":["Monitoring"],"security":[{"device":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"readings":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"recordedAt":{"type":"string","format":"date-time"},"pvPowerW":{"type":"number","minimum":0,"maximum":2000000},"loadPowerW":{"type":"number","minimum":0,"maximum":2000000},"gridPowerW":{"type":"number","minimum":-2000000,"maximum":2000000},"batteryPowerW":{"type":"number","minimum":-2000000,"maximum":2000000},"batterySocPct":{"type":"number","minimum":0,"maximum":100},"pvEnergyTodayWh":{"type":"number","minimum":0,"maximum":100000000},"statusCode":{"type":"string","maxLength":40}},"required":["recordedAt"]}}},"required":["readings"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deviceId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"accepted":{"type":"number"},"duplicates":{"type":"number","description":"Readings already stored for the same device and time"},"rejected":{"type":"array","items":{"type":"object","properties":{"index":{"type":"number"},"reason":{"type":"string"}},"required":["index","reason"],"additionalProperties":false}}},"required":["deviceId","accepted","duplicates","rejected"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Malformed request (for example invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Not authenticated, or the key or token is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Authenticated but not allowed (role, scope or cross-site request)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found, or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicts with the record's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"sb.session_token","description":"Better Auth session cookie from signing in on the website (__Secure- prefixed in production). Non-GET requests must send a same-origin Origin header."},"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"jl_live_<prefix>_<secret>","description":"Organisation API key. Scopes: financing:read, financing:write, projects:read, projects:write, monitoring:write, catalog:write."},"device":{"type":"apiKey","in":"header","name":"Authorization","description":"Monitoring device token as `Device <token>`."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code, e.g. not_found, validation_failed, rate_limited"},"message":{"type":"string","description":"Plain-language explanation you can show to people"},"fields":{"description":"Per-field messages for validation errors, keyed by field path","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}},"x-sizing-engine":"sizing-2026.09"}