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.5,
"totalUsage": 7.31
}Both are USD, rounded to cents. totalUsage resets at the start of each month.
List invoices
http
GET /api/billing/invoicesA plain array of invoices. Each one covers a billing period and itemises what you used.
json
[
{
"id": "6a4d5b83b7006ccae6391820",
"accountId": "6a4d5b83b7006ccae6391800",
"amount": 5.97,
"currency": "usd",
"status": "paid",
"periodStart": "2026-06-01T00:00:00Z",
"periodEnd": "2026-06-30T23:59:59Z",
"items": [
{ "description": "pod - my-app (small)", "hours": 720, "rate": 0.0072, "amount": 5.18 },
{ "description": "storage - my-app (small)", "hours": 720, "rate": 0.0011, "amount": 0.79 }
],
"createdAt": "2026-07-01T00:05:00Z",
"updatedAt": "2026-07-01T00:07:12Z"
}
]status is pending (raised, not yet settled from your balance) or paid. Each entry in items is one line of usage: description (the resource type, its pod name, and its size), hours (how long it ran), rate (its hourly rate), and amount (the two multiplied). Every pod produces two lines, one for compute and one for its storage. Once paid backups start, each backup adds a line of its own, such as backup - my-app (0.68 GB), whose rate is its size in GB times the per-GB hourly backup rate. The rates above are illustrative; the pricing page is authoritative.
Download an invoice as PDF
http
GET /api/billing/invoices/:id/pdfReturns the invoice as a PDF (application/pdf), not JSON, as an attachment named invoice-<id>.pdf. Good for expense reports and accountants who like paper.
bash
curl https://cloud-api.microapps.io/api/billing/invoices/6a4d5b83b7006ccae6391820/pdf \
-H "Authorization: Bearer $MICROAPPS_API_KEY" \
-o invoice.pdfList transactions
http
GET /api/billing/transactionsEvery top-up and how it went, as a plain array.
json
[
{
"id": "6a4d5b83b7006ccae6391830",
"accountId": "6a4d5b83b7006ccae6391800",
"userId": "6a4d5b83b7006ccae6391801",
"sessionId": "cs_test_a1B2c3D4e5F6g7H8i9J0kLmNoPqRsTuVwXyZ",
"amount": 25,
"currency": "usd",
"status": "paid",
"createdAt": "2026-07-01T09:12:00Z",
"updatedAt": "2026-07-01T09:13:44Z"
}
]status | Means |
|---|---|
unpaid | Checkout opened, payment not completed yet |
paid | Paid and credited to your balance |
expired | Nobody finished the checkout; the session timed out |
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. Top-ups are accepted regardless of any pending invoices; settlement runs within minutes of payment and takes whatever your balance covers. Note that an invoice left unpaid starts the dunning ladder described in the billing model (warning email, pods stopped after 2 business days, backed up and deleted after 3 more).
json
{ "checkoutSessionURL": "https://checkout.stripe.com/c/pay/cs_test_a1B2c3D4e5F6g7H8i9J0kLmNoPqRsTuVwXyZ" }The session is good for about half an hour. Leave it and the transaction settles as expired; nothing is charged and nothing is credited.
| Problem | Status | Message |
|---|---|---|
amount missing or not a positive integer | 400 | Invalid amount format: |
amount below 3 | 400 | Credit amount must be at least $3 |
amount above 10000 | 400 | Amount cannot exceed $10,000: 20000 |
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_test_a1B2c3D4e5F6g7H8i9J0kLmNoPqRsTuVwXyZCalled when the customer returns from Stripe. It reconciles that one 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. A session belonging to another account returns 404.
json
{
"status": "paid",
"amount": 25,
"currency": "usd",
"paid": true
}status is the transaction's status after reconciliation; paid is the same fact as a boolean. You do not have to call this at all - a background sweep reconciles pending transactions anyway. It exists so the console can stop showing a spinner without waiting for the sweep.
curl example
Check your balance:
bash
curl https://cloud-api.microapps.io/api/billing/stats \
-H "Authorization: Bearer $MICROAPPS_API_KEY"Open a $25 top-up:
bash
curl "https://cloud-api.microapps.io/api/billing/create-checkout-session?amount=25" \
-H "Authorization: Bearer $MICROAPPS_API_KEY"