Docs menu

Configure your server

Billing

Charge for hosted use with Stripe: an own-key plan, monthly model credits and top-ups.

Plans

Billing stays off unless STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET are both set (see .env.example). Enabling billing offers a monthly own-key plan for a personal model connection or monthly model credits in USD: $10, $20, $50, $100, $200, or $500. One-time top-ups use the same amounts. Monthly credits expire at the end of their service period; one-time top-ups do not expire. The hosted computer is included in both paths, and monthly credits include the own-key plan.

BYOK_TIERS in @orkbot/contracts sets the own-key plan’s tiers: Standard, Pro and Max, each with a monthly and yearly price, a monthly computer allowance and a computer size. New organizations start on Standard; existing subscribers keep the price they signed up at. A null Standard monthly price makes the plan free, hides the other tiers, and ends paid own-key subscriptions at their period end; a null yearly price offers that tier monthly only, and a null monthly price on Pro or Max hides it. Billing reads a plan’s tier from its price’s lookup key, which Ork creates as orkbot_byok_<tier>_<monthly|yearly>_<cents> (Standard’s keys name no tier), so keep those keys on any price you create by hand. Before selling a tier, make sure the sandbox account can run its computer size; a computer that cannot start at its size starts at its current one.

Subscribers can change tier from Billing at the same interval, and monthly subscribers can switch to yearly, which charges the yearly price less the unused part of the month. A tier change charges the prorated difference now, and a downgrade credits the unused difference to the next invoice. A downgrade is refused while this period’s computer use is above the smaller tier’s allowance. Both are offered only to a paid-up plan that is not cancelling and has no monthly credits; the yearly switch also only when it saves money. Billing reads a plan’s period and tier from its price on every sync, so a switch made in the Stripe billing portal also shows correctly. Portal plan switching skips those checks and allows both directions, including yearly back to monthly with its own proration, so enable it only if that is acceptable; the yearly price exists after the first yearly checkout or switch. Runs check access on the server, so a lapsed organization’s bots and routines stop until it subscribes.

Model credits

Configure the managed default model through the existing model connection settings. The default OpenRouter model is Luna 6; customers can choose another available model, with its usage deducted at model cost. In credit mode, the configured hosted provider uses Ork’s key even when a personal key for that provider is saved. Switching back to BYOK restores that connection. Personal connections to other providers continue to use their own keys and never debit Ork credits. Hosted calls reserve an upper cost estimate atomically before starting, then settle to reported or catalog-priced usage. Unknown usage retains its reservation for reconciliation.

STRIPE_PRICE_ID is optional and only needed to display the legacy seat price. Existing live seat subscriptions retain their access and billing portal. Upgrades charge the prorated difference immediately and add the amount collected to the credit balance; a failed payment leaves the plan unchanged. Downgrades lower the next renewal without charging now or removing credits. Credit purchases require settled payments; webhook replays do not add credits twice, and refunds reduce the remaining account balance.

Monthly funds are spent before top-ups. Each grant has an audited allocation lot, so reservations retain their funding source across renewal: unused monthly holds expire when released, while purchased top-ups remain available. Prorated upgrades share the original period end. Expiration creates a financial journal delta and runs before balance reads, reservations, settlements, and background recovery. Unclassified legacy balances are preserved as non-expiring funds.

Accounting

Postgres owns accounting. billing_audit_events is an append-only journal enforced by database triggers; credit entries, usage rows, and balances are projections. Each managed call shares one callId across reservation, durable provider receipt, usage, and settlement. Provider generation IDs, token buckets, cost provenance, and pricing snapshots are retained. Usage and settlement commit together, and journal/usage history survives clearing messages or deleting a bot or organization. Corrections append evidence rather than rewriting earlier journal events. Existing rows receive explicit baseline events when the migration runs; earlier history cannot be recovered.

The API/worker reconciler recovers saved receipts and, when supported by the configured provider, fetches authoritative generation costs for interrupted calls and estimates. Retries use leases and idempotent settlement. Unverifiable calls retain their holds and become needs_review after six attempts. An hourly, paginated audit rebuilds drifted balance caches from the journal and records repairs. Investigate Model credit hold requires review logs using the shared call ID; do not turn missing provider evidence into a zero-cost settlement.

OpenRouter inference requests include the normal Ork user ID in user, HTTP-Referer (https://orkbot.run), and X-OpenRouter-Title (Ork). These values are sent only to OpenRouter’s HTTPS inference endpoints, never to compatible custom hosts. Recovery uses the existing configured deployment credential; no Redis or external accounting service is required.

Stripe setup

The adapter pins Stripe API 2026-09-30.endive. Configure webhook destinations for your own account, using snapshot payloads on the same API version. Subscribe to all customer.subscription events, customer.deleted, checkout.session.completed, checkout.session.async_payment_succeeded, invoice.paid, invoice.payment_failed, charge.refunded, charge.dispute.created, and charge.dispute.closed. Credit Checkout restricts payment methods to cards. New subscriptions explicitly retain classic billing mode so API upgrades do not change invoice/proration behavior.

For local testing, forward Stripe test events to /api/v1/billing/webhook. Use the signing secret from stripe listen and test API credentials; keep them in an ignored environment file.

Support chat

CRISP_WEBSITE_ID on the API shows a Crisp support chat on the paywall.