Docs: The statement payload

The statement payload

A statement.available body is one statement: an envelope of identifiers, the statement's own fields, and its meters, sections and charges. Charges hang off sections, and a section or charge may point at a meter.

Envelope

Field Type Notes
schema_version string Contract version, for example 1.0.0
statement_id string stt_…. Stable across re-extractions of the same bill
version_id string ver_…. One extraction of this statement
is_latest boolean True when sent: a version is current when it is delivered. A version you hold is superseded when a newer one arrives
superseded_by string or null Reserved. Null when sent; a later version does not update one you already hold
parent_statement_id string On a child of a summary bill only: the parent's statement_id
request_id string The request that delivered this version
client_reference string Echoed from your request, when you sent one
document_id string doc_…. The same for every statement from one file, and stable across re-extractions
extracted_at string UTC timestamp, ISO 8601. The number of fractional-second digits varies (none, 3, 6 or 9), so compare it as a time, never as a string. Statements from one extraction share it
statement object The statement's own fields, below
meters, sections, charges arrays Below
children object On a summary parent only. See Summary bills
reconciliation object The arithmetic, checked. See below
confidence object Checkable signals and a tier. See below
issuer null Reserved; currently always null

connection_id and account_id are sent on statements retrieved through a connection (see Connecting a portal), and are absent on uploaded bills. provider appears in some samples but is not yet sent; it will be added in a minor version, so do not require it.

Values carry their printed form and their source

Money, quantities, dates and identifiers are objects, not bare values:

"amount_due": { "amount": 55.7, "as_printed": "55.70", "source": "extracted" }
"usage":      { "value": 3, "unit": "thousand gallons", "as_printed": "3", "source": "extracted" }
"due_date":   { "value": "2026-09-09", "as_printed": "9/9/2026", "source": "extracted" }

Amounts are numbers in the bill's currency, credits negative. Dates are YYYY-MM-DD. as_printed is the text on the bill, so you can always check a value against the document.

source Meaning
extracted Read directly from the bill
derived Calculated from other printed values, for example a period start from the end date and the day count
inferred Not printed; concluded from context
defaulted Not on the bill at all; a stated default, such as a total of 0.00 for a bill that prints no late fee

statement

statement_date, due_date, period_start, period_end and account_number are value objects. totals holds amount_due, current_charges, previous_balance, balance_forward, late_fee, payments, credits and adjustments as money objects, each present when the bill prints or implies it. Also currency, service_address, is_summary, and location_id when the bill prints an identifier for the service location separate from the account number. statement_date and totals are always present.

Identifiers carry one more field. account_number, location_id and each meters[].number add normalized: the value's letters and digits only, in upper case. Luminetric computes it from value; the model never writes it. The same printed number always gives the same normalized, however the bill punctuates it, so 10-00001-00001 and 10 00001 00001 both give 100000100001. Leading zeros are kept.

"account_number": { "value": "10-00001-00001", "as_printed": "10-00001-00001", "source": "extracted", "normalized": "100000100001" }

Key accounts, locations and meters on normalized, and show value or as_printed to people. Where a provider issues one account for several locations, the account and location together identify a place: key on both normalized values. normalized is absent only when the identifier itself is.

meters, sections and charges

  • meters[] — meter_id (local to this statement), number (the meter number as printed), service, service_address, previous_read and current_read, multiplier, read_start and read_end dates, and usage as a quantity object with its unit.
  • sections[] — each block of charges as the bill prints it: section_id, heading_as_printed, service, service_source (how the service was decided), ordinal, optional meter_id, and printed_total when the bill prints a subtotal.
  • charges[] — each line: name_as_printed, section_id, service, kind, amount, contributes_to_total and service_source, plus quantity, rate, meter_id, period_start and period_end when the bill gives them.

contributes_to_total is true for charges that make up current_charges. Payments, prior balances and printed subtotals are false, so summing the true rows reproduces the bill's current charges.

Enum Values
service electric, gas, water, sewer, irrigation, stormwater, drainage, trash, fire, steam, chilled_water, internet, phone, tv, none, other, unknown
kind supply, delivery, tax, fee, credit, adjustment, subtotal, other, unknown
charges[].service_source section, item_text, meter, summary_row, single_service_bill, convention, inferred, none
sections[].service_source heading, summary_row, item_text, meter, single_service_bill, inferred, none

other means classified but not in the list. unknown means the bill gave nothing to classify it from, and is never a guess. none on service marks a line that belongs to no service, such as a payment or a bill-level late fee.

reconciliation

We check the arithmetic and report it. We never adjust a value to make it balance.

"reconciliation": {
  "identity": "sum(charges where contributes_to_total) == statement.totals.current_charges",
  "current_charges": 85.7, "sum_of_charges": 85.7, "delta": 0.0, "balanced": true,
  "total_due": 55.7,
  "total_due_identity": "previous_balance + payments + adjustments + current_charges",
  "total_due_delta": 30.0, "total_due_balanced": false
}

balanced concerns the current charges and is the one to rely on. total_due_balanced is often false on a correct bill, because many bills print the balance forward differently, as in this example where a $30.00 credit is carried outside the printed identity.

confidence

"confidence": { "tier": "deliver", "reconciles": true, "key_totals_extracted": true,
                "unknown_service_charge_count": 0, "signals_failed": [] }

Three signals, each one you can recompute from the payload: the charges reconcile, amount_due and current_charges were both read from the bill rather than derived, and no charge has an unknown service. tier is deliver when all three hold, and review when any fails, with the failures named in signals_failed.

review does not mean wrong. It means one of the checks could not confirm the statement, and it tells you which. A sensible policy is to load deliver statements automatically and route review statements to a person, or to automatic use only where the failed signal does not matter to you. Treat an unrecognized tier as review.