Docs: Sending a bill

Sending a bill

Send requests to https://api.luminetric.com. Your API token is issued when your account is set up.

POST /v1/statements
Authorization: Bearer <your API token>
Content-Type: application/json
{
  "request_id": "req_0a4d6e82-9c37-4b15-a8f2-3e7b1d5c9042",
  "client_reference": "invoice-433193",
  "provider": "Example Water District",
  "document": {
    "url": "https://files.example.com/bills/7299639426-2026-08-18.pdf",
    "content_type": "application/pdf",
    "sha256": "329ec7b43ecb6bad0f2bbc25c888987a5ce677ade468ac31a1f0f2e0875a1b4c"
  },
  "options": { "force_reprocess": false }
}
Field Required Notes
request_id yes Your unique id for this request: 1 to 128 letters, digits, '.', '_', ':' or '-', starting with a letter or digit. Every event about it carries it. Reusing an id another account holds is refused
client_reference no Your own label, echoed on every statement and event for this request. A string of at most 255 characters; anything else is ignored rather than failing the request
provider no The utility you believe issued the bill. We read the issuer from the bill itself and use your value as a check, not an instruction
document.url one of url or content_base64 Where we fetch the PDF, if you are not sending it inline: an https URL on the standard port, publicly reachable for long enough for us to fetch it (a pre-signed storage URL works well). Up to 3 redirects are followed, to https only. At most 40 MB
document.content_base64 one of url or content_base64 The PDF itself, base64-encoded (standard alphabet, padding allowed), instead of a URL. Send this or document.url, not both. The request body is capped at 32 MB and base64 adds a third, so files above about 24 MB must go by document.url
document.sha256 yes SHA-256 of the file's bytes, so we can confirm the file we received is the one you sent
options.force_reprocess no Extract again even if you have sent this file before. Default false

Only PDFs are accepted. A scanned bill is fine. Send one request per file: a PDF that holds several bills is split for you.

Responses. 202 Accepted means the bill is queued, and everything after that arrives by webhook. 401 means the token is missing or invalid, and 400 means the request cannot succeed as sent: the body is not valid JSON, a field is missing or malformed, both or neither of url and content_base64 are sent, the URL is refused, the base64 does not decode, or the file received is not a PDF matching document.sha256. The error message says which, and lists every problem at once. 502 means we could not fetch the document (it was unreachable or answered with an error), and 500 means we could not queue it; retry both. 404 and 405 mean a wrong path or method. Retrying a request with the same request_id is safe.

Sending the same file twice. We do not extract a file you have already sent. The new request is answered at once with a request.duplicate event naming the earlier request, and the statements are the earlier request's. To extract it again, set force_reprocess.