Appearance
Billing API
All endpoints under /api/billing require a bearer token (login token or API key). Reading uses the billing:read permission; adding credit uses billing:pay.
MicroApps is prepaid. You keep a credit balance, usage accrues against it hourly, and the month's usage is settled from your balance by a monthly invoice. Nothing auto-recharges - you top up when you want to. You need at least $3 of credit for anything that creates a billable resource (pods, networks, domains, firewalls, snapshots, backups, mailboxes - plus clone and restore), or those calls return 402. The billing model has the full picture.
Account stats
http
GET /api/billing/statsYour available credit and this calendar month's usage so far.
json
{
"availableCredit": 42.50,
"totalUsage": 7.31
}Both are USD, rounded to cents. totalUsage resets at the start of each month.
List invoices
http
GET /api/billing/invoicesAn array of invoices. Each one covers a billing period and itemises what you used.
json
[
{
"id": "inv_...",
"amount": 6.84,
"currency": "usd",
"status": "paid",
"periodStart": "2026-06-01T00:00:00Z",
"periodEnd": "2026-06-30T23:59:59Z",
"items": [ ... ]
}
]Each entry in items is one line of usage: description, hours (how long it ran), rate (its hourly rate), and amount (the two multiplied).
Download an invoice as PDF
http
GET /api/billing/invoices/:id/pdfReturns the invoice as a PDF (application/pdf), not JSON. Good for expense reports and accountants who like paper.
List transactions
http
GET /api/billing/transactionsEvery top-up and how it went. status is one of paid, unpaid, expired.
json
[
{
"id": "txn_...",
"amount": 25,
"currency": "usd",
"status": "paid",
"createdAt": "2026-07-01T09:12:00Z"
}
]Add credit (Stripe Checkout)
http
GET /api/billing/create-checkout-session?amount=25amount is a whole number of US dollars, minimum 3, maximum 10000. You get back a Stripe-hosted checkout URL - send the customer there to pay. One catch: if you have a pending invoice, top-ups smaller than the pending total are rejected with a 400 asking you to cover it first.
json
{ "checkoutSessionURL": "https://checkout.stripe.com/c/pay/cs_..." }We never see or store card details; Stripe handles the payment. When the customer finishes, Stripe sends them back to the console.
Verify a payment
http
GET /api/billing/verify-payment?session_id=cs_...Called when the customer returns from Stripe. It checks the session and, if it is paid, applies the credit. Applying credit is idempotent - calling this twice for the same session will not double your balance.
json
{
"status": "complete",
"amount": 25,
"currency": "usd",
"paid": true
}curl example
Check your balance:
bash
curl https://cloud-api.microapps.io/api/billing/stats \
-H "Authorization: Bearer $TOKEN"Open a $25 top-up:
bash
curl "https://cloud-api.microapps.io/api/billing/create-checkout-session?amount=25" \
-H "Authorization: Bearer $TOKEN"