HTTP API
mb's UI is HTMX over our own HTTP API — there's no separate
"frontend talks to backend" split. Every action the UI takes
is a plain HTTP request you can script from
curl, Postman, n8n, Zapier, or your own software.
Hello world — list your invoices
Sign in once, get a session cookie, then call any UI route as an HTTP endpoint. Real example:
# 1. Sign in to get a session cookie curl -c cookie.txt -X POST \ -F email=you@example.com \ -F password=… \ -F _csrf=… \ https://app.billmybill.com/auth/signin # 2. List finalized invoices (HTML by default) curl -b cookie.txt \ https://app.billmybill.com/invoices?status=finalized # 3. Download GSTR-1 JSON for the current period curl -b cookie.txt \ https://app.billmybill.com/gstr1/download.json \ > gstr1.json
Authentication
Session cookie + CSRF token for mutations. A true REST/JSON
external API with API keys + webhooks is on the roadmap
(~Q1 2027). Today's API is what the UI calls — stable,
real, fully scriptable, but accepts form-encoded POSTs and
returns HTML partials by default. Add
Accept: application/json on endpoints that
advertise it (currently the GSTR exports).
Route groups
Grouped by domain. Counts verified against
cmd/api/main.go.
Auth & accounts
- POST /auth/signup
- POST /auth/signin
- POST /auth/logout
- GET /auth/google/start
- GET /auth/google/callback
- POST /auth/forgot
- POST /auth/reset
- GET /auth/verify?token=…
Businesses
- GET /business
- POST /business
- GET /business/{id}
- POST /business/{id} — update
- POST /business/switch — flip active business cookie
Customers (sales-side parties)
- GET /customers — list, paginated, ?q= trigram search
- GET /customers/new — form
- POST /customers
- GET /customers/{id} — detail
- POST /customers/{id} — update
- POST /customers/{id}/delete — soft-delete
Invoices
- GET /invoices — list, ?status=&page=&limit=
- POST /invoices — create draft (Idempotency-Key supported)
- POST /invoices/{id}/finalize — assigns gapless number
- POST /invoices/{id}/cancel — guarded by ErrCannotCancelPaid
- GET /invoices/{id}/pdf-status — async PDF status
- GET /invoices/_line_row — HTMX line-row partial
Payments
- GET /payments
- POST /payments — record + partial allocation (Idempotency-Key)
- GET /payments/{id} — detail with allocations
Credit notes
- GET /credit-notes
- POST /credit-notes — issue against finalized invoice
- GET /credit-notes/{id}
- GET /credit-notes/{id}/pdf-status
Quotations
- GET /quotations
- POST /quotations — create
- POST /quotations/{id}/send — flip to 'sent', allocate share URL
- POST /quotations/{id}/accept
- POST /quotations/{id}/reject
- POST /quotations/{id}/convert — to draft invoice
- GET /q/{token} — PUBLIC, no auth, customer view
Suppliers (inward-side parties)
- GET /suppliers
- POST /suppliers — create (Idempotency-Key)
- GET /suppliers/{id}
- POST /suppliers/{id} — update
- POST /suppliers/{id}/delete
Purchases
- GET /purchases — list, ?supplier=&from=&to=&page=&limit=
- POST /purchases — create (Idempotency-Key)
- GET /purchases/new?from_2b={id} — inline-create from a 2B row
- GET /purchases/_itc_suggest?line_hsn_sac=… — HTMX live hint
- POST /purchases/{id}/delete
GSTR-1
- GET /gstr1 — HTML preview
- GET /gstr1/download — same, as a download
- GET /gstr1/download.json — CBIC v3.0 JSON for the portal
GSTR-3B
- GET /gstr3b — HTML preview
- GET /gstr3b/download.json — CBIC JSON
GSTR-2B reconciliation
- GET /gstr2b — imports list for this business
- POST /gstr2b/upload — multipart, accepts CBIC v3.0 JSON
- GET /gstr2b/{import_id} — 4-tab recon page
- POST /gstr2b/invoices/{id}/mark?action=ignore — HTMX
- POST /gstr2b/{import_id}/delete
Dashboard & health
- GET /dashboard — at-a-glance KPIs
- GET /healthz — liveness (no DB touch)
- GET /readyz — readiness (pings DB)
- GET /static/* — embedded static assets