Skip to main content
Every selection response carries the usage receipt described here, and the same number enforces your per-request ceiling. Self-serve billing is prepaid: you add credit from the dashboard’s Wallet page and each request’s charge is debited from that balance. No invoices are raised against a prepaid balance.Ledger lines are typed, and only one type is a usage charge. A debit is what a request cost, and it carries the same input-token count and amount as that response’s receipt, so every usage debit is checkable against the receipt that produced it. A grant is credit we added, which is how your welcome credit arrives; a purchase is credit you added; and a refund returns credit to the balance. None of those three describes a request, so none carries a token count or a receipt to check it against. Reconcile against the debit lines.

One number, computed once

Every 200 carries a usage block. It is the same number the telemetry event records and the same number the wallet debit carries; there is no second computation anywhere for it to drift from. A 4xx carries an error envelope instead, with no usage block, because nothing was metered.
The measurement and the price are separate fields on purpose. A single field cannot be both “the input you submitted” and “zero when nothing is charged”: on a 100,000-token stand-down those are different numbers. Splitting them means the measurement is always verifiable and the price is always attributable.

Three versions that move independently

policy_version says what ran. meter_version says what a token means. price_version says what it costs. They are deliberately decoupled: a retune must not reprice anyone, and a repricing must not change anyone’s selection. If they were one field, every price change would look like a behaviour change and every retune would look like a price change.

What is metered

Every customer-supplied text field the engine processes:
That is the whole definition. It is computed at the boundary, from your request body, before the engine runs.

Recompute it yourself

The reference implementation, in Python and TypeScript, with a worked example.

What is not metered

tokens_before is not your bill. On this deployment it happens to work out to Σ estimate_tokens(record.text), so it is close enough to look like the meter, which is exactly why it is worth being explicit.It is not. The meter also counts record.title, task.prompt and task.recent_prompts, so input_tokens is the larger number. And tokens_before is an engine-internal budgeting quantity by definition: it is a per-record sum taking a maximum against the summary the engine holds, so it is free to move when engine internals move, while the meter is not.Budget against tokens_before. Reconcile a wallet debit against input_tokens.

Why input, and not tokens saved

Charging for tokens saved is the intuitive model and it is the wrong one, for two reasons we would rather state than have you infer.
  • It pays us more the more we cut. That is a direct incentive against answer quality: the vendor’s interest and yours point in opposite directions on every request.
  • It is unstable. A retune would change your bill for identical inputs, making your charges a function of our tuning decisions rather than of your usage.
Charging on submitted input has its own incentive, and it is worth naming: we are paid more when you send more. The difference is that you observe and control that directly, and our own shadow report is an argument for sending less.

The charge

There is no per-request minimum fee. charge_multiplier is carried on the receipt for exactly this reason: you never have to look up which multiplier applied to a given request.
An empty response is not proof of a free request. escalated returns nothing while carrying charge_multiplier: "1.0". Do not infer the charge from records_selected, from rendered_context, or from tokens_saved. None of those price anything.charge_multiplier tells you whether, and at what fraction, you were charged. It is not the amount: the amount also depends on input_tokens and on the rate for your price_version. See The charge for the formula.
The rate card is public. Under price_version npp-2026-08-r1, the rate is $0.09 per 1,000,000 metered input tokens, in USD. A rate card is immutable once named: a repricing mints a new price_version and leaves this one alone, so a receipt always resolves to the rate that was in force when it was written.The dashboard’s estimated savings figure is a different number on purpose: it prices the tokens Needlepath removed at a stated reference of $5 per 1M tokens (a typical frontier-model input price) because what you save is denominated in what your downstream model would have charged you, not in what we charge. The tile names the assumption so you can recompute it.

Escalation is charged

escalated means the engine could not fit a selection inside the capacity your request allowed. The response is a real one with nothing in it: records_selected is 0, rendered_context is empty, the status is 200, and usage.charge_multiplier is "1.0". The rule is the same one that applies everywhere else on this page: you are charged for the input you submitted, not for the size of what came back. An escalated request processed all of that input. By the time the engine can tell that nothing will fit, it has already searched the full record set, tried every budget it was allowed to try, and assembled and measured the complete context. Whether a selection fits is not knowable until after that work is done. How to avoid it. The capacity the engine must fit inside is normally governed by budget.max_context_tokens, so the levers are on your side of the call:
  • Raise budget.max_context_tokens to something your downstream call will actually accept. Escalation means the value you sent was too small for the records you sent with it.
  • Send fewer records. A smaller record set is less likely to escalate under the same budget. It does not guarantee a selection: the engine may still decide the set is not worth acting on and stand down, which is free.
The escalated response carries format_metrics.capacity_cap_tokens (the capacity that applied) and format_metrics.attempted_recall_rungs (what the engine tried before giving up). Those tell you what the engine was working with. They do not tell you which of the two levers above will fix it, so treat them as a starting point for a retry rather than a diagnosis.
Escalation depends on the operating point you run. It comes from operating points that enforce a capacity cap, so whether you can reach it at all depends on the label that ran. It is reachable on np-2026-08-r3.Do not assume the same request is free on another label. A request that escalates on one operating point may engage and be charged at the full rate on another, or it may stand down for nothing. Both happen. The outcome is a property of the request and the label together, not of the label alone.Operating point labels are immutable, so check policy_version on the response for the label that actually ran.
If you do not send budget.operating_point, your requests run on whatever the current default is, and that default can change. A change of default can move a request from one outcome to another, including from an outcome that costs nothing to one that is charged at the full rate. Nothing about your own code has to change for that to happen.Pin budget.operating_point on every request if you need billing behaviour to be stable. A pinned label is immutable, so its behaviour cannot move under you. Pinning is the only mechanism that makes you independent of a change of default.

Cases people ask about

Rounding never reaches the ledger

Every wallet debit is posted at its exact amount: under npp-2026-08-r1 the per-request charge is exact for every whole token count, so nothing is rounded away per request. Rounding happens only at display, which is why a small request can show as $0.000042 rather than a $0.00 that hides it. Per-request rounding of sub-cent amounts is how a million small requests silently stop summing to their own receipts; here the ledger and the receipts sum to the same number by construction.

Disputing a debit

Every debit on the Wallet ledger carries the same input-token count and amount as the receipt that produced it, so the first check is a lookup, not a computation. If you want to go further, we cannot show you your records, because we never had them. What we can show you is better:
1

You hold the payload

You sent it. We did not keep it.
2

We publish the function

estimate_tokens is published in full, including a reference implementation you can run.
3

The receipt names the version

meter_version pins which definition applied to that request.
So you can recompute the debit yourself, exactly, without taking our word for anything. That is a stronger audit story than “trust our logs”, and it exists because the meter is a pure function of your request body rather than in spite of it.

How to recompute your own bill

Step by step, with runnable code.