Account billing summary
The owner-facing billing snapshot for your own platform account — period usage, the upcoming invoice, the card on file, and recent invoices. Supabase user-JWT authed; not a host API call.
https://api.swarmz.net/functions/v1/platform-billing-summaryReturns the consolidated billing snapshot for your own platform (reseller) account — the data the account-level billing page renders in one shot: period usage, the upcoming Stripe invoice, the card on file, and recent invoices.
This is an owner dashboard endpoint — not a host API call
Unlike the rest of the Platform API, platform-billing-summary is not
authenticated with your sk_live_ key and takes no tenant_id /
external_ref / period parameters. It authenticates the account owner
via their Supabase user JWT and resolves the one active account they own
(or admin-member). It exists to power your billing page, not to drive a WHMCS
integration. For host-facing usage roll-ups by tenant, use
usage.
Authentication
Send the owner's Supabase user JWT as a Bearer token — not a sk_live_ API key:
Authorization: Bearer <supabase-user-jwt>The account is resolved from the caller's identity: the single active account they own, falling back to an active admin membership. There are no body parameters — the endpoint reads everything from the authenticated user.
Request
platform-billing-summary accepts GET (the natural verb, and what the dashboard proxy forwards) or POST. There is no request body.
curl https://api.swarmz.net/functions/v1/platform-billing-summary \
-H "Authorization: Bearer <supabase-user-jwt>"const res = await fetch('https://api.swarmz.net/functions/v1/platform-billing-summary', {
method: 'GET',
headers: {
Authorization: `Bearer ${supabaseUserJwt}`,
},
});
const data = await res.json();import requests
res = requests.get(
"https://api.swarmz.net/functions/v1/platform-billing-summary",
headers={"Authorization": f"Bearer {supabase_user_jwt}"},
)
data = res.json()Response
{
"ok": true,
"account": { "id": "<uuid>", "name": "...", "slug": "...", "email": "owner@example.com" },
"usage": {
"credits_used": 0,
"usd_credits": 0,
"cloud_usd": 0,
"period": { "from": "<ISO>", "to": "<ISO>", "label": "current_month" },
"by_workspace": [
{ "workspace_id": "<uuid>", "credits_used": 0, "usd_credits": 0, "cloud_usd": 0 }
]
},
"upcoming": {
"amount_due_cents": 0,
"currency": "usd",
"period_end": 1234567890,
"next_attempt": 1234567890
},
"card": {
"brand": "visa",
"last4": "0000",
"exp_month": 12,
"exp_year": 2030
},
"card_on_file": true,
"billing": {
"company": "...",
"email": "...",
"address": { "line1": "...", "city": "...", "country": "..." },
"vat": "..."
},
"invoices": [
{
"id": "<uuid>",
"stripe_invoice_id": "in_...",
"status": "paid",
"amount_due_cents": 0,
"amount_paid_cents": 0,
"currency": "usd",
"period_start": "<ISO>",
"period_end": "<ISO>",
"hosted_invoice_url": "https://...",
"paid_at": "<ISO>",
"created_at": "<ISO>"
}
]
}Field meanings:
| Field | Meaning |
|---|---|
account | Your account identity. email is the owner's auth email (billing is bound to it). |
usage | The same current-period roll-up the usage endpoint computes — shared code, so the two never drift. period.label is current_month. |
upcoming | The Stripe upcoming/preview invoice for your subscription: amount_due_cents, currency, period_end (next bill date), next_attempt. null when there's no subscription or no card. Stripe timestamps are Unix seconds. |
upcoming_error | Present only when the Stripe preview fetch failed — a string reason. The rest of the summary still returns; upcoming degrades to null instead of failing the call. |
card | The default payment method: brand, last4, exp_month, exp_year. null when no card is attached. |
card_on_file | Boolean — whether a card is recorded on the account. |
billing | Saved billing identity from Stripe: company, email, address, vat. null when not yet set. |
invoices[] | Up to 24 recent rows from platform_invoices, newest first. |
upcoming may carry upcoming_error
A Stripe hiccup never 500s the summary. When the preview invoice fetch fails,
the response still returns ok: true with upcoming: null and an
upcoming_error string describing what went wrong (e.g.
stripe_not_configured: ...). Treat upcoming as best-effort.
Errors
| Status | error | reason | When |
|---|---|---|---|
| 401 | unauthorized | missing_bearer | No Bearer token supplied |
| 401 | unauthorized | invalid_token | The user JWT failed verification |
| 403 | forbidden | no_active_account | The caller owns no active account and has no active admin membership |
| 405 | method_not_allowed | — | Anything other than GET or POST |
| 500 | internal_error | — | Unexpected server-side failure; safe to retry |
| 500 | usage_read_failed | RPC reason | The usage roll-up failed server-side |
| 500 | invoices_read_failed | DB message | The invoice read failed server-side |
Idempotency
Not applicable — billing summary is a pure read. Safe to call as often as you like. See Idempotency.
Notes
Pair with platform-usage for host integrations
billing-summary is the owner's view of their own account. To report
usage per tenant from your WHMCS integration (key-authed, scoped to a
tenant_id), use usage instead.
Display usage & stats in your panel
A copy-paste guide to fetching per-tenant usage and standing credit balances from platform-usage and rendering them as a stats panel — the credit pools, plan caps, and per-workspace spend the WHMCS client area shows.
Entitlements
The per-tenant budget caps you set with create and plan. A JSONB object of known knobs — invalid keys and values are dropped silently, never rejected.