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.
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.
{
"error": "Upstream service unavailable. Please try again shortly."
}
// HTTP/1.1 502 Bad Gateway → recorded cost: 0Each 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.
| Service | Price | When charged |
|---|---|---|
| Search | $0.001 / query | on success (sync) |
| Content | $0.002 / page | on success (sync) |
| Answers | $0.002 / answer | on success (sync) |
| Research | $0.08 / job | on submit, once (async) |
| Monitors | $0.05 / block to create · $0.01 / check / block | create 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.
# A usage_events.cost_cents value of 800 is NOT $8.00 units=800 printf '$%.4f\n' "$(echo "$units / 10000" | bc -l)" # -> $0.0800
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:
{
"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 RequiredTop 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.
To keep your integration honest, here is what the billing system deliberately does not do. Do not build against any of these:
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.