{"$id":"https://solaranalytica.com/projection-lens/schema.json","title":"Solar Analytica Projection Lens payload","description":"What one kilowatt in each lens market is projected to earn over the horizon, as a conditional planning range with every input pinned by hash. Not a probability, a forecast of returns or advice.","$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"schemaVersion":{"type":"string","const":"projection-lens-payload-v1"},"methodVersion":{"type":"string","const":"projection-lens-v1"},"frameworkVersion":{"type":"string","const":"projective-layers-v1"},"generatedAt":{"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))$"},"serving":{"type":"string","enum":["Stored edition","Published snapshot"],"description":"Where the editions were served from: the edition store the daily job writes, or the committed snapshot. It does not mean any number follows live grid conditions; none does."},"status":{"type":"string","enum":["published","store-unavailable"]},"homepage":{"type":"string","format":"uri"},"license":{"type":"string","minLength":1},"claimBoundary":{"minItems":4,"maxItems":4,"type":"array","items":{"type":"string","minLength":1}},"earthBaseline":{"type":"object","properties":{"edition":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"methodVersion":{"type":"string","minLength":1},"windows":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["edition","methodVersion","windows"],"additionalProperties":false},"markets":{"type":"array","items":{"type":"object","properties":{"servedFrom":{"description":"Where this edition was served from. The payload's serving label says Stored edition once any market comes from the store, so this is the per-market answer: a snapshot edition carries no recorded test.","type":"string","enum":["store","snapshot"]},"schemaVersion":{"type":"string","const":"projection-lens-payload-v1"},"methodVersion":{"type":"string","const":"projection-lens-v1"},"frameworkVersion":{"type":"string","const":"projective-layers-v1"},"forecastFamily":{"type":"string","const":"projection-lens"},"forecastKey":{"type":"string","minLength":1},"lensKey":{"type":"string","minLength":1},"marketCode":{"type":"string","minLength":1},"system":{"type":"string","enum":["swis","nem","gb","us","eu"]},"zoneCode":{"type":"string","minLength":1},"currency":{"type":"string","enum":["AUD","GBP","USD","EUR"]},"editionVersion":{"type":"string","minLength":1},"publishedOn":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"baselinePeriod":{"type":"string","minLength":1},"horizonPeriods":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"status":{"type":"string","enum":["current","superseded","withdrawn"]},"supersedesEditionVersion":{"type":["string","null"]},"envelope":{"type":"object","properties":{"technology":{"type":"string","enum":["perc","topcon","hjt"]},"metrics":{"minItems":4,"maxItems":4,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["specific-yield-kwh-kwp","energy-value-usd-kwp-yr","lcoe-usd-kwh","simple-payback-years"]},"title":{"type":"string","minLength":1},"unit":{"type":"string","minLength":1},"decimals":{"type":"integer","minimum":0,"maximum":9007199254740991},"direction":{"type":"string","enum":["higher_is_better","lower_is_better"]},"baseline":{"type":["number","null"]},"lower":{"type":["number","null"]},"reference":{"type":["number","null"]},"upper":{"type":["number","null"]},"baselineCase":{"type":"string","minLength":1},"lowerCase":{"type":"string","minLength":1},"referenceCase":{"type":"string","minLength":1},"upperCase":{"type":"string","minLength":1}},"required":["key","title","unit","decimals","direction","baseline","lower","reference","upper","baselineCase","lowerCase","referenceCase","upperCase"],"additionalProperties":false}},"constraintExposure":{"type":"object","properties":{"regimeKind":{"type":"string"},"exposure":{"type":"number","minimum":0,"maximum":1}},"required":["regimeKind","exposure"],"additionalProperties":false},"priceCase":{"type":"string","minLength":1},"market":{"type":["string","null"]},"yieldPath":{"type":"array","items":{"type":"object","properties":{"year":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"yieldKwhKwp":{"type":"number"}},"required":["year","yieldKwhKwp"],"additionalProperties":false}},"yieldPathCase":{"type":"string","minLength":1}},"required":["technology","metrics","constraintExposure","priceCase","market","yieldPath","yieldPathCase"],"additionalProperties":false},"triggers":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"label":{"type":"string","minLength":1},"metric":{"type":"string","minLength":1},"comparator":{"type":"string","enum":["gt","lt","gte","lte","abs_delta_gt","abs_delta_pct_gt","outside_range"]},"threshold":{"type":"number"},"thresholdUpper":{"type":["number","null"]},"windowDays":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"appliesTo":{"type":"array","items":{"type":"string"}},"cadence":{"type":"string","minLength":1},"source":{"type":"string","minLength":1}},"required":["key","label","metric","comparator","threshold","windowDays","cadence","source"],"additionalProperties":false}},"triggerState":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"label":{"type":"string","minLength":1},"metric":{"type":"string","minLength":1},"comparator":{"type":"string","minLength":1},"threshold":{"type":"number"},"thresholdUpper":{"type":["number","null"]},"windowDays":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"cadence":{"type":"string","minLength":1},"evaluatedOn":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The date of the daily job's latest recorded test of this trigger on this edition, when served from the store. Null in the published snapshot, which declares triggers without testing them, and null when no test is recorded yet."},"evaluable":{"type":"boolean","description":"Whether the latest recorded test could be made. False when no test is recorded; see notEvaluableReason when a test was recorded but could not be made."},"observed":{"description":"The live grid record's value over the tested window, from the latest recorded test. A trigger test value, not an edition figure; null when no test is recorded or none could be made.","type":["number","null"]},"pinned":{"description":"The reference the trigger is judged against: the live grid record's value when the daily job first wrote this edition. Null when no test is recorded.","type":["number","null"]},"crossed":{"type":"boolean","description":"Meaningful only when evaluatedOn is set and evaluable is true."},"windowStart":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First operating day in the tested window of the live grid record; null when no test is recorded."},"windowEnd":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last operating day in the tested window of the live grid record; null when no test is recorded."},"windowRows":{"description":"How many operating days the tested window held, which can be fewer than windowDays when an ingest lags.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"notEvaluableReason":{"description":"Why the latest recorded test could not be made, when it could not.","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"openReviewId":{"description":"Set when the edition is served from the store and a review opened by a crossed trigger is still open on this market, on this edition or one it superseded.","type":["string","null"]},"openReviewOpenedOn":{"description":"When that open review was opened.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"openReviewWindowEnd":{"description":"The last operating day of the window whose test opened that review.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"openReviewEditionVersion":{"description":"The superseded edition the open review sits on; null when it sits on this edition.","type":["string","null"]}},"required":["key","label","metric","comparator","threshold","thresholdUpper","windowDays","cadence","evaluatedOn","evaluable","observed","pinned","crossed","windowStart","windowEnd"],"additionalProperties":false}},"pins":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"ref":{"type":"string","minLength":1},"vintage":{"type":["string","null"]},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"absent":{"description":"Why this input carries no value: either the market has no such input, or, for gridWindow, no published edition uses it by rule.","type":"string","minLength":1}},"required":["ref","vintage","sha256"],"additionalProperties":false}},"pinsSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"editionPinsSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"editionSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"vintageStamps":{"type":"object","properties":{"earthBaselineVerifiedOn":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"earthBaselineEdition":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"earthBaselineMethod":{"type":"string","minLength":1},"gridWindowStart":{"type":"null","description":"Always null: the live grid record is used only to test the review triggers and never moves a published range (decided 2026-09-23)."},"gridWindowEnd":{"type":"null","description":"Always null: the live grid record is used only to test the review triggers and never moves a published range (decided 2026-09-23)."},"gridWindowRows":{"type":"number","const":0,"description":"Always 0: the live grid record is used only to test the review triggers and never moves a published range (decided 2026-09-23)."},"retailPriceYear":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"retailPriceMatch":{"type":"string","enum":["city","country_avg","none"]},"tariffEdition":{"type":["string","null"]}},"required":["earthBaselineVerifiedOn","earthBaselineEdition","earthBaselineMethod","gridWindowStart","gridWindowEnd","gridWindowRows","retailPriceYear","retailPriceMatch","tariffEdition"],"additionalProperties":false},"boundaries":{"minItems":4,"type":"array","items":{"type":"string","minLength":1}}},"required":["schemaVersion","methodVersion","frameworkVersion","forecastFamily","forecastKey","lensKey","marketCode","system","zoneCode","currency","editionVersion","publishedOn","baselinePeriod","horizonPeriods","status","supersedesEditionVersion","envelope","triggers","triggerState","pins","pinsSha256","editionPinsSha256","editionSha256","vintageStamps","boundaries"],"additionalProperties":false}}},"required":["schemaVersion","methodVersion","frameworkVersion","generatedAt","serving","status","homepage","license","claimBoundary","earthBaseline","markets"],"additionalProperties":false}