Billing
Usage, wallet and monthly invoices over the API, and what happens to an organization whose subscription payment fails.
All billing reads need the billing:read scope.
| Method | Path | Returns |
|---|---|---|
GET | /billing/usage | Quota usage for the period |
GET | /billing/wallet | Wallet balance and recent transactions |
GET | /billing/invoices | Invoices, newest period first |
GET | /billing/invoices/{id} | One invoice as JSON |
GET | /billing/invoices/{id}.pdf | The same invoice as PDF |
Usage and wallet are described in Quotas and billing.
Invoices
Each organization gets one invoice per month (period = YYYY-MM). It is a
statement of what AACSearch itself charged: allowance used, overage blocks and
wallet movements. The subscription price is billed by your payment provider
and only referenced here, never charged twice.
curl -sS "$AAC_API/billing/invoices?limit=12" -H "Authorization: Bearer $AAC_KEY"{
"invoices": [
{
"id": "clxinv01",
"number": "INV-ab12cd34-202609-1",
"period": "2026-09",
"status": "paid",
"currency": "USD",
"lines": [
{
"kind": "included",
"metric": "searches",
"quantity": 500000,
"unit_cents": 0,
"amount_cents": 0,
"description": "Searches: 500000 of 500000 included (Pro)"
},
{
"kind": "overage",
"metric": "searches",
"quantity": 12,
"unit_cents": 50,
"amount_cents": 600,
"description": "Searches overage: 12000 over, 12 block(s) of 1000"
},
{
"kind": "subscription_ref",
"metric": null,
"quantity": 1,
"unit_cents": 0,
"amount_cents": 0,
"description": "Subscription pro (sub_123, active) - billed by the payment provider"
}
],
"subtotal_cents": 600,
"total_cents": 600,
"issued_at": "2026-10-01T00:05:00.000Z",
"paid_at": "2026-10-01T00:05:00.000Z",
"provider_invoice_id": "sub_123",
"provider_url": null,
"created_at": "2026-10-01T00:05:00.000Z"
}
],
"request_id": "req_…"
}limit is 1–100, default 24.
Line kinds
kind | Meaning |
|---|---|
included | Allowance actually used, zero amount, for context |
overage | Completed overage blocks × block price — exactly what was debited from the wallet. A partial last block is not charged and not invoiced |
wallet_debit | Wallet debits that are not overage (manual adjustments) |
wallet_credit | Refunds and adjustments reduce the total; top-ups are listed with a zero amount |
subscription_ref | Reference to the provider subscription; the price is on the provider's invoice |
Status
status | When |
|---|---|
draft | The period is still open |
paid | Period closed and the wallet covered all overage |
issued | Period closed and some overage could not be collected (wallet ran dry) |
void | Cancelled by an operator |
Invoices for the closed month are generated by a daily scheduler job. Generation
is idempotent: re-running it refreshes a draft and leaves issued, paid and
void invoices untouched.
curl -sS -o INV.pdf "$AAC_API/billing/invoices/clxinv01.pdf" \
-H "Authorization: Bearer $AAC_KEY"Content-Type: application/pdf, downloaded as <number>.pdf. An invoice of
another organization is 404 NOT_FOUND.
Generating on demand (operators)
POST /billing/invoices/generate?period=YYYY-MM&organization_id=… is a
platform-admin operation: it needs the x-platform-admin-token header in addition
to an API key, like /admin/*. It answers { invoice, created, recomputed }.
Failed payments (dunning)
An organization's billingStatus follows the subscription payments reported by
the payment provider:
active ──payment failed──▶ past_due ──grace period──▶ suspended
▲ │ │
└────────payment succeeded──┴──────────────────────────┘| State | Effect |
|---|---|
active | Normal |
past_due | Nothing is taken away. Owners get one e-mail and an in-app notice; the console shows a banner |
suspended | The organization is treated as Free: search keeps working within Free limits; paid features answer 402 FEATURE_NOT_AVAILABLE with details.reason = "past_due" and no upgrade hint. Owners are told once |
The grace period is BILLING_GRACE_DAYS (default 7 days) from the first
unrecovered failure. A successful payment restores active and the plan
immediately. Every transition happens once even if the provider retries the
webhook.
Supported providers: Stripe, Lemon Squeezy, Polar and Dodo Payments report
payment failures. Creem, Robokassa and Tochka do not yet — organizations paying
through them stay active.