> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.nyra-labs.com/billing/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nyra-labs.com/_mcp/server. # Billing Billing is prepaid and pay-as-you-go. An organization tops up a wallet, and each transcription draws down the balance. There is no monthly minimum, no subscription, and no invoice to approve. ## Topping up | | | | --------------- | ------------------------------- | | Minimum top-up | **\$5.00** | | Maximum top-up | **\$10,000.00** per transaction | | Maximum top-ups | **250** per 30 days | | Currency | USD | Top up from **Settings → Wallet** in the dashboard. Payment goes through Stripe Checkout; sales tax or VAT is calculated at checkout and charged on top of the credit amount, so a $25 top-up adds exactly $25.00 of credit to the wallet whatever the tax came to. The card used for a top-up is saved, which is what makes auto-recharge possible. Cards, receipts and invoices are managed in the Stripe billing portal, reachable from the same page. ## Auto-recharge Auto-recharge tops the wallet up automatically when it runs low, so a long overnight batch does not stop halfway. | | | | ------------------------- | ----------- | | Default recharge amount | **\$20.00** | | Default trigger threshold | **\$10.00** | | Minimum trigger threshold | **\$5.00** | The minimum threshold exists so there is always enough balance left to keep serving requests while a failed payment is sorted out. Auto-recharge needs a saved payment method: make one manual top-up first, then enable it. An off-session charge cannot answer a bank's 3-D Secure challenge, because nobody is at a browser. If the charge fails for that or any other reason, auto-recharge switches itself off and the organization's owners, admins and billing members get an email. Turn it back on after updating the card. ## Prices Prices are per model, not global, and they are served from the API rather than published as a static table. `GET /v1/models` returns each model's `unit` and `price_per_unit_usd`: ```bash curl https://api.nyra-labs.com/v1/models \ -H "Authorization: Bearer $NYRA_API_KEY" ``` The unit is `audio_second`. CrisperWhisper 2 (`crisperwhisper-v2`) costs \*\*$0.90 per audio hour**, which is $0.00025 per second. The cost of a request is the **whole seconds of decoded audio**, rounded up, multiplied by that price: a 2.84 s clip is 3 billable seconds and costs $0.00075; a one-hour recording costs $0.90. The response's `usage.seconds` and the `x-nyra-cost-usd` header tell you what a request came to. ## How a request is charged Money is tracked in an append-only ledger in Postgres. Stripe only ever moves money *in*; the ledger is the source of truth for what a balance is. 1. **Reserve.** Before the audio is sent to the model, the API reads the audio's duration from the file itself and places a *hold* for that duration plus one second of grace, at the model's price. The hold comes off the available balance immediately, so two large requests in flight at once cannot both spend the same last dollar. Audio whose duration cannot be read, or that is longer than one hour, is refused here — before anything is reserved or sent to a model. 2. **Run.** The request is transcribed. 3. **Settle.** The hold is released in full and the *actual* cost — the duration of the audio the model decoded, rounded up to the second — is charged. The grace second comes back to the wallet the moment the request finishes. A request that fails is **voided**: the hold is released and nothing is charged. That includes a `503 capacity_exceeded` from a saturated backend. A request that never reports back — a dropped connection, a crashed client — has its hold expire and released automatically, so reserved money is never stranded. Balances and holds are visible in the dashboard, and every entry — `top_up`, `hold`, `settle`, `release`, `void`, `refund`, `adjustment` — is listed in the wallet ledger with its reference. ## Running out When the available balance cannot cover a request's hold, the API answers **HTTP 429** with the `insufficient_quota` error type: ```json { "error": { "message": "You exceeded your current quota, please check your plan and billing details.", "type": "insufficient_quota", "param": null, "code": "insufficient_quota" } } ``` `insufficient_quota` is not a rate limit, and retrying will not clear it — the same request will fail identically until the wallet is topped up. Treat it as a terminal error for that request and alert an operator. If your HTTP client retries 429s automatically, exclude this `code`. Two emails warn you before it happens: **low balance** when the balance drops below the alert threshold (default \$5.00, configurable), and **balance exhausted** when it reaches zero. Both are throttled to at most one per day. ## Refunds Refunds issued in Stripe are posted back to the ledger automatically as `refund` entries, including partial refunds. ## Idempotency `POST /v1/audio/transcriptions` accepts an `Idempotency-Key` header, so a retried request is charged once: a retry with the same key within 24 hours replays the first response without running again. See [Retries and idempotency](/quickstart#retries-and-idempotency) for the exact rules. Top-ups are deduplicated on the Stripe event id *and* on the ledger entry, so a payment credits the wallet exactly once no matter how many times Stripe delivers the confirmation. > Prepaid wallet, per-model unit prices, no subscription.