AACSearch

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.

MethodPathReturns
GET/billing/usageQuota usage for the period
GET/billing/walletWallet balance and recent transactions
GET/billing/invoicesInvoices, newest period first
GET/billing/invoices/{id}One invoice as JSON
GET/billing/invoices/{id}.pdfThe 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

kindMeaning
includedAllowance actually used, zero amount, for context
overageCompleted overage blocks × block price — exactly what was debited from the wallet. A partial last block is not charged and not invoiced
wallet_debitWallet debits that are not overage (manual adjustments)
wallet_creditRefunds and adjustments reduce the total; top-ups are listed with a zero amount
subscription_refReference to the provider subscription; the price is on the provider's invoice

Status

statusWhen
draftThe period is still open
paidPeriod closed and the wallet covered all overage
issuedPeriod closed and some overage could not be collected (wallet ran dry)
voidCancelled 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.

PDF

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──┴──────────────────────────┘
StateEffect
activeNormal
past_dueNothing is taken away. Owners get one e-mail and an in-app notice; the console shows a banner
suspendedThe 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.

On this page