Find the floor your electric bill charges you for
A commercial demand charge is not your meter's peak. It is the greater of this month's peak, a percentage of the highest peak in the trailing months, and a contract minimum — and one hot afternoon sets that floor for a year. RatchetProof rebuilds the number from your interval data and the filed tariff, then prices the carry-over. A clause it cannot read blocks the month; nothing is defaulted to 0%.
Billed = max(month peak, ratchet % × the highest peak in the lookback, contract minimum). The schematic's figures are the worked example; the report computes yours from the files you supply.
Audit the billed demand
Load a worked example or drop in your own export. The engine sums coincident meter intervals, applies the tariff's window and ratchet, and prices the gap between what the meter reached and what the bill charged.
Four months of two-meter interval data, a 75% ratchet over a three-month lookback, and a 1,400 kW Saturday spike the tariff does not bill.
Nothing is audited until you run it. The worked example is a four-month, two-meter set: a 1,000 kW January peak, a 1,400 kW Saturday spike the tariff does not bill, and a 75% ratchet over a three-month lookback.
What this build does — and what it deliberately does not
v1 implements the demand clause: coincident peaks across meters, the tariff's billed window, the ratchet lookback, the contract minimum, and the carry-over dollars. Every figure is computed in this deterministic engine; a document reader may only fill declared fields.
rp-interval-gap · rp-interval-count-mismatch · rp-interval-granularity-mixed · rp-interval-misaligned · rp-interval-overlap · rp-interval-coverage-gap · rp-history-window · rp-tariff-unstated · rp-tariff-unreadable · rp-tariff-invalid · rp-tariff-interval-mismatch · rp-bill-unstated · rp-rate-missing · rp-billed-variance · rp-billed-rounding
- Sales-tax, rider and surcharge lines (the audit prices demand only)
- Utility API / Green Button Connect OAuth data pulls (file upload only)
- Weather or satellite normalisation of a peak
- Portfolio roll-up across sites (one site per audit in v1)
- Time-of-use energy charges (this engine audits billed demand)
Watch the launch video
24s · nothing estimated · no signupRatchetProof: one hot interval sets your electric bill for months Watch on YouTube
Four stages, one deterministic chain
- Coincident peakEvery meter aligned onto one grid and summed per interval. Two meters peaking at different times never add up to a site peak that did not happen — and Σ intervals read must equal Σ intervals declared, or the file is refused.
- Billed windowOnly the days and hours the tariff bills are searched. A Saturday spike that would set a record sets nothing on Monday–Friday 08:00–20:00.
- The ratchetbilled = max(month peak, ratchet % × the highest peak in the lookback, contract minimum). The lookback is an explicit ordered history, so a missing month blocks the verdict instead of shortening the window.
- Carry-over(billed − metered) × the month's demand rate, summed across the months the floor bound — plus what shaving the single interval that set the floor would have saved.
Printed demand is rounded on the bill: a difference of 1 kW or less is reported as printing noise, and anything larger is an unmatched variance against the tariff. The audit never re-prices the rate — it reads the rate the bill prints (or the one the tariff declares for the month's voltage class).
Agent Surface & WebMCP Integration
How an energy agent invokes the billed-demand audit. The extraction layer reads declared fields; the audit itself is this deterministic engine.
// 1. In any browser with WebMCP support (auto-registered on page load):const audit = await navigator.modelContext.executeTool("audit_demand_billing", { interval: intervalExportText, // meter_id,interval_start_utc,kw (CSV or Green Button XML) tariff: tariffDeclaration, // the declared clause set (JSON) or the tariff's document text bills: billsCsv, // month,period_start,period_end,printed_billed_demand_kw,... seed_history: [ // prior months' peaks, most recent first (the standing ratchet history) { month: "2025-12", peak_kw: 950 }, { month: "2025-11", peak_kw: 850 }, { month: "2025-10", peak_kw: 900 } ]}); console.log("Verdict:", audit.report.verdict); // "complete" | "blocked"console.log("Carry-over:", audit.report.carryOverMicroUsd / 1e6);console.log("Blocked months:", audit.report.months.filter(m => m.blocked).map(m => m.month));JSON Schema Parameters Contract
intervalRequiredThe meter export as CSV (meter_id,interval_start_utc,kw), a wide export, or Green Button XML. Mixed 15/30-minute granularity and any gap are refused, never interpolated.
tariffRequiredThe declared tariff clause set as JSON, or the tariff's document text for the extraction path. Every field carries value + provenance; a clause that is not extracted blocks the month.
billsRequiredThe bills as CSV (month,period_start,period_end,printed_billed_demand_kw,printed_demand_rate_usd_per_kw) or the bill document text. The printed figure is the evidence — it is never derived from the tariff.
seed_historyOptionalPrior months' peaks as [{ month, peak_kw }], most recent first, ending at the month before the interval data begins. A short or gapped history blocks the month it cannot price.
Pricing
Use it free in the browser. Pay only for exports, the suite, or agent calls.
Free
$9.00 one-off
$29.00/month
| Agent tool | Metered rate |
|---|---|
audit_demand_billing | $1.50 per successful call |
Agent calls are metered per successful call and billed monthly to your Stripe customer. Billing shows your usage, history and spend cap.
Manage Billing & API Keys (/billing) →Agent surface: audit_demand_billing is registered as a WebMCP tool and advertised in /.well-known/mcp.json at $1.50 per successful call. The extraction layer it needs must be configured in the deploy environment first — until then the tool answers with an explicit unconfigured error naming the missing variable, never an estimated tariff.