Docs
Sign inStart free
Documentation/Billing & credits

Billing & credits

A prepaid wallet, no subscriptions: every successful call debits a fixed per-service cost, failed calls cost nothing, and you top up in whole dollars via Stripe Checkout. The cross-service money model that lives on no single service tab.

4 min readHumans & agentsopen as text

01Prepaid wallet, charge-on-success only

STELQ runs a prepaid wallet — buy credit up front, get debited per successful call. There are no subscriptions and no monthly bill. Your balance lives in one place (user_balances); every discrete money movement (top-up, adjustment, refund) is a row in balance_ledger of type topup, usage, or adjustment. Per-call usage is debited from the balance in real time and folded into a daily rollup rather than written as one ledger row per request.

Failed calls cost nothing. Any response with a status code of 400 or above — a 400 validation error, a 401, 402 or 403, and a 502 when the upstream engine is unreachable — records a cost of exactly $0. This is not a policy; it is the code: the debit amount is statusCode < 400 ? cost : 0. You are billed only for work that succeeded.

The same rule covers Research, which is the one service that charges on submit: if the submit itself fails (an upstream 5xx or an unreachable engine), the submit price is not charged and the idempotency claim is released so you can retry. The async report that arrives later on the free poll is never separately billed.

The debit is idempotent per request. Internally, usage is recorded as an insert into usage_events keyed on the per-request request_id with ON CONFLICT (request_id) DO NOTHING; if the row already exists, the balance is not touched again. A retried record-usage call — a network blip, a redelivery — can never double-charge a single request.

A failed call returns its error and bills $0
{
  "error": "Upstream service unavailable. Please try again shortly."
}
// HTTP/1.1 502 Bad Gateway  →  recorded cost: 0

02What a call costs

Each service has a fixed per-call price, debited only on success: Search $0.001 per query, Content $0.002 per page, Answers $0.002 per answer, and Research $0.08 / $0.25 / $0.40 per job by depth (quick / balanced / deep). Monitors price on size: $0.05 to create per block of 12 compiled queries, then $0.01 per completed check per block — both shown on the monitor's pricing before you pay. These are the exact amounts the gateway (and the monitor sweep) debits — the price you see in the catalog is the price you pay.

ServicePriceWhen charged
Search$0.001 / queryon success (sync)
Content$0.002 / pageon success (sync)
Answers$0.002 / answeron success (sync)
Research$0.08 / jobon submit, once (async)
Monitors$0.05 / block to create · $0.01 / check / blockcreate on 201; each completed check by the sweep (standing)

Reading the API or a CSV export? All money is stored in units of $0.0001 — one ten-thousandth of a dollar — not cents. Divide by 10,000 to get dollars; never divide by 100. The database columns are named *_cents for historical reasons, but the unit is $0.0001. So a value of 800 is $0.08, 20 is $0.002, and 10 is $0.001.

Converting a stored amount to dollars
# A usage_events.cost_cents value of 800 is NOT $8.00
units=800
printf '$%.4f\n' "$(echo "$units / 10000" | bc -l)"   # -> $0.0800

03402 and topping up

A 402 Payment Required is returned before the upstream call is ever made, so a 402 never charges you and never does any work. Three independent checks can trigger it, in order:

  • Absolute floor — your wallet has dropped to or below the negative-balance backstop (default -$0.0050, i.e. -50 units). This catches concurrent-request races.
  • Per-request affordability — your balance is less than the cost of this specific call. The error states the request cost and your current balance.
  • Per-key credit limit — this API key has a spend cap set, and the call would push it past the limit. The error names the spent-vs-limit figures; daily/weekly/monthly caps re-arm automatically when their window elapses.
402 — affordability check, nothing charged
{
  "error": "Insufficient balance. This request costs $0.0800 but your balance is $0.0100. Please top up at https://stelq.com/dashboard/billing."
}
// HTTP/1.1 402 Payment Required

Top up in whole dollars only — a wallet is a fuel tank, not an invoice, so cents on the way in are rejected rather than silently rounded. The minimum top-up is $5 (below it Stripe's fixed fee is punitive) and the maximum is $10,000. The console offers presets of $5 / $10 / $25 / $50 / $100 / $250 plus a custom amount, defaulting to $25.

Payment runs through hosted Stripe Checkout in one-off payment mode. The browser redirect back to the console does NOT credit your wallet — it only shows a toast and re-polls the balance. Crediting happens exactly once, server-side, when Stripe's signed checkout.session.completed webhook fires. A partial unique index on balance_ledger.stripe_payment_id makes a double-credit impossible even under webhook retries or races: a repeat delivery inserts no row and the balance bump is skipped.

New accounts start with $5 of free credit at signup — no card required — so you can make real calls before ever opening Checkout. For limiting spend per key (the credit-limit trigger above), see Spend controls.

04What is NOT offered

To keep your integration honest, here is what the billing system deliberately does not do. Do not build against any of these:

  • No subscriptions, plans, or tiers — billing is purely prepaid, pay-as-you-go credit.
  • No Stripe Customer Portal — there is nothing to manage for a non-subscription wallet.
  • No tax or VAT invoices — receipts are ad-hoc (each top-up links to Stripe's hosted receipt, and Stripe emails one) plus a CSV ledger export. Formal invoicing is a manual support workflow, not a feature.
  • No automated partial refunds — only FULL refunds and disputes are automated and reversed idempotently. A partial refund of prepaid credit is logged for manual handling.

If you need an invoice, a partial refund, or anything in this list, it is a support request, not an API call. Everything that IS automated above is grounded in the live code path; nothing here is a hidden endpoint waiting to be discovered.

05Related