# Billing

> INFRO bills a software subscription; your own providers bill you for model usage. What each covers, how cost estimates are computed, and what a plan limit does.

Source: https://infro.io/docs/org/billing

You get two bills, from two companies, and they do not move together.

| Bill | From | For | Scales with |
| --- | --- | --- | --- |
| Model usage | Your AI providers | The inference your requests consume, on the accounts you connected, at the rates you negotiated with them | Your traffic |
| Subscription | INFRO | The control plane: gateway, request logs, cost attribution, budgets, policy, audit log | Your plan — never your tokens |

> **Note:** **INFRO takes 0% of model spend**, and that is structural rather than a promise: your requests run on your own accounts under your own credentials, so your provider invoices you and INFRO is not a party to the transaction. There is no arrangement under which we could take a share of it, and provider spend never appears on an INFRO invoice.

## What a plan is priced on

- **Gateway requests** per month, with a soft allowance.
- **Request history** — how long request metadata stays queryable.
- **Seats** — people with console access. Gateway keys are not seats.
- **Projects** — separate keys, budgets, policies and attribution.
- **Capabilities** — prompt capture on every plan, with a longer window as you climb; custom provider rates and OpenTelemetry export from Team; provider cost reconciliation, priority support, SSO and SCIM on Business.

Nothing INFRO sells is priced per token. A plan whose price moved with what your provider charged would put us back in the middle of your model spend, which is the arrangement this product exists to replace. The four plans and what each includes are on the [pricing page](https://infro.io/pricing).

## What counts as a request

- One inference request your application sends to the gateway counts once, whether it streams or not.
- **Retries and provider failover inside a single request do not add to the count.** One request you made is one request on your allowance, however many upstream attempts it took.
- Only requests that succeed count. A request refused before it reached a provider — a budget ceiling, a model your policy does not allow — or one that failed on every connection is recorded in your request log so you can see it, and does not count.
- **Every successful request the gateway serves counts, whichever way it came in.** That includes runs in the console Playground and its other test runs (a connection test, a decision test), generations in INFRO Studio, and answers served from INFRO's [response cache](https://infro.io/docs/features/caching). Each model call INFRO makes on your own connection for one of your requests — a classifier guardrail check, a route's prompt classifier, an evaluation of a served answer — is its own row in your request log and counts too.
- Console screens, sign-in, health checks, model-catalog reads and INFRO's own scheduled jobs are never counted.

The allowance resets at 00:00 UTC on the 1st of each calendar month, on monthly and annual subscriptions alike: an annual subscription buys twelve monthly allowances, not one pooled yearly quota. That is a different clock from `billing_day_of_month`, which is the reset day for the [budgets](https://infro.io/docs/org/spend-controls) you set against your *providers'* spend — the console labels each with its own date.

## The 14-day trial

Every plan can be tried for 14 days, and **a trial requires a card**. The order in the console is: name the organization and say how many people will use it, choose a plan and interval, then enter a card on the payment provider's checkout. There is no billing form in between, and nothing is created until you continue to that checkout. If INFRO has given you a promotion code, enter it on the checkout page. It changes the subscription price only, never the plan or what it includes. The trial starts when the checkout completes — not when you sign up — and connecting a provider, creating a gateway key and inviting teammates come after it.

- **The trial converts on its own.** At the end of day 14 the card is charged automatically for the plan and interval selected at that moment. The console shows the charge date and the amount throughout the trial, and we email you a few days before it.
- **Cancel before the trial ends and you won't be charged.** Cancel from the payment provider's portal, linked in the console; access continues until the trial end date and then stops. Changed your mind before then? On the Billing screen, **Resume trial** keeps the plan you had, and any other plan resumes the trial on that plan instead. Either way the trial keeps its original end date, and the plan you resumed on is the one charged when it ends.
- **Changing plan during a trial keeps the days you have left.** The 14 days are one trial, shared by every plan: the trial end date does not move when you switch, cancel or resume, and the plan you are on at the end is the one charged. Once the trial has ended, a new subscription is charged when it starts.
- **One trial per person.** A trial is counted against the person who starts it, across every organization they create or own. If you have already had one, checkout says so before you pay and the plan is charged the same day.
- **If the charge at the end of the trial fails**, the organization keeps access for **three days** while you update the card. After that access is suspended (`402` with code `trial_payment_failed`) and the subscription ends, so you are never charged later for time you could not use. Start a new subscription from the billing screen to resume.

**A trial includes everything in the chosen plan, with the same limits as the paid plan.** The same features, seats, projects, retention and request allowance — and past the allowance, requests keep being served and are counted, exactly as on the paid plan. Nothing is refused for being a trial, and nothing is charged per request.

While an organization has no active plan — its trial, paid period or payment grace has ended — it is **locked**. The gateway returns `402 subscription_required` to its requests, and the console, the Playground and Studio stay closed until a plan is active. What stays open is the way out: Billing, the organization's settings (transfer ownership, leave, delete), revoking keys and tokens, and your other organizations. A subscription cancelled with time left keeps full access until the end of the period it has paid for. **Nothing is deleted at any point**: your provider connections and their credentials, gateway keys, routes, budgets, policies, team and request history all remain, and everything works again the moment a plan is active.

## Going past the allowance

> **Warning:** **On a paid plan, overage is soft. The gateway does not drop production traffic over a plan limit.** Passing the request allowance is counted and shown on the billing screen, which offers the larger plan; it does not start refusing requests, and it does not raise a charge for the excess. The organization's owners, admins and billing contact are emailed once each when the month reaches **80%, 100% and 150%** of the allowance, with the count, the date it resets and the plan whose allowance fits; the billing screen and the `GET /v1/usage` count show where the month stands at any time. A software quota must never become an outage in your product — that is the whole reason a control plane is safe to put in the request path.

## Where cost figures come from

Every request carries `usage.cost`: what your provider will bill you for it — an **estimate**, unless the provider reported the figure itself. `usage.price_source` says where it came from.

| `price_source` | Meaning |
| --- | --- |
| `provider` | Reported by the provider in its own response for this request, and also returned as `usage.cost_usd`. Not an estimate; only some providers report it. |
| `custom_provider` | Your own negotiated rate **for the provider that served this request**. The most accurate figure INFRO can give you: a rate card belongs to one contract, and this is the rate from the contract the request actually ran under. |
| `custom` | Your own negotiated rate for this model, entered without naming a provider, and applied here. Right when you pay the same rate everywhere; approximate when you do not. |
| `list` | The **model vendor's** published rate. The default, and right for most accounts on that vendor's own API — an approximation on a cloud reseller, where the same model bills off a different rate card. |
| `gateway_cache` | Answered from INFRO's [response cache](https://infro.io/docs/features/caching). Your provider was not called and bills nothing for this request, so `cost` is a known `0`, never unpriced. The request record's `cache.estimated_provider_cost_avoided` holds the estimate recorded for the answer it replayed. |
| absent | The model is **unpriced** — no rate is known. `cost` is `null` rather than zero. |

A rate is set per model, and optionally per provider. The same model does not cost the same everywhere: `anthropic/claude-opus-5` bills off one rate card on a direct Anthropic account, another on AWS Bedrock and a third on Google Vertex. Set one rate for a model and it applies to every connection; set one for a specific provider and it wins for that provider, leaving the general rate to answer for the rest.

- The rate is applied **at serving time and stored**. Entering a new rate today does not rewrite what last month cost, and neither does a vendor changing their list price.
- **A provider rate and a general rate are never merged.** If your Bedrock rate names only input tokens, output falls through to the catalog rather than borrowing the general rate's output figure — a cost assembled from two different contracts appears on no invoice anywhere.
- An unpriced request contributes nothing to any total rather than being counted as zero, and totals that include one are reported as partial.
- **A budget cannot measure an unpriced request.** Its worst case is unknown, so while a blocking budget applies such a request is refused with `402` and code `unpriced_model_under_budget` by default. The organization owner can instead choose, under Budgets in the console, to serve unpriced traffic uncounted — the budget then does not govern it. The better remedy is a rate; the console flags every unpriced model.
- Your provider's own invoice is authoritative. These are estimates for planning and attribution.

## Estimating a request before you make it

`POST /v1/estimates` answers what a request would cost on your own provider account, before you make it: `model`, optionally `provider` (else the first of your connections that serves it), and the quantities — `n`, `size` or `resolution` and `quality` for images, `duration_seconds` for video and transcription, `characters` for speech, `input_tokens` and `output_tokens` for text. The answer is `estimated_cost` in USD (null with an `unpriced_reason` where no rate is known), the `price_source` and the rate with its tiers. Your negotiated rate for that provider is used where you have entered one, else the model vendor's list rate. It is the provider's charge to you, never INFRO's: INFRO bills the subscription only.

## Checking the estimates against your provider

An estimate can be checked. Connect a **read-only billing credential** under **Cost reports → Reconciliation** in the console and INFRO reads your provider's own cost API once a day, storing what they reported beside what it estimated for the same UTC day. What the console then shows is the *variance* — "estimated $4,182, OpenAI billed $4,194, variance 0.29%" — which is a stronger and more honest claim than either figure alone.

- **The billing credential is separate from the one that serves your requests, and always will be.** Your inference key is used to send requests and read the usage the provider reports back — never to read your account or your billing. Provider reporting needs an admin-scoped key that cannot serve inference at all, so it is a second credential with its own consent. It is stored encrypted and never shown again. INFRO uses documented read-only endpoints for costs and, where supported, organization, key-lifecycle and rate-limit metadata.
- **Missing provider data is not guessed.** OpenAI and Anthropic do not expose remaining provider account credit through these APIs, so the console says `unsupported` rather than showing zero or an estimated balance. Expiration is shown only when the provider exposes it and INFRO can unambiguously match the connected admin key.
- **Credential warnings are proactive.** INFRO checks supported inference credentials daily without making a billable generation, refreshes admin metadata during scheduled reconciliation, and alerts the organization's billing contact when a key is rejected, revoked, expired, or approaching a provider-reported expiration date.
- **It is entirely optional.** Connect none and you get estimates with no variance figure, which is exactly how the platform behaves today.
- **Reconciliation never rewrites a request's cost.** Both providers report daily and organization-wide, so attributing a reported total back to individual requests would invent precision they did not give. A request keeps the rate it was priced at.
- **A sustained one-way gap is a finding, not a report.** A single day's difference is usually timing — a request at 23:59 UTC lands in one system's day and the other's. A gap that holds becomes a finding that names its likely cause, such as a negotiated rate that was never entered, and can suggest a rate to apply. See [Cost reconciliation](https://infro.io/docs/cost/reconciliation).
- Available for **OpenAI** (an Admin key) and **Anthropic** (an `sk-ant-admin` key). Bedrock, Vertex and Azure keep their cost in the surrounding cloud's billing system, behind IAM unrelated to the inference credential; a provider without an integration shows no variance rather than a variance of zero.

> **Note:** Two documented gaps worth knowing before you compare a figure against an invoice: Anthropic's cost endpoint **excludes Priority Tier spend**, and it is unavailable for Claude on AWS. On an account using either, a variance will not close — and that is the provider's reporting, not your rates.

## Billing details belong to the organization

Each organization has its own billing contact: a billing email and a billing name. The first checkout sets them for you — the email of the person setting the organization up, and the organization's name — and the owner can change them at any time under Billing. From then on the contact belongs to the organization: changing your login email does not change it. Every organization needs its own billing email, so two organizations cannot share one; if yours already receives another organization's receipts, checkout asks for a different address first. Addresses, tax details and payment methods are collected on the payment provider's checkout and portal; INFRO stores no card data.

An organization's subscription, invoices and billing portal are its own: owning several organizations gives each one a separate subscription and a separate portal, and cancelling or changing one never affects another.

## Changing plans

Plan changes are made on the billing screen in the INFRO console — not in the payment provider's portal. The portal is where you update the payment method, read invoices and receipts, and cancel.

- **An upgrade applies immediately**, with a prorated charge for the rest of the current period.
- **A downgrade applies at the next renewal.** You keep the current plan until then, and there is no refund or credit for the current period.
- **During a trial** neither is charged when you make it: the plan selected when the trial ends is the one charged.

If the smaller plan includes fewer seats or projects than you are using, the console says which before you confirm. INFRO does not delete projects, remove members or revoke security controls to make a plan fit.

## Budgets are not payments

A `402 budget_exceeded` means a ceiling **you set** — on an organization, project, member or key — has no room for the request. Nothing is owed to INFRO and nothing is unpaid; the remedy is to raise or remove that budget, not to pay anybody. See [spend controls](https://infro.io/docs/org/spend-controls).

## Cancelling

Cancel from the payment provider's portal, linked in the console, at any time. Cancel during a trial and nothing is charged; access continues until the trial end date. Cancel a paid plan and it runs to the end of the period it paid for; after that the gateway stops serving requests for the organization. Until that date, **Resume** on the Billing screen undoes the cancellation, on the same plan or on any other you choose: a trial keeps its end date, and a paid plan renews as before (an upgrade applies at once with the prorated difference charged, a downgrade at the renewal). Cancellation does not delete your account configuration. Provider connections, gateway keys, routes, budgets, policies and team settings remain. Request history and optional payload logs remain subject to the retention windows in [Privacy](https://infro.io/docs/privacy); export needed records within those windows. A *failed renewal* is different from a cancellation: an established paid subscription we cannot collect keeps its entitlements through a 14-day grace period while we ask you to update the card, so an expired card does not take a production application down. See the [refund policy](https://infro.io/refund-policy).
