Wallet & AI credits
How the pre-paid wallet for AI usage works — top-ups, auto-recharge, spending limits, ledger entries, and refunds.
AACsearch separates plan billing from AI usage. Plans pay for search capacity and seats; the wallet pays for AI features. The wallet is a pre-paid balance denominated in micro-USD (or kopecks for RUB-billed customers) that draws down per AI call.
The wallet is independent of your plan, has its own ledger, and does not roll over month to month — but it also does not expire. A balance sits there indefinitely until you spend it.
Why a wallet at all?
AI cost varies wildly per call. A typical RAG query is a few thousand tokens; a long retrieval with rerank can be tens of thousands. Mixing that variance into a flat plan cap would mean either huge plans (most customers overpay) or constant surprise overage. A pre-paid wallet keeps the cost visible per call and the bill predictable.
What the wallet pays for
| Feature | Drawn from wallet? | Notes |
|---|---|---|
POST /search | No | Plain keyword search uses plan search units, not the wallet. |
| AI rerank | Yes | Adds a rerank ledger entry per search that requested rerank. |
| Knowledge query (RAG) | Yes | Embeddings + LLM tokens per query. |
/embeddings endpoint | Yes | Embedding-only calls (e.g. you build your own RAG). |
| Document summarization | Yes | One call per summary. |
| AI chat | Yes | Token-priced per turn, cumulative on conversation history. |
| Index reindex | No | Plan search units only — reindexing does not invoke AI. |
Plan features (search, ingest, connectors, analytics) never draw from the wallet. AI features only draw from the wallet.
Wallet lifecycle
top-up → balance grows → AI call → ledger entry deducts → balance shrinks → top-up …At any moment the wallet has:
balance: BigInt— current balance in micro-USD (or kopecks).currency: "USD" | "RUB"— fixed at first top-up.autoRechargeEnabled: boolean— if true, top up automatically when balance drops below threshold.autoRechargeThreshold: BigInt— refill trigger.autoRechargeAmount: BigInt— how much to refill.spendingLimit: BigInt | null— optional per-period cap.
The schema lives in WalletAccount and WalletLedgerEntry in the database.
Topping up
From /settings/billing/ai-credits:
- Click Top up.
- Pick an amount ($10 / $50 / $200, or custom).
- Confirm with your saved payment method.
- The wallet credits as soon as the provider webhook lands (typically a few seconds).
A receipt is sent to your billing email. The wallet ledger entry shows type: "topup" with the gross amount.
If you have a saved tax ID, the receipt includes it. Otherwise, set one under Billing details before topping up.
Auto-recharge
Enable auto-recharge if you do not want to think about top-ups. From /settings/billing/ai-credits → Auto-recharge:
- Toggle Enabled.
- Set Threshold (when balance drops below, recharge fires).
- Set Amount (how much to add).
When the balance crosses the threshold from above, an auto-top-up runs with the saved payment method. Failures retry with backoff. After three consecutive failures, auto-recharge is paused and you are notified by email.
For runaway-bill protection, set a monthly spending limit (next section) alongside auto-recharge. Auto-recharge respects the limit — it will not refill past the cap.
Spending limits
A spending limit caps how much the wallet can be drawn in a calendar month. Hitting the limit halts AI calls with wallet_spending_limit_reached and pauses auto-recharge.
From /settings/billing/ai-credits → Spending limit:
- Set the monthly cap (any positive amount).
- Optional: alert thresholds at 50%, 80%, and 100% trigger an email to billing contacts.
The limit resets on the 1st of each month at 00:00:00 UTC.
Ledger entries
Every wallet operation writes a row to WalletLedgerEntry:
| Field | Meaning |
|---|---|
id | Stable ID for the entry |
walletId | Which wallet |
type | topup, embedding, rerank, knowledge, summarize, chat, refund, admin_adjust |
amount | BigInt micro-USD, signed (positive = credit, negative = debit) |
balanceAfter | Snapshot of balance after this entry (for audit) |
referenceId | Foreign key into the originating event (search id, knowledge query id, top-up id) |
metadata | Model used, token counts, raw provider response keys |
createdAt | When the entry was recorded |
You can export the full ledger from /settings/billing/ai-credits → Export (CSV) or via the v1 REST endpoint:
curl https://app.aacsearch.com/api/v1/wallet/ledger?from=2025-01-01&to=2025-01-31 \
-H "Authorization: Bearer $AACSEARCH_ADMIN_KEY"Pricing rules
AI prices are not flat — they depend on the model and the underlying provider rate. The pricing rule table is published at /settings/billing/ai-credits → Pricing:
| Operation | Model | Unit | Price (USD) |
|---|---|---|---|
| Embedding | text-embed-3 | per 1k tokens | $0.0001 |
| LLM (knowledge) | claude-haiku | per 1k input tok | $0.0008 |
| LLM (knowledge) | claude-haiku | per 1k output tok | $0.004 |
| Rerank | cohere-rerank | per 1k tokens | $0.001 |
Rates can change with 30 days' notice — you will be emailed before any increase. Decreases apply immediately.
Common errors
| Status | Error code | Meaning |
|---|---|---|
| 402 | wallet_balance_insufficient | Balance is below the call's minimum required amount. |
| 402 | wallet_spending_limit_reached | The monthly spending limit has been hit. |
| 402 | wallet_currency_mismatch | The org's wallet currency differs from the call's pricing currency. |
| 402 | wallet_disabled | Wallet has been administratively disabled (rare; contact support). |
| 503 | pricing_provider_unavailable | We could not look up the model rate; call is rejected, no charge. |
These are 402 (Payment Required) rather than 429 because the wallet is a soft state, not a rate limit — top up and retry.
Refunds
Refunds happen in two cases:
- Top-up refund — you charge back or request a refund via support. We reverse both the payment and the ledger entry atomically (a negative
type: "refund"row equal to the original top-up). - Operational adjustment — platform admins issue a credit (e.g. for a billing bug). This is
type: "admin_adjust"with positive amount and a reason inmetadata.
Wallet balance can never go negative. If a refund would push it below zero, support contacts you to reconcile.
Multi-currency
A wallet is single-currency for its lifetime. The currency is fixed at the first top-up — you cannot mix USD and RUB in one wallet.
If you need to switch currencies (e.g. moving billing entities from EU to RU), open a support ticket. The fix is to close the old wallet (zeroing the balance via refund) and open a new one in the target currency.
Admin overrides
Platform admins can adjust any wallet from /admin/wallet:
- Manually credit or debit a wallet (audit-logged with reason).
- View the full ledger across all orgs.
- Disable a wallet (blocks all AI calls).
- Re-issue a failed top-up.
Audit log actions: wallet_admin_adjust, wallet_disable, wallet_enable.
Related
- Plans — what your plan covers (search), what the wallet covers (AI).
- Usage units — full unit-by-unit reference, including AI events.
- Quotas — plan-level caps; wallet caps are described here.
- Invoices — top-up receipts vs. plan invoices.