Developers

The bill engine, as an API

Photograph a UK energy bill, get structured figures back, and audit them against real tariff and price-cap data. It’s the same engine behind Joulely’s free bill check — we’ve been running it on real bills, not a demo.

What this is not: a smart-meter data feed. We are not a DCC “Other User” and this API does not provide consumption data from anyone’s meter. It reads and audits bills. If what you actually need is half-hourly meter data, the people to talk to are Hildebrand or n3rgytell us what you’re building and we’ll gladly point you at the right one.

What you can call

  • POST /api/v1/bill/read A bill image or PDF in, machine-read figures out. Nothing is stored — the bytes are discarded after the read.
  • POST /api/v1/bill/audit Confirmed figures in, an authoritative audit out: what they should be paying, against the cap and real deals.
  • POST /api/v1/bill/check One-shot read + audit, for agents. Flagged clearly as machine-read so you can have a human confirm before trusting it.

Full schema: openapi.json.

Try it right now — no account

Paste this. The key below is public and works for everyone; it returns a fixed sample home, so you can wire up the request, the headers and the response shape before you decide anything.

curl -X POST https://joulely.co.uk/api/v1/bill/check \
  -H "X-API-Key: jly_sbx_demo" \
  -H "Content-Type: application/json" \
  -d '{}'

No image, no base64, no sign-up. Sandbox ignores what you send.

What comes back (trimmed — the audit block is the full thing):

{
  "ok": true,
  "sandbox": true,
  "environment": "sandbox",
  "notice": "SANDBOX. Nothing was read from your request and no bill was processed. …",
  "fields": {
    "supplier": "Sandbox Energy",
    "fuel": "both",
    "elec_unit_p": 26.38,
    "elec_standing_p": 46.32,
    "elec_kwh_year": 4262.7,
    "gas_unit_p": 7.2596,
    "gas_standing_p": 33.27,
    "gas_kwh_year": 11466.3,
    "dd_month": 160.0,
    "postcode": "SW1A 1AA",
    "reading_estimated": false,
    "rate_denomination": "pence"
  },
  "fields_confirmed": false,
  "audit_basis": "sandbox_sample",
  "audit": { "headline_kind": "switch", "region": "London", "money": {…},
             "rip_offs": […], "direct_debit": {…}, "switch": {…} },
  "meta": { "sandbox": true, "environment": "sandbox", … }
}

Those figures are one fixed sample home — the same one behind /preview, built from a real year of readings. They are not a customer’s, and Sandbox Energy is not a real supplier. The audit is the real engine against real cap and tariff data, so what you get back is a genuine audit of a home that is nobody’s.

Telling sandbox from live

  • The key Sandbox keys start jly_sbx_. Live keys start jly_. You can see which environment your config points at without running anything.
  • The response "sandbox": true and "environment": "sandbox" at the top level, a notice in words, and the same two markers inside meta.
  • The headers X-Joulely-Sandbox: true on every sandbox response, including the errors.

What sandbox will not do

  • It never reads your bill No image is decoded and no model is called, so it costs us nothing and there is nothing to approve. Send a photo and it will be ignored.
  • It never returns anyone’s data The only home it can reach is the published sample. No account, no meter, no customer record is in scope of a sandbox key.
  • It is not a free production tier The same home comes back every time. When you need real bills read, that is a live key.

Rate limits

KeyAllowanceBurst
jly_sbx_demo (shared) 30 calls an hour, per IP
Your own sandbox key 500 calls a month 60 a minute
Free50 bills a month
Starter1,000 bills a month
Pro5,000 bills a month
No key30 calls per 10 minutes, per IP

Over the limit you get a 429 with {"error": "quota_exceeded"} or {"error": "rate_limited"}, and the reason in detail. Monthly allowances reset on the 1st. Every keyed response carries X-Quota-Limit, X-Quota-Used and X-Quota-Remaining.

Using a live key

curl -X POST https://joulely.co.uk/api/v1/bill/check \
  -H "X-API-Key: jly_…" \
  -H "Content-Type: application/json" \
  -d '{"image_base64": "…", "mime_type": "image/jpeg"}'

Same endpoint, same response shape, minus the sandbox markers — swapping the key is the whole migration.

Pricing

Sandbox

£0
500 calls a month. Sample home only, no card, no approval.

Free

£0
50 bills a month. Key required.

Starter

£29/mo
1,000 bills a month.

Pro

£99/mo
5,000 bills a month.

Volume

Talk to us
Above that, or on-prem.

Paid plans aren’t self-serve yet — start on the free tier and tell us when you need more, and we’ll sort it out with you directly. The first few are priced by hand, so nobody has to guess your volumes.

Get a key

No card either way, and the key is shown once. A sandbox key works immediately and only ever returns the sample home. A live key reads real bills against the 50-a-month allowance; when you need more than that, email business@joulely.co.uk with your volumes and we’ll set it up. That is one email, not an application.

Doing this for a supplier or a partner rather than yourself? Set up a business account — same terms, same keys, plus the organisation on the record and one page telling you what still needs a conversation.

Joulely

Your home bills, checked on your own numbers — £0 commission on any switch.

Check your home · Check your energy bill (free) · Council tax check · Guides

About · For business · Who we support · Privacy & your data · Terms · Tariff data & supplier corrections