Overview
You send us a utility bill as a PDF, or give us a login to the utility's portal and we retrieve the bills ourselves. Either way, we send back one structured statement per bill, as signed JSON webhooks to an HTTPS endpoint you register. Every figure we send carries the text it was read from and says how it was obtained, so you can check any value against the bill.
This documentation describes contract version 1.0.0, frozen on October 14, 2026. Every endpoint and field it describes is live and is what the service produces today; the retrieval schedule starts when your account goes live. From 1.0.0 on, the rules in Compatibility and versioning apply.
How an integration works
An integration has two halves.
- You send a bill. One HTTPS request per PDF, authenticated with your API token. You choose the
request_id, and you can attach your ownclient_reference, which we echo on everything we send back about that request. - We answer every request at the webhook URL you registered. Most requests produce one statement. A summary bill produces a parent statement plus one child per metered service point, and a PDF holding several unrelated bills produces one statement for each. A request we cannot complete produces a
request.failedevent instead, and a file you already sent producesrequest.duplicate.
Or we retrieve the bills. Register a login to a utility portal once, choose which of its accounts you want, and we sign in on a schedule or whenever you ask. Each new bill is delivered exactly as an uploaded one would be, and every run ends in a retrieval.completed or retrieval.failed event. See Connecting a portal.
Processing is asynchronous. The upload returns as soon as the bill is queued. Results arrive by webhook. Turnaround is set in your service agreement, and a large summary bill takes longer than a single bill.
A request ends in exactly one of three answers: statements, a failure or a duplicate notice. A later re-extraction can add a version or withdraw a statement.
Using an AI coding assistant
Point it at llms-full.txt. That one file holds a checklist of the details integration code most often gets wrong, this whole documentation, and the JSON Schema for every webhook body. Each page is also available as Markdown at the same address ending in .md, for example webhooks.md, and llms.txt indexes them all.
Terms
| Term | Meaning |
|---|---|
| Request | One PDF you sent, identified by your request_id |
| Document | That file. Its document_id is the same however many statements it yields |
| Statement | One bill for one account and period (or one service point on a summary bill), identified by statement_id |
| Version | One extraction of a statement, identified by version_id. A re-extraction delivers a new version under the same statement_id |
| Connection | One login to one utility portal, identified by connection_id |
| Account | One account a connection's login can see, identified by account_id. You choose which accounts we retrieve |
| Run | One retrieval for a connection, scheduled or triggered by you, and retried under the same id when the portal could not be read. Identified by its own request_id |
| Event | One webhook delivery, named in the Luminetric-Event header |