# Payments

**Current state: no payment rail is live.** Prices in manifests have `approved: false`.
They are inventory taken from service code, not offers. Do not pay for any listed service.

## Payment profiles (as declared in manifests)

| `rail` | What it is |
|---|---|
| `nevermined-credits` | Plan credits metered per MCP tool call. A credit has no fixed cash value; never infer one. |
| `x402-exact` | HTTP 402 challenge, then a signed stablecoin payment (`network` and `asset` in the profile). |
| `ground-truth-prepaid` | Owner-funded balance; quote, then budget lock, then idempotent purchase. |
| `free` | No payment. |

Each priced tool references one profile. `amount` is the price per `unit`; `max_amount`
is the most a single call can cost. Authorise against `max_amount` when present.

## Rules

1. Pay only within the cap your owner delegated for this service and rail.
2. Verify amount, receiver, asset and network against the manifest before signing.
3. Never auto-fund a balance or sign beyond delegated authority.
4. Never send provider or supplier credentials to a service.
5. Whether a valid empty result is charged is stated per tool (`empty_result_charged`).

## Errors and what to do

| Condition | Action |
|---|---|
| 401 / authentication failure | Follow the documented auth flow. Do not retry with other credentials. |
| 402 / payment required | Check the profile and the owner's cap. Pay only if both allow it. |
| 403 / rights, terms or scope denied | Stop. Ask the owner to act on their account. |
| 404 | Do not infer that a private record exists. |
| 409 / quote expired or input conflict | Resolve the existing operation before any new purchase. |
| 429 | Wait as instructed. Never loop paid calls. |
| 5xx or timeout before settlement is known | Check the operation or receipt, or replay with the same idempotency key. If still unknown, stop. |
| Paid delivery disabled / endpoint unpublished | Report unavailable. Do not route around the paywall. |

## Idempotency

The same idempotency key with the same input returns the stored result without a new charge.
A changed input with the same key is a conflict. A JSON-RPC request ID is not an
idempotency key.
