PUBLIC
Use it: authenergy.github.io/agile-compareSource: github.com/AuthEnergy/agile-compare
Why we built this
Tariff comparison tools generally apply today’s rates retrospectively, which is misleading for any tariff that changes frequently. Agile Octopus reprices every half hour; applying its current rate to a year of historical consumption produces a number with no real relationship to what a customer would actually have paid. We wanted a comparison that uses the rate that was genuinely in force at each half-hour interval, calculated against a customer’s real billing periods rather than arbitrary calendar months. This space owes a real debt to Guy Lipman’s collection of Octopus API tools — particularly bill_agile.html, which reconciles an Agile bill to the penny, and price_comparison.html, which compares paid vs alternative for a given month. We built on that foundation to combine the gap check, bill reconciliation, and cross-tariff comparison in one flow; cover a full year of history rather than month by month; derive the comparison window automatically from real billing statements rather than requiring dates to be supplied; and include Flexible, since the question we most often hear isn’t “what would Agile have cost” but “would switching to Agile actually save me money.” This sits alongside our published work on tariff data interoperability: a customer being able to retrieve their own consumption and billing history, and compare it accurately against alternative tariffs, is a basic capability the market should support natively. Building a working example against Octopus’s public API is one way of demonstrating what that looks like in practice.What it does
The tool runs entirely in the user’s browser. The only input required is an Octopus API key — the tool discovers the account number, meters, MPANs, and meter serials automatically. If multiple meters are found, a picker lets the user choose which to compare. For the selected meter, it:- Confirms the meter’s region and reads the account’s full agreement history, including all past and present tariff codes. The account data is fetched once during the initial API key verification and reused throughout.
- Fetches the account’s real billing statements. Where individual transaction line items are available, the electricity charge is read directly from those — filtering to “Electricity” charges only, so that gas charges on dual-fuel accounts are never included, and distinguishing import from export by sign so export earnings do not inflate the paid figure. Where only statement totals are available, the gross total is used as a fallback. Credits (referral payments, goodwill credits, account adjustments) are tracked separately and displayed alongside the comparison, not netted into the electricity charge.
- Derives the comparison window from the real statement dates, so billing periods are never partially cut off. The window extends to approximately seven days ago to include recent usage that has not yet been billed, capped at thirteen months back.
- Pulls half-hourly consumption across all meter serials for the selected MPAN and deduplicates overlapping readings where serial replacement or multi-serial accounts have produced duplicate slots.
- Checks the consumption data for gaps, flags any it finds, and estimates the missing consumption per gap using a median half-hourly profile built from surrounding readings.
- Detects billing periods where the billed kWh and observed half-hourly kWh diverge significantly, or where the implied unit rate is implausible (for example, a short bridging statement generated at a tariff switch point). Affected periods are flagged and excluded from summary totals.
- Fetches the real historical unit rates and standing charges for the user’s current tariff, Flexible Octopus, and Agile Octopus across the same window. The current-tariff fetch works as follows:
- Flexible Octopus users: Flexible rates are the current tariff, so no separate fetch is needed.
- Agile Octopus users: the comparison is Agile vs Flexible by design — the tool shows what the user paid on Agile and what Flexible would have cost.
- All other tariffs (Go, Fixed, Tracker, Cosy, Intelligent Go, and others): the tool fetches
standard-unit-ratesdirectly from the user’s own tariff code. It then silently probesnight-unit-rates; if that endpoint returns data the tariff is time-of-use (Go-style), and the day and night windows are merged into correct half-hourly coverage. If it returns nothing, the tariff is treated as flat-rate. - Fallback: if the tariff’s rates are not available via the Octopus API — because the product has been retired, the endpoint does not exist, or the rate fetch fails — Flexible Octopus is used as a proxy for that tariff’s column. The results screen shows a callout explaining this whenever the fallback is active.
- Calculates what each billing period would have cost under each tariff — correctly splitting any period that spans a rate change — and displays it next to what the customer actually paid.
- Where a customer has switched tariff during the window, pre-switch periods are dimmed and labelled; summary totals are restricted to on-current-tariff periods only, so the comparison is not distorted by mixing bills from different tariffs.
Diagnostics
The results screen includes a “Download diagnostics” button. This produces a structured JSON file containing everything needed to investigate a calculation discrepancy:- Comparison window and region: the date range used and the DNO region letter.
- Agreement history: all tariff codes with their start and end dates.
- Flex column source: which tariff the comparison column actually used (the user’s real tariff rates, a Flexible proxy, or Flexible as the comparison target for Agile users) and why.
- Readings: all half-hourly consumption slots, plus total count, date range, and total kWh.
- Gap analysis: gap date ranges, total missing slot count, and per-gap estimated missing kWh.
- Products and tariff codes: the Flexible and Agile product and tariff codes discovered for the window.
- Rate windows: summary (count, date span, value range, any gaps between windows) and full raw arrays for flex and Agile unit rates and standing charges.
- Billing periods: for each period — kWh, actual paid, calculated cost under each tariff (energy and standing charge separately), unmatched reading count, and flags for pre-switch, mixed-tariff, suspect, and clamped.
- Statement validation: per-statement billed vs observed kWh, mismatch flag, and individual charge line items with titles, kWh, and amounts.
- Totals: unmatched reading and standing-charge-day counts across all periods; consistent-only subtotals (the filtered set that drives the summary cards).
hello@auth.energy or attached to a GitHub issue to diagnose a problem without sharing anything identifiable.
During development, the diagnostic file was used to identify two real issues that would otherwise have been invisible: a tariff switch creating a short bridging statement with an implied unit rate of 462p/kWh (now correctly detected and excluded), and an opening credit applied by Octopus that caused the net paid figure to be negative for the first two billing periods (now correctly handled via charges minus credits).
Architecture
There is no backend. The page is a single self-contained HTML file — built from TypeScript source but containing no external dependencies — hosted on GitHub Pages. Every API request goes directly from the user’s browser to Octopus’s own API atapi.octopus.energy, authenticated with the user’s own API key. We never see the request, the response, or any data the tool produces, with one narrow exception described below.
This matters for a tool that asks people to enter API credentials: the architecture itself, not a policy statement, is what makes the privacy claim true. The full source is one inspectable file.
The one data point we do collect
The connect screen has an analytics toggle, on by default. When on, two anonymous events are sent to PostHog on each run:comparison_complete: outward postcode area (e.g. “N15”, never the full postcode), percentage difference between tariffs, total kWh, and period length in days.comparison_failed: error type, HTTP status if applicable, and which stage of the flow failed.
Limitations
The tool calculates outcomes from real historical rates; it doesn’t predict future costs, and a tariff that would have been cheaper historically isn’t guaranteed to remain cheaper. It depends on Octopus’s product codes for Flexible and Agile remaining queryable for the full comparison window — if Octopus retires a product version without preserving its rate history, affected readings are flagged rather than silently miscalculated. It isn’t financial advice, and we’d encourage anyone using it to also check their real bills and Octopus’s own tariff tools before switching. Full detail is in the README and in the disclaimer shown on the tool itself.Feedback
The repository is open to issues and pull requests. If you find a calculation that looks wrong, the diagnostic export is the fastest path to a fix — download it from the results screen and attach it to a GitHub issue or email it tohello@auth.energy. The project’s test suite covers the calculation logic directly; see the testing section in the README.
