One API for every waste hauler your customers use.

Request invoices
# invoices for all of your accounts
GET /v1/invoices
Authorization: Bearer $ROVER_TOKEN
# → 200 · 21 records

the API · /v1/accounts, /v1/invoices, /v1/documents

{ "records": [{
  "invoice_number": "48812", "invoice_date": "2026-09-01",
  "total": 1284.10, "amount_due": 0.00, "payments": 1284.10,
  "account_name": "Site 14 Depot",
  "document_ref": "sha256:9f3c…" }] }

the same fields for every hauler · each invoice keeps the hauler's invoice number

POST https://your.app/rover
X-Rover-Timestamp: 1790294400
X-Rover-Signature: sha256=HMAC(secret, ts + "." + body)
invoice 48812 changed · amount_due 1,284.10 → 0.00 · payments → 1,284.10
verified · timingSafeEqual

change events · signed, so no one can resend a copied request

Did any invoice change this week?
› changes · hauler-e · since last week
Yes, one. Invoice 48812 at Site 14 Depot dropped from 1,284.10 to 0.00 after a payment. Checked Thu 02:00.

MCP tools · latest_records, changes, record_history, invoice_text, portal_health, coverage

Connect a hauler account once. Rover delivers its invoices, services and locations to your product and your agents on schedule.

Three ways to get the data

Open an account to get an API key and the full API reference.

01 · The API

Pull accounts, invoices and PDFs with the same fields for every hauler.

02 · Change events

Register a webhook to get a signed event when data changes.

03 · Agent tools

Your AI agents can query the data through an MCP server.

What your agent can do

Your agent can audit new invoices, explain rate changes, reconcile AP and answer questions about any site.

one agent tool call
example dataMCP over JSON-RPC

Signed change events

Each delivery carries a timestamp and an HMAC signature, so no one can resend a copied request.

webhook.js
POST /v1/subscriptions
{ "channel": { "kind": "webhook",
               "url": "https://your.app/rover" } }

# every delivery carries
X-Rover-Timestamp: 1790294400
X-Rover-Signature: sha256=HMAC(secret, ts + "." + body)

# verify before you trust it
const mac = createHmac('sha256', secret)
  .update(`${ts}.${raw}`).digest('hex')
timingSafeEqual(mac, sig.slice(7))

Your integration keeps working when portals change

Invoice IDs never change

Each invoice keeps the hauler's invoice number, so fixes never create duplicates.

Field names stay the same

A fix only changes how Rover finds a field. See a fix happen.

Each customer is kept separate

Each API key sees only its own customer's logins and records.