This page is for whoever runs this deployment and decides what its tenants pay. It covers the pricing strategy you set per provider, what an invoice is made of, when a tenant is credited without anybody asking, and the one correction the platform cannot make for itself. Tenants read Billing & plans instead; nothing on this page is shown to them.

The four strategies

Every provider is priced by exactly one strategy, and which one suits it depends on whether the provider knows what its own machines cost.

StrategyWhat it doesThe provider it suits
noneNothing is priced. Nodes on this provider carry no price at all — which is not a price of zero, it is the absence of one.Anything you are not charging for: a tenant's own hardware, a provider you are still setting up.
flatOne price per node hour, whatever the node asked for.A provider whose machines are all the same to you.
drfDominant Resource Fairness: you give what the whole machine costs you per hour — its total cost of ownership spread over its depreciation — and the capacity it has of each resource. A node pays that hourly cost times the share of it the node asks for, between the average share across the resources and the largest single one.Hardware you own and divide between nodes — a hypervisor host whose cost you know and whose capacity you can state.
markupA percentage added to the price the provider quotes. The quote is the price; the markup is your margin on it.A provider that prices its own machines — a public cloud with a plan list.

A drf strategy takes the total cost of ownership, the depreciation period in whole years, the capacity of each resource a node can ask for, and an optional margin percentage added to the hourly cost. Where between the average share and the largest one a node lands is the weight: 0.5, the midpoint, unless you set another through the API. The form does not offer it.

You set a strategy on the provider's card, on the Resource Providers page of any project that can see it. The card appears only for zone-scoped (Global) providers — an organization's or a project's own provider is that tenant's infrastructure and is never billed — and only to a viewer holding read_pricing_strategies at zone scope; manage_pricing_strategies adds the form. POST /api/billing/pricing-strategies/ writes the same thing, and refuses the same things.

A provider that quotes its own rates

A provider says in its offer whether it prices its own machines (see Authoring providers). That one flag decides which strategies make sense for it, and the platform holds you to it from both directions.

When you write. flat and drf are refused for a provider whose live offer says it quotes, and markup is refused for one that says it does not. Both come back as a validation failure on the strategy type. none fits either. A provider that has not offered anything yet contradicts nothing, so you can set its strategy before its plugin first connects; the offer decides how the strategy is read once it arrives.

When a node is priced. The offer wins over what is stored. A flat or drf strategy left on a provider that has since started quoting is treated as a markup of zero — the provider's quote is the price, and nothing is added to it — rather than pricing the node twice. Nothing is rewritten: the stored strategy comes back into effect if the provider stops quoting. The same holds the other way: a markup left on a provider that has stopped quoting has nothing to mark up, and that provider is unpriced until it quotes again. The provider's card says which of the two has happened, so a stored strategy that nobody is applying is never mistaken for one that is.

The flag belongs to each resource a provider offers, not to the provider as a whole. A provider with one region it can price and one it cannot prices each of them its own way.

The markup a node keeps

A node's markup is taken when the node is admitted and written onto its first price. Every later price the node is held at — the provider announces one whenever its own rates move — carries that same markup, copied unchanged.

So editing a markup never moves the price of a node that is already running. It applies to nodes admitted after the edit. If you need the new margin on existing nodes, they have to be replaced.

Rates are stored raw

Nothing is ever stored marked up. What is recorded against a node is the provider's own lines, at the provider's own rates, under the provider's own labels. The tenant's price is worked out when it is read: each rate times one plus the markup, summed per kind.

That is also the disclosure boundary. A tenant sees what they are charged — one figure per kind, and the total — and never the rates underneath or the margin over them. The raw lines and the markup are shown only to a reader holding read_pricing_strategies at zone scope. No view shows a tenant the margin.

What an invoice is made of

An invoice's usage lines are grouped by pool, and within a pool by what the line is for: compute, an operating-system licence, storage, network, an app licence, or other. A pool that ran Windows nodes on attached volumes bills a compute line, an OS-licence line and a storage line rather than one opaque amount.

Each line is the sum of its nodes over the period. A node's window opens when it was deployed — when the machine was materialised and held for the tenant — and closes when it was destroyed, and it stays open across agent disconnects and restarts. Within that window the time is split at every price change and each piece charged at the rate that was in force over it, at the tenant's rates. A node counts once toward its line's node count however many prices it was held at.

Money is exact decimal throughout. Each line is rounded to cents once; the invoice total is the sum of the rounded lines and is not rounded again. Hours are shown for reading and never used in the arithmetic.

Credits

A node the platform lost is credited back without anybody asking. What decides it is the cause the node ended with:

Credited backBilled
connect-timeout, vm-lost, crashed, appdata-unavailable, prepare-failedeverything else — an app that failed to install or start, exited non-zero, was killed, a configuration that could not work, a reboot that never came back, an ordinary stop, and a teardown the provider could not confirm after the tenant had already ended the node

The question the list answers is "did the tenant lose service they were holding?" A credit gives back the node's whole life — back as far as the last credit for that node, and never before the organization's first billing period — because a machine taken away mid-life was not the service that was paid for. A failure at either end of a life the tenant asked for is not that: a node that never deployed opened no window and bills nothing either way, and a cleanup problem after the tenant ended the node is the platform's to fix, not a month of service to give back.

Credits net inside the invoice they belong to, and an invoice never goes below zero. Whatever the credit cannot spend carries to the next draft, and carries again until it is used up. Every line stays at its own gross amount and the leftover is its own row, so the invoice a tenant reads adds up to what they are asked to pay.

Manual adjustments

POST /api/billing/invoices/{invoice}/adjustments is the operator's correction path, and the only one. It is not under /api/orgs/{org}, because adjusting an invoice is the platform's act rather than the organization's: it takes manage_invoice_adjustments at zone scope, which is a system owner's permission.

The body is three fields:

{
  "amount": "-12.40",
  "reason": "Price landed after the August period was settled",
  "idempotency_key": "aug-2026-reprice-p_d000000000c3"
}
  • amount is a signed decimal string: negative credits the tenant, positive charges them. A crediting adjustment behaves exactly like a credit a failure earned, carrying included.
  • reason is required and becomes the line's text on the invoice the tenant reads. Keep it to a sentence; 500 characters is the limit.
  • idempotency_key is required. Repeating it with the same amount and reason is accepted and writes nothing. Repeating it with a different correction is refused as a conflict — two corrections cannot share a key, and there is no way to know which of them the caller meant.

Adjustments only go on a draft, and an attempt on a finalized invoice is refused rather than quietly dropped — though a repeat of a key that already landed is still answered as the first one was, whatever the invoice has done since. They survive a regeneration: the cycle replaces the lines it computes, and a human's correction is not one of them.

Reach for it when the platform cannot correct itself. The case it exists for is a price that landed after the period it belongs to was already settled: the seconds are invoiced, the mark has moved past them, and no recomputation will revisit them.

Budgets

An organization's hourly ceilings, its default for its projects, and a project's own override are a core feature and are documented for tenants on the Organizations page. Nothing about them is operator configuration: the owners set them, the owners read them, and going over refuses the next node without touching anything already running.

What this composition adds is the money half of that message. When a ceiling first has no room, the organization's owners get an email — "Hourly budget reached" — saying since when, what the organization or project is running at per hour in USD, the ceiling it has hit, what the node that did not fit needed, and what that ceiling costs over a full month (730 hours) if it stays where it is. It says in as many words that nothing was stopped, and links to the budget page.

It is sent once per condition, not per refusal. A pool at its ceiling asks again on every pass, and one email per attempt would be a denial of service with a friendly subject line. The condition clearing sends nothing at all — the in-app notification resolves itself, and an inbox is not a status board.

The public price estimator

The landing page carries a cost estimator, and it is public: GET /api/billing/price-estimator/providers lists the providers it offers and what a visitor may choose for each, and GET /api/billing/price-estimate prices one shape. Neither takes authentication. A price nobody can establish — a provider that is not a live zone-scoped one, no strategy, a provider nobody can reach, a quote that is not a price — answers {"status": "unavailable"} at 200 rather than an error, so the page always renders.

A provider is listed when it has a strategy other than none and the estimator can actually price it. Self-hosted capacity keeps the default and stays out: what is listed here is what this deployment sells. A provider priced by your own arithmetic is listed only if its catalogue publishes, as numeric choices, every dimension that arithmetic divides by — a strategy that prices by vCPU against a catalogue with no vCPU choice would compute zero for every shape, and nothing an hour is not a price. A provider whose price is its own quote is listed whether or not there is anything to select, and its entry carries the whole catalogue: a cloud machine is chosen by region and instance type and image, not by two numbers, so the widget renders one control per published field exactly as the request composer does. Each entry says which of the two it is, and an App-data selector appears only where picking a tier would change the number.

A visitor may only name shapes the provider published — every key a catalogue field, every value one of its choices — so the estimate is a closed set and never a free-text box. A quote is asked through the same per-server cache the allocation pass uses, so a shape somebody has already asked about costs this deployment nothing to answer again, and the outbound traffic is bounded by the catalogue rather than by how many visitors there are. New shapes are budgeted per visitor address and per provider, and a visitor who exhausts that budget is told to try again shortly.

What comes back is the tenant's own view and nothing more: the hourly price, the currency, and the lines grouped by what is charged for, at user rates. A visitor never sees the provider's raw rates or the margin over them — the same disclosure rule the node page and the request form keep.

  • Billing & plans — what a tenant reads about plans, payment, and invoices.
  • Organizations — hourly budgets, roles, and limits.
  • Authoring providers — the offer flag and the quote contract behind markup.
  • Providers — where a provider's price comes from, in a tenant's words.
  • Pools — the three places a tenant is shown a price.