Schema

Everything the federal Home Energy Rebates API asks for, and Focus's answer to the question the API never asks: who actually fills each value in — which changes with the job.

213
questions
26
payloads they come from
32
published diagrams
2
settled by a person
How these are counted

A placement is one property occurrence inside one payload. A field is one row per distinct question: the same property in the same position is one row however many payloads carry it, and the key names the schema that defines it most fully. Where PNNL writes a field out inline in several payloads rather than referring to one definition, those copies collapse -- 404 declarations across the 26 payloads are 213 questions.

That collapse is the fix for a real problem rather than a tidying-up. PNNL writes most fields out inline in every payload that carries them instead of referring to one definition, so the previous build showed 404 rows holding only 213 distinct questions: max_amps was asked six times and annual_consumption fourteen. Where the same name genuinely means two things the path still separates them — the panel you started with and the one you fitted are two rows, not one.

The labelling, and what is ours

You asked for a first pass at this. Here is what it is and where each part comes from, so you can disagree with a whole class at once rather than cell by cell.

1 · Who fills it in

Nine parties, and there is nothing else, because these are the swimlane columns DOE prints on the workflow diagrams under the rule “Columns indicate the entity performing the task described.” The previous fifteen included parties nobody had drawn.

Tenant 0 DOE swimlane “Tenant”, drawn on the ten tenant-occupied and multifamily diagrams. PNNL `electric_claimant_type` value TENANT.
Building owner 0 DOE swimlane “Building Owner”, drawn on fourteen of the sixteen; on the two do-it-yourself diagrams DOE moves it into the Claimant column. PNNL `claimant_type` value MULTIFAMILY_BUILDING_OWNER.
Installer 1 DOE swimlane “Installer”, and the Claimant column header names it on twelve diagrams. PNNL `installation_type` value CONTRACTOR_INSTALLED. Focus calls them trade allies.
Aggregator 0 Named inside the Claimant column header on all sixteen diagrams. PNNL `homes_claimant_type` value AGGREGATOR.
Eligible entity representative 0 Named inside the Claimant column header on the ten 50122 diagrams as “Eligible Entity Representative (EER)”. Not on the 50121 ones.
Vendor 0 DOE swimlane “Vendor”, drawn on all sixteen — including the post-purchase ones, where there is no coupon but there is still somebody selling the equipment. PNNL `vendor_id`, `vendor_coupon_id`.
State administrator 1 DOE swimlane “State or Territory” on the 50121 diagrams and “State, Territory, or Tribe” on the 50122 ones. Every PNNL `state_attests_*` and `jurisdiction_attests_*` field is signed here.
Program implementer 0 DOE swimlane “Program Implementation”, printed “Program Back End” on workflows 1, 2 and 3.
DOE API 0 DOE swimlane “DOE API” — the federal endpoint itself.

Left out on purpose:
Claimant — DOE's Claimant column is a *slot*, not a party: it is headed “Installer or Aggregator” on HOMES, “Installer, Aggregator, EER” on non-DIY HEEHR, and “Building Owner, Aggregator, EER” on the two do-it-yourself diagrams. Recording “claimant” as the answer would hide the very difference this page exists to show. It is a role slot instead, resolved per workflow.
Customer / participant — Not a lane. DOE draws Tenant and Building Owner; which of them is the participant is what the workflow decides. Collapsing them into “customer” throws that away.
Housing authority, support contractor, installation entity — Focus vocabulary from ticket #6, not federal. None appears on any diagram or in any PNNL enum, and the previous build never once used them as an answer. They belong on Focus's own intake mapping in #6, not on the federal schema.
Payee, submitter, inspector — Who is paid and who presses send are fields (`claimant_type`, `total_rebate_payout`), not separate people. Whoever submits is one of the nine above wearing a hat.

2 · Where the value comes from

A separate axis, because “the system” is not a person who fills a form in — that was the wrong shape as well as too broad. This one says whether there is a human in it at all.

Typed by a person Somebody enters this. It needs a field on a screen. Needs a field on a screen.
Calculated Worked out from other values. Nobody types it.
Minted identifier Issued by the API or the state, and quoted back afterwards.
Read off the product or catalogue Copied from the equipment or its listing — a person still reads it. Needs a field on a screen.
Returned by DOE Comes back from the federal API rather than being sent to it.
3 · Stage of the job

The grouping in the ticket was DOE's “Data Category” column from the Data & Tools Requirements Guide. That guide is not in PNNL's repo and its published link 404s, and half the fields matched none of its ten names — 109 of 213 are still Unclassified against it. A grouping that cannot place most of what it groups is not doing its job, so there is a second one derived from the API's own endpoints. Every field belongs to a payload, so nothing can fall outside it.

Address The address service call that resolves a property to an `address_id`.
Applicant & household Identifying the household the rebate is for.
Eligibility check Asking the API what this household and property qualify for.
Limited home assessment The contractor's site visit and its readings.
Reservation Reserving rebate money against a proposed scope of work.
Redemption Claiming the money once the work is done or the product is bought.
Files & evidence Photos, HPXML, signed documents uploaded against a project.
State addenda Fields a state adds for its own programme.
Corrections & deletions Undoing or amending something already sent.
Bulk reporting The spreadsheet route: the same data reported in arrears.
Measure detail The 16 per-measure schemas -- what was there before, what went in.

DOE's categories are still on every field and still honestly labelled unconfirmed. Re-obtaining the guide at v2.0 and checking the ten names against it is real work that is still outstanding.

A grouping DOE uses that we have not adopted

Every one of the seven wireframes carries the same key in its margin, marking each data element as one of: Identifier, Requirement, Best Practice, Report to DOE, State Retain, State Collect. That is DOE's own classification and it is a real candidate for the way this page groups fields — but the marks sit on the drawings rather than in the schema, so adopting it means reading 137 screens by hand. Flagged rather than half-done: say the word and it becomes the fourth axis.

4 · Components, and 5 · your own labels

Components are the things Focus will build; they live in the database because the full list is not known yet, and you can add, rename and retire them. Labels are free-form buckets of your own — nothing in the app reads one, so there is no way to make a wrong one.

How far it has got

Nothing proposed211
Settled by a person2

The first pass is computed on every read rather than stored, so correcting a rule moves a whole class of fields at once and the database holds only what a person actually decided. That is also what makes “a re-import never overwrites your answer” true by construction.

Where this came from

  • The schema. https://github.com/pnnl/IRA-Rebates-API, branch prod-sandbox, pinned at 808c404 (2026-09-01T09:54:56-07:00). Structure, types and enums from resolved_json_schemas/; the 97 error_msg sentences, the readOnly flags and the $comments only exist in json_schemas/, so both are read.
  • The workflow diagrams. https://www.pnnl.gov/projects/rebate-tools/program-implementation — all 32, and the source of the swimlanes, the printed subtitles and each workflow's cast.
  • DOE's own portal wireframes. Seven of them, published on the same page as the diagrams: an Owner, a Tenant and a Contractor interface for each statute, plus a Retailer one for 50122. They draw the screens each party sees, which makes them the only published statement of who types a field — and they answer it outright for 46 of the 213. Where one exists it leads the first pass and says so on the field.
  • The human-readable schema. https://pnnl.github.io/IRA-Rebates-API/
  • Not obtained. Data & Tools Guide v1.2 (PNNL); DOE has published v2.0 dated 2025-01-07. The link in PNNL's README 404s.
Dated caveat

All 32 workflow diagrams predate Program Notices 26-1, 26-2 and 26-3, effective 29 May 2026, which say the API's data elements are being revised. PNNL tracks Data & Tools Guide v1.2; DOE has published v2.0, dated 2025-01-07. This page mirrors what PNNL publishes today. It does not assert Focus's reading of what those notices changed.

Evidence formats

HPXML and BuildingSync are attached documents, not fields — 1,178 XML element names against 213 real questions, and no portal user types them. They arrive through binary_file_content_base_64, file_name, file_type, file_purpose. These are uploaded documents validated separately against XSD and Schematron, not fields anyone fills in. They enter through the files endpoints as the four fields above.

Payloads with no live endpoint

electricEligibleRebatesPayload, homesEligibleRebatesPayload, tribesElectricBulkReportingPayload. Shown and flagged rather than hidden — an absent payload reads as an oversight. The Tribes payload is additionally not applicable to Focus.

Source and licence

PNNL's IRA-Rebates-API is published under BSD-2-Clause. Redistribution in source form must retain the copyright notice, this list of conditions and the disclaimer; redistribution in binary form must reproduce them in the documentation or other materials supplied with the distribution. Battelle Memorial Institute disclaims all warranties and accepts no liability. This page is not endorsed by, nor affiliated with, DOE or PNNL. It is Focus on Energy's own reading of a published schema.

Not built here

The trade-ally portal, the household portal, the app-wide sign-in, and Focus-specific fields the federal API does not ask for. This is a view of PNNL's schema plus Focus's answers about it. The address ambiguity is #2, site-wide sign-in is #4, the CDN risk is #7, and Focus's own intake forms are #6.