One price, one unit, a cap tied to what you saved, and a refund with no conditions.
The unit
You pay $1 per 1,000 governed requests, and on routed traffic never more than half of what Ergoda measurably saved you that month, nor below a quarter of list. The rate is the same whichever model answers.
A governed request is one request your agent sends through Ergoda (the SDK or the proxy), or one request in your own traces that observe mode reads. It counts once, whichever model answered it, however many calls the checks made for it and however many times the same trace is read.
Every environment counts. Requests your staging, development or eval
deployments send with your key are metered as production's are; the
environment decides only what counts as evidence for your routes
(environments). A label that lowered the bill could be put on
production traffic, so the bill does not read it. The setting comes after
0.1.5; the 0.1.5 SDKs and proxy send every row as production. The meter
(GET /v1/sites/SITE/metering) lists the non-production share under
non_production when there is any.
Old dates count too. Observe mode sends your traces' own history, so a request may be dated months before it reaches us, and it is billed in the report that follows its arrival, once. The dashboard's monthly figures place a request in the month it says it happened, so history you upload shows in those months while its charge lands on the invoice after the upload.
The cap
If what you paid for routed traffic in a month comes to more than half of what Ergoda measurably saved you, we credit the difference on your next invoice, so you keep at least half of what routing saved. It never takes the fee on routed traffic below a quarter of list.
- What it covers. The fee on requests in trajectories that reached a route. Observe mode, discovery and steps no route serves measure no saving and are billed at list.
- The floor. However small the saving, the fee on routed traffic keeps a quarter of list ($0.25 per 1,000). The checks, the audit trail and the attestation are worth something on a route that saves little, and a fee that went to zero with the saving would pay us only for moving traffic to the cheaper model, which is the incentive our routing rules keep out.
- How the saving is measured. One trajectory in twenty that reaches a routed step is held out at random and served by your frontier model alone (the cost holdout). The saving is the number of routed trajectories times the difference between a held-out trajectory's average cost and a routed one's, in the dollars your provider charged (or, where it returned no bill, its token counts at its list price). It counts whole trajectories, so a cheaper model that takes more steps is caught. Each request's cost is checked against the list price of its own token counts: a cost more than 10% under that list price is counted at list, and a request with no token counts, or on a model with no list price, counts as having no cost.
- When it applies. Only when the month's holdout can support the figure: at least 40 held-out and 40 routed trajectories, at least 95% of them with a cost, and a saving known to within 2.5% of what the frontier would have cost (95% confidence). 40 is the smallest holdout that measured a varied workload that closely in our tests; a workload whose task costs vary more needs more, about 160. Below that, you pay the plain fee and the invoice preview shows the measured saving for information only. A thin holdout never lowers the fee on a guess, and a saving of zero or less brings the fee down to the floor only when it is measured that precisely.
- What we check first. The saving is reported by your own SDK or proxy, so besides holding each cost to its list price, two checks run before it lowers anything, and either failing leaves the plain fee. The holdout draw is recomputed: which trajectories are held is a keyed hash of each trajectory, so we can see whether the reported arms are the ones the draw made. And each model's reported cost is compared with its list price in both arms; one model on one account has one price.
- How it settles. Monthly, after the calendar month closes. Usage is still reported at $1 per 1,000 through the month; the part of the fee above the cap comes back as a credit on your next invoice, labelled with the month it caps. Usage below the $10 charge threshold that is billed in a later month is still capped by the month it was used in. The invoice preview shows the fee, the measured saving and the cap as the month runs.
Paying
- Monthly in arrears, by card through Stripe. Stripe keeps the card; we never see its full number.
- Nothing is charged until $10 of usage has built up. At that point usage waits for a card: your agents keep running on the policy they have, and the usage data they send is refused until a card is on file (see A hold, below).
- Add a card during setup or on the dashboard's Billing page, which lists every saved card (brand, last four digits and expiry) and lets you choose which one invoices charge. The one invoices charge cannot be removed until another is chosen.
- Larger accounts can pay by invoice instead, with a purchase-order number on it.
- Prices are in USD, excluding VAT. Adding a card asks for your business name, billing address and, in the EU, the UK and other VAT countries, your VAT number. EU businesses outside Finland pay no VAT; it is reverse-charged.
- Invoices run on the day your billing began, not on the 1st. Stripe cuts one each month on the day your subscription started (the Billing page says which day) and bills the usage we reported since the last one. The month the dashboard shows is a calendar month, so a figure there and an invoice cover different days unless you signed up on the 1st.
A hold
A site whose card is missing past the first $10, or whose invoice stays unpaid 14 days after a failure, is on hold. So is one whose Stripe subscription was canceled or paused, whose customer was deleted, or whose invoice Stripe gave up collecting. The Billing page and an email give the reason.
A hold refuses your usage data and nothing else. Your agents keep routing on the policy they have, because routing runs in your process.
What happens to the data your agents send meanwhile. Nothing on our side
stores it. The Python and TypeScript SDKs write it to a spool on your own
disk, up to 100,000 events, 64 MB and 30 days, oldest dropped first, and send
it once the hold lifts, from the same process or the next one for that site
(Python, TypeScript).
A process with no writable disk, such as most serverless functions, or one run
with ERGODA_SPOOL_DIR=off, keeps only the last 1,000 events in memory and
loses them on a restart. The proxy and observe mode keep theirs on disk. A
card saved, an invoice paid or a restored subscription lifts the hold at once.
What is billed. Usage sent after the hold lifts is metered like any other usage and appears on the next invoice; ingest counts a replayed event once however many times it is sent. Events dropped under a hold, by a spool bound, a restart or a process without a disk, never reach us and are not billed.
If a card is declined we email you once for that invoice; Stripe retries it on its own schedule.
The refund
Ask within your first 60 days of paid use and we refund what you were charged
in those 60 days, VAT included. They start at your first charge, no reason is
needed, and it is once per organisation. The dashboard's Billing page shows
the last day to ask. Write to support@ergoda.com from your account's address.
We refund each invoice paid in the window to the card it was paid with and
record it on your account; once refunded, it is not refunded again.
The refund does not cover an enterprise commit, which is a written agreement with its own terms.
Leaving
Close the account at any time and pay for what you used up to that point.
An owner closes it from the dashboard's Billing page (type close, then
enter the code we email to the owner's address), or you can write to
support@ergoda.com. Closing reports your usage so far (the
$10 minimum does not apply to a closing account) and bills it on a final
invoice, cancels the subscription, revokes every key, and schedules your
stored usage data for erasure 14 days later; a confirmation goes to your
address. Closing waits for Stripe to count your last usage before it cancels, which
takes about a minute, so the button may take that long; if Stripe is slow it
stops without cancelling and says so, and pressing it again finishes. Billing
records are kept for six years, as the law requires. If it
was a mistake, write before the erasure date.
Enterprise
An enterprise account prepays an annual commit, negotiated per customer from $120,000. It stays metered: every governed request is reported at the same $1.00 per 1,000 and draws the commit down, and usage past the commit is billed at the same rate. The monthly cap does not apply to a commit; its agreement sets the terms. The Billing page and the invoice preview show the commit, what has been drawn and what remains. It is a written agreement, so the 60-day refund does not apply to it. A flat unmetered licence exists only where no meter can reach us (air-gapped), and is priced from the metered equivalent.
Operator runbook
- Agree the commit, term and invoice terms in writing. In Stripe, issue the prepay invoice for the commit amount and collect it.
- Put the account on invoice terms if it is not paying by card:
ergoda controlplane billing collection --site S --method invoice --days-until-due 30 --email ap@... --po ...(Stripe needs the customer's address and, for an EU business, VAT id first). - Record the commit once the prepay is paid:
ergoda controlplane billing commit --site S --amount 120000 --term-start 2026-10-01 --by NAME --note MSA-7(without--applyit only says what it would do). This grants the amount as Stripe credit against the metered price, expiring with the term, moves the site to the enterprise plan, and starts the drawdown. The invoice then shows the credit applied and charges only what exceeds it.--no-grantrecords a commit whose credit you gave by hand. - Check the first invoice after the term starts against
billing invoice-preview --site S --period YYYY-MM. - Renewal is a new
billing commitwith the next--term-start. An unused commit expires with the term unless the agreement says otherwise; the credit grant'sexpires_atis the term's end.
Operator runbook: refunds, closing, billing problems
- The fee cap (after each calendar month closes):
billing settle-fee-cap --period YYYY-MMshows each metered site's fee, measured saving and credit; add--applyto grant the credit at Stripe (a promotional credit against the metered price, expiring after 12 months) and record it. A month below the floor settles at zero and the row says why. Re-running does not credit a month twice; a failed grant is recorded and retried by the next run. The scheduled job runs--recentfrom the 3rd to the 7th: every unsettled month in the last three (payments.FEE_CAP_LOOKBACK_MONTHS), so a dropped run is retried. A month whose invoices were all refunded under ยง5 settles at zero, and so does one for an account with a refund on record and no payment to tie the month to it. A month that settles after the subscription is gone (closed, cancelled, customer deleted) grants nothing and printsOWED: refund that amount by hand (payments.fee_cap_owedlists the rows). Closing an account settles every unsettled month, the closing month to date included, before it cancels, so the credit lands on the final invoice. - Refund (customer wrote to support):
billing refund --site S --by NAMEshows what would be refunded; add--applyto refund each invoice paid in the 60 days at Stripe and write a ledger row for it. It refuses a plan the refund does not cover, a request after the 60 days (--latewaives that, your decision), and an invoice already refunded. Once per organisation is yours to check across sites a group opened. - Close (customer wrote to support):
controlplane close-account --site S --by NAMElists the steps; add--apply. It waits up to 100 s for Stripe's meter to hold the final usage before cancelling (Stripe counts events asynchronously, about 40-50 s). If a step fails or the wait runs out, run it again. Erasure runs from the dailyerase-closedjob;closing cancel-erasure --site S --note ...calls it off. - A hold from the account (canceled subscription, deleted customer, uncollectible invoice): fix it at Stripe, then
billing resolve-account --site S --note .... The push skips a site with an open account problem and does not count it as sent. - Stripe's own dunning should leave the subscription active after retries fail (Settings, Billing, Subscriptions and emails); a subscription Stripe cancels is held here, but the usage stops reaching an invoice.
Reports
Usage by month, the invoice preview and the billing status are available over the API, with a read key.