# Nevermined Catalog

> Discover and pay for services from the Nevermined Catalog using a spend-capped budget.

- name: io.github.nevermined-io/catalog
- version: 1.75.0
- connection class: R0 (autonomous)
- trust: 97/100
- quality: 63/100 (needs work)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.nevermined-io%2Fcatalog
- tools: https://api.protogrid.dev/v1/servers/io.github.nevermined-io%2Fcatalog/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "catalog": {
      "type": "http",
      "url": "https://mcp.live.nevermined.app/mcp",
      "headers": {
        "Authorization": "Bearer ${CATALOG_TOKEN}"
      }
    }
  }
}
```

Placeholders to fill: `${CATALOG_TOKEN}`.

## Trust

- hygiene: 100
- liveness: 100
- freshness: 100
- provenance: 90
- drivers: +repository +namespace-matches-repo +website +reachable +uptime-100% +updated-0d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 63/100 (needs work)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 71 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 8 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 13 of 13 tools declare readOnlyHint or destructiveHint
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: list_payments (destructiveHint, idempotentHint, openWorldHint); list_categories (destructiveHint, idempotentHint, openWorldHint); get_subscription_checkout (destructiveHint, idempotentHint, openWorldHint); …
- warn `tools.token_cost`: about 9,822 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 25 (weight 15)

- warn `stability.changes`: 25 tool changes in 30 days
- fail `stability.rug_pull`: 1 tools kept their name but changed most of their description in 30 days; review before trusting them

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 13, about 9,822 tokens to load them all
- tool set hash: 6d0bcf4761e408136f57334baecb27f8
- tools last changed: 2026-10-20T14:43:49.562Z
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.nevermined-io/catalog.svg)](https://protogrid.dev/servers/io.github.nevermined-io/catalog)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-10-20 `get_subscription_checkout` changed (description)
  - before: Read your personal subscription balance and get the link the human opens to subscribe or manage their allowance when credits are short. Charges nothing and never starts a paid checkout. One-time credit top-ups are not currently offered; an existing subscriber gets the dashboard and reset date. After the human finishes checkout, use get_budget to verify the credits, then retry pay_service. OAuth commerce connections must explicitly grant subscription credits.
  - after: Read your personal subscription balance and get the link the human opens to subscribe or manage their allowance when credits are short. Charges nothing and never starts a paid checkout. One-time credit top-ups are not currently offered; an existing subscriber gets the dashboard and reset date. After the human finishes checkout, use get_budget to verify the credits, then retry pay_service. OAuth commerce connections must explicitly grant Nevermined credits.
- 2026-10-20 `wallet_balance` changed (description, annotations)
  - before: Read the balances of YOUR OWN PERSONAL wallet — the funding source the crypto rails PULL from when pay_service charges a PERSONAL delegation. It answers `how much do I have, and on which chain`. Reading costs nothing and charges nothing. WHAT IT DOES NOT COVER, so you do not mis-diagnose: a delegation backed by an ORGANIZATION wallet is paid from that wallet, not this one; and a CARD delegation has no wallet at all — there `BCK.ROUTER.0009` is the card ISSUER declining, with nothing to top up, so this tool does not apply and the answer is a different card. BY RAIL: on MPP the wallet is checked BEFORE anything is signed, and the `BCK.ROUTER.0009` you get back already names the wallet and the chain — what it never says is HOW MUCH is there, which is what this tool supplies. On x402 there is NO balance pre-check and `BCK.ROUTER.0009` is never raised: the credential is minted, budget is reserved, and a short wallet only surfaces when the merchant's on-chain transfer fails — by which point your budget is already committed, and the reserve comes back only once the reconciler has seen the authorization expire unconsumed. So on that rail read the balance BEFORE you pay, not after. By default this reports EVERY network this deployment settles on, and you must read the one the merchant quoted: a healthy balance on one chain says NOTHING about the other, and most services settle on only one of them. Pass `network` (a chain id) to read a single chain. A token whose `atomic`/`formatted` is `null` was NOT READ (the on-chain read failed) — that is not a zero balance, and reporting it as empty is wrong; a chain that could not be read at all comes back as an entry with `error` instead of `balances`. This tool diagnoses and fixes nothing: there is no on-ramp and you cannot top your own wallet up, so a genuine shortfall is a stop condition — report the network and the amount to your human, and do not retry the payment. Each entry with `balances` also carries `lockedInChannels` when the API reports it, per token (`atomic` in the token's smallest unit, `formatted`, `symbol`): money your payer wallet (the one the Router signs MPP payments with, which is this wallet once your account is migrated) has deposited into payment channels with merchants that charge per call over an MPP session, held in the channel's escrow. It is NOT part of `balances` and it is NOT spent: it is still the human's. It can pay further calls only to the merchant holding that channel, never anyone else, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use. Report it beside the balance, never as spending, and never count it toward paying any other merchant. Here a null `symbol`/`decimals`/`formatted` means a token Nevermined does not recognise, NOT an unread amount: report `atomic` as raw units of `token`. An empty list means nothing is locked; `lockedInChannels: null` means it could not be read, which is not the same as nothing locked. When you have a Nevermined Subscription the result also carries `subscription` (the credits left in your monthly allowance, reset date and plan, as in get_budget): that allowance is not held in this wallet and is not money; subscription calls are paid by Nevermined, not from this wallet. Requires your Nevermined API key on the Authorization header.
  - after: Read the balances of YOUR OWN PERSONAL wallet — the funding source the crypto rails PULL from when pay_service charges a PERSONAL delegation. It answers `how much do I have, and on which chain`. Reading costs nothing and charges nothing. WHAT IT DOES NOT COVER, so you do not mis-diagnose: a delegation backed by an ORGANIZATION wallet is paid from that wallet, not this one; and a CARD delegation has no wallet at all — there `BCK.ROUTER.0009` is the card ISSUER declining, with nothing to top up, so this tool does not apply and the answer is a different card. BY RAIL: on MPP the wallet is checked BEFORE anything is signed, and the `BCK.ROUTER.0009` you get back already names the wallet and the chain — what it never says is HOW MUCH is there, which is what this tool supplies. On x402 there is NO balance pre-check and `BCK.ROUTER.0009` is never raised: the credential is minted, budget is reserved, and a short wallet only surfaces when the merchant's on-chain transfer fails — by which point your budget is already committed, and the reserve comes back only once the reconciler has seen the authorization expire unconsumed. So on that rail read the balance BEFORE you pay, not after. By default this reports EVERY network this deployment settles on, and you must read the one the merchant quoted: a healthy balance on one chain says NOTHING about the other, and most services settle on only one of them. Pass `network` (a chain id) to read a single chain. A token whose `atomic`/`formatted` is `null` was NOT READ (the on-chain read failed) — that is not a zero balance, and reporting it as empty is wrong; a chain that could not be read at all comes back as an entry with `error` instead of `balances`. This tool diagnoses and fixes nothing: there is no on-ramp and you cannot top your own wallet up, so a genuine shortfall is a stop condition — report the network and the amount to your human, and do not retry the payment. Each entry with `balances` also carries `lockedInChannels` when the API reports it, per token (`atomic` in the token's smallest unit, `formatted`, `symbol`): money your payer wallet (the one the Router signs MPP payments with, which is this wallet once your account is migrated) has deposited into payment channels with merchants that charge per call over an MPP session, held in the channel's escrow. It is NOT part of `balances` and it is NOT spent: it is still the human's. It can pay further calls only to the merchant holding that channel, never anyone else, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use. Report it beside the balance, never as spending, and never count it toward paying any other merchant. Here a null `symbol`/`decimals`/`formatted` means a token Nevermined does not recognise, NOT an unread amount: report `atomic` as raw units of `token`. An empty list means nothing is locked; `lockedInChannels: null` means it could not be read, which is not the same as nothing locked. When you have a Nevermined Subscription the result also carries `subscription` (the credits left, reset date and plan, as in get_budget), and whenever you hold credits, subscribed or not, `credits` (total, spendable and by kind and expiry, as in get_budget): credits are not held in this wallet and are not money; calls paid with credits are paid by Nevermined, not from this wallet. Requires your Nevermined API key on the Authorization header.
- 2026-10-20 `payment_summary` changed (annotations)
- 2026-10-20 `list_payments` changed (description, annotations)
  - before: List your Router payments: the unified ledger across every service and delegation, newest first, at most 1000 records. Each record carries its `id` (the `paymentId` get_payment_result takes), `createdAt`, `status`, `protocol`, `network`, `requestId`, `delegationId` and `amount` in the asset's smallest unit (see `assetDecimals`), not in cents. Each row also carries `deliveryStatus`: `delivered` (request settled), `charged_not_delivered` (request failed and the merchant charge was observed), `charged_unconfirmed` (charge observed; delivery unconfirmed), `not_charged` (reconciliation proved no merchant charge), or `pending` (charge outcome unknown). On SPT and card rails, `pending` is not proof of no charge; flag `charged_not_delivered` to the user. Use this tool to reconcile an uncertain payment or find a paymentId; it does not return service responses (use get_payment_result) or the remaining budget (use get_budget, whose figures include fees and rounding). Reading costs nothing. Requires your Nevermined API key on the Authorization header.
  - after: List your Router payments: the unified ledger across every service and delegation, newest first, at most 1000 records. Each record carries its `id` (the `paymentId` get_payment_result takes), `createdAt`, `status`, `protocol`, `network`, `requestId`, `delegationId` and `amount` in the asset's smallest unit (see `assetDecimals`), not in cents. Each row also carries `deliveryStatus`: `delivered` (request settled), `charged_not_delivered` (request failed and the merchant charge was observed), `charged_unconfirmed` (charge observed; delivery unconfirmed), `not_charged` (reconciliation proved no merchant charge), `not_delivered` (the merchant answered with an error, so nothing was delivered, and no charge has been seen: the amount stays reserved until reconciliation decides, after the payment authorization expires, whether the merchant charged; it is not a charge), or `pending` (charge outcome unknown). On SPT and card rails, `pending` is not proof of no charge; flag `charged_not_delivered` to the user. Use this tool to reconcile an uncertain payment or find a paymentId; it does not return service responses (use get_payment_result) or the remaining budget (use get_budget, whose figures include fees and rounding). Reading costs nothing. Requires your Nevermined API key on the Authorization header.
- 2026-10-20 `get_payment_result` changed (annotations)
- 2026-10-20 `get_budget` changed (description, annotations)
  - before: Read the spending budget pay_service spends from: its cap, what has been spent, what remains, how many payments were made (and the limit, if any), and when it expires. Reading costs nothing and charges nothing. Use it whenever the human asks how much is left, or before a run of paid calls. Money is in CENTS: `capCents` is whole cents; `spentCents` and `remainingCents` can carry up to four decimals because the budget is charged per call at 1/10,000 of a cent (e.g. `"1.632"` = 1.632¢), and `spentCents + remainingCents = capCents` while the budget is within its cap. Tell the human `message` as it stands and never substitute a figure of your own: the budget includes routing fees and rounding, so adding up your calls will not match it. With no `delegationId` it reads the budget pay_service would use; that only includes budgets that can still pay, so `{"status":"no_active_delegation"}` also covers a budget that ran out or expired — pass the `delegationId` from an earlier pay_service result to read that one anyway. On a deployment that reports it, `spentByDeliveryStatusCents` splits the spend by what each payment delivered (`delivered`, `charged_not_delivered`, `charged_unconfirmed`, `not_charged`, `pending`, the `deliveryStatus` values list_payments uses), and `unattributedSpentCents` is spend no payment record itemizes; a non-zero `charged_not_delivered` is what was spent on calls that delivered nothing although the merchant charged (the merchant charge plus any routing fee not given back), so tell the human. `lockedInChannels`, when present, is money the wallet this budget pays from has deposited into payment channels with merchants that charge per call (per token, as in wallet_balance). It is that WALLET's total, shared by every budget paying from it, not a figure of this budget's own: it is NOT spent and NOT charged to this budget, it can pay further calls only to the merchant holding each channel, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use; `message` then says so. An empty list means nothing is locked; `null` means it could not be read, and `message` then says that too. When you have a Nevermined Subscription the result also carries `subscription` (`creditsLeft`, a digit string of credits spendable now; `resetsAt`, when they expire and, unless `cancelAtPeriodEnd`, the next period's are granted; `status`, `suspended` and `plan`) and `subscriptionMessage` to relay as it stands; `subscription.subscribed: false` means none. Never count credits yourself. Requires your Nevermined API key on the Authorization header.
  - after: Read the spending budget pay_service spends from: its cap, what has been spent, what remains, how many payments were made (and the limit, if any), and when it expires. Reading costs nothing and charges nothing. Use it whenever the human asks how much is left, or before a run of paid calls. Money is in CENTS: `capCents` is whole cents; `spentCents` and `remainingCents` can carry up to four decimals because the budget is charged per call at 1/10,000 of a cent (e.g. `"1.632"` = 1.632¢), and `spentCents + remainingCents = capCents` while the budget is within its cap. Tell the human `message` as it stands and never substitute a figure of your own: the budget includes routing fees and rounding, so adding up your calls will not match it. With no `delegationId` it reads the budget pay_service would use; that only includes budgets that can still pay, so `{"status":"no_active_delegation"}` also covers a budget that ran out or expired — pass the `delegationId` from an earlier pay_service result to read that one anyway. On a deployment that reports it, `spentByDeliveryStatusCents` splits the spend by what each payment delivered (`delivered`, `charged_not_delivered`, `charged_unconfirmed`, `not_charged`, `not_delivered`, `pending`, the `deliveryStatus` values list_payments uses), and `unattributedSpentCents` is spend no payment record itemizes; a non-zero `charged_not_delivered` is what was spent on calls that delivered nothing although the merchant charged (the merchant charge plus any routing fee not given back), so tell the human. `not_delivered` is held for calls the merchant answered with an error: not a charge, it comes back unless the merchant redeems the payment before its authorization expires (an older deployment reports it inside `pending`). `lockedInChannels`, when present, is money the wallet this budget pays from has deposited into payment channels with merchants that charge per call (per token, as in wallet_balance). It is that WALLET's total, shared by every budget paying from it, not a figure of this budget's own: it is NOT spent and NOT charged to this budget, it can pay further calls only to the merchant holding each channel, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use; `message` then says so. An empty list means nothing is locked; `null` means it could not be read, and `message` then says that too. When you have a Nevermined Subscription the result also carries `subscription` (`creditsLeft`, a digit string of every unexpired credit; `resetsAt`, when the allowance expires and, unless `cancelAtPeriodEnd`, the next period's is granted; `status`, `suspended` and `plan`) and `subscriptionMessage` to relay as it stands; `subscription.subscribed: false` means none. Whether or not you subscribe, it also carries `credits` (`null`: could not be read, which is not the same as none): `total`, `spendable` (what can pay a call now), `parts` (`kind` allowance | welcome | topup | sla, `credits`, `expiresAt` — null never expires — and `frozen`: null, `renewal_overdue` for allowance credits frozen until a renewal payment goes through, `dispute` for every credit while a card dispute holds them) and `nextExpiry`, with `creditsMessage` to relay as it stands. Every amount is a digit string. Never count credits yourself. Requires your Nevermined API key on the Authorization header.
- 2026-10-20 `setup_delegation` changed (annotations)
- 2026-10-20 `route_by_intent` changed (annotations)
- 2026-10-20 `quote_service` changed (description, annotations)
  - before: Price ONE call to a catalog service WITHOUT paying it: it charges nothing, signs nothing and reserves no budget. Pass exactly what you would pass to `pay_service` (the same `slug`, `path`, `method`, `search`, `headers`, `body` and `delegationId`): the Router sends that request to the service unpaid, reads the price it asks for, and returns an opaque `quoteId`, its short `expiresAt`, the rail (`protocol`), the network and merchant amount (`settlement`) and the fee-inclusive total (`fee.capChargedCents`, whole cents rounded up; `fee.capChargedMicros` exact, in 1/10,000 of a cent). Unlike the `quote` on a get_service endpoint (the last merchant price the catalog observed, routing fee excluded), this is priced live for your exact request and includes the fee. Because the request really reaches the service, a service that does not charge for it performs it, so take care quoting a method with side effects; and a quote spends the same per-service rate limit as a payment, so quote once per decision rather than polling. It prices the delegation pay_service would charge (`optionSet: "delegation"`, naming its `delegationId`), or, with no delegation set up, what a personal crypto delegation would select (`optionSet: "deployment"`); in that case `nextTool` is `setup_delegation`: set one up and quote again before paying, since the delegation you create can select a different rail and price. It checks neither your remaining budget nor your wallet balance (see get_budget and wallet_balance). Next step (`nextTool: "pay_service"`): if `fee.capChargedCents` fits what you planned to spend, call `pay_service` before expiry with the same arguments, the quoted `delegationId`, `quoteId`, and `maxTotalCents` set to that figure as a number. The quote id fixes the exact challenge and fee-inclusive total while `maxTotalCents` remains an independent ceiling. `paymentRequired: false` means the service did not ask for payment for this request; `upstreamStatus` is its answer, and a non-2xx usually means the path, method or body is wrong. The service response itself is never returned. Outcomes, all charging nothing: `{"payable":false}`, `service_not_found`, `catalog_unavailable` and `delegation_lookup_failed` as in pay_service; `quote_unavailable` (no quote can be made here and retrying will not change that, so bound the price with pay_service `maxTotalCents` instead); `quote_failed` (the Router refused to price the call, or did not answer; see `code`, `message` and `retryable`); `credential_refused` (re-authorize). FUNDING (`funding`): chosen as pay_service would choose it. When you hold an active Nevermined Subscription and the endpoint carries a subscription tariff the answer is `{"funding":"subscription","credits":…,"tariffVersion":…}`: the credits one call costs from the published tariff (the service is not contacted, and there is no `quoteId` or cent total); then call pay_service with the same arguments. The credits left in your monthly allowance and the price ceiling are checked only when pay_service makes the call, so this answer does not promise the call will be paid with credits. Pass `funding: "delegation"` to price the delegation instead. Subscription refusals are named as in pay_service. Requires your Nevermined API key on the Authorization header.
  - after: Price ONE call to a catalog service WITHOUT paying it: it charges nothing, signs nothing and reserves no budget. Pass exactly what you would pass to `pay_service` (the same `slug`, `path`, `method`, `search`, `headers`, `body` and `delegationId`): the Router sends that request to the service unpaid, reads the price it asks for, and returns an opaque `quoteId`, its short `expiresAt`, the rail (`protocol`), the network and merchant amount (`settlement`) and the fee-inclusive total (`fee.capChargedCents`, whole cents rounded up; `fee.capChargedMicros` exact, in 1/10,000 of a cent). Unlike the `quote` on a get_service endpoint (the last merchant price the catalog observed, routing fee excluded), this is priced live for your exact request and includes the fee. Because the request really reaches the service, a service that does not charge for it performs it, so take care quoting a method with side effects; and a quote spends the same per-service rate limit as a payment, so quote once per decision rather than polling. It prices the delegation pay_service would charge (`optionSet: "delegation"`, naming its `delegationId`), or, with no delegation set up, what a personal crypto delegation would select (`optionSet: "deployment"`); in that case `nextTool` is `setup_delegation`: set one up and quote again before paying, since the delegation you create can select a different rail and price. It checks neither your remaining budget nor your wallet balance (see get_budget and wallet_balance). Next step (`nextTool: "pay_service"`): if `fee.capChargedCents` fits what you planned to spend, call `pay_service` before expiry with the same arguments, the quoted `delegationId`, `quoteId`, and `maxTotalCents` set to that figure as a number. The quote id fixes the exact challenge and fee-inclusive total while `maxTotalCents` remains an independent ceiling. `paymentRequired: false` means the service did not ask for payment for this request; `upstreamStatus` is its answer, and a non-2xx usually means the path, method or body is wrong. The service response itself is never returned. Outcomes, all charging nothing: `{"payable":false}`, `service_not_found`, `catalog_unavailable` and `delegation_lookup_failed` as in pay_service; `quote_unavailable` (no quote can be made here and retrying will not change that, so bound the price with pay_service `maxTotalCents` instead); `quote_failed` (the Router refused to price the call, or did not answer; see `code`, `message` and `retryable`); `credential_refused` (re-authorize). FUNDING (`funding`): chosen as pay_service would choose it. When you hold Nevermined credits that can pay it (a Nevermined Subscription allowance, welcome or top-up credits) and the endpoint carries a credits tariff the answer is `{"funding":"subscription","credits":…,"tariffVersion":…}`: the credits one call costs from the published tariff (the service is not contacted, and there is no `quoteId` or cent total); then call pay_service with the same arguments. The credits left and the price ceiling are checked only when pay_service makes the call, so this answer does not promise the call will be paid with credits. Pass `funding: "delegation"` to price the delegation instead. Subscription refusals are named as in pay_service. Requires your Nevermined API key on the Authorization header.
- 2026-10-20 `pay_service` changed (description, annotations)
  - before: Pay for a catalog service from your spend-capped delegation and return the vendor response. This charges real funds. Call `get_service` FIRST: its `requestShape.endpoints[]` lists the callable paths with their HTTP method and price, and each `payServiceArgs` is the `slug`/`path`/`method` to pass here, after replacing any `pathParams` placeholder in `path` with a real value. A bare slug reaches the service base URL, which for a multi-endpoint API answers 404 instead of a payment challenge; only a single-endpoint service is called by slug alone. Send the endpoint's `payServiceArgs`: they carry an example only when it is `paid-run` or `challenge`. A `docs` example (and its `invokePath`) is unverified — use it only deliberately, filling any path parameter with the entity you want; otherwise build `body` from the endpoint description or the provider's docs. `method` may be omitted: it is taken from the catalog endpoint matching `path` (POST when the catalog names none) and echoed back under `request`. To accept a live quote, pass its `quoteId` before `expiresAt` with the exact same call arguments; the Router uses that cached challenge and exact fee-inclusive total. Keep `maxTotalCents` as an independent ceiling. Repeating an identical call (same arguments, no `fresh`) charges nothing new: on a deployment running API 1.48 or later it is answered within 24 hours from the first call's stored result, or its `pending` answer; on an older deployment it comes back as `already_paid`. For an ASYNC service, where you submit once and then poll a status endpoint with the same id, set `fresh: true` on every poll INCLUDING THE FIRST: otherwise each later poll reuses the first poll's idempotency key and gets the first poll's stored answer (or `already_paid`) back, so the status never advances. `fresh` makes each poll a distinct, separately billed call (the merchant charges per status call). Leave `fresh` off the submit and off any retry of a call whose outcome is unsure, because with `fresh` a retry is not de-duplicated and is charged again. A completed call returns `paid`, `upstreamStatus` (the vendor's HTTP status) and `response` (its body); `paid: true` with a non-2xx `upstreamStatus` may still have cost the merchant price. Outcomes to act on: `{"status":"pending"}` means the payment was made and the service is still working; call `get_payment_result` with its `paymentId` every few seconds instead of calling pay_service again. `{"status":"already_paid"}` means this call's idempotency key already carries a payment whose result is not replayed here (the original call failed, its 24-hour result expired, the `requestId` was reused for a different request, or the deployment predates result replay, API 1.48); nothing new was charged, and it does not by itself say whether the original succeeded. Read the original with `get_payment_result` (`paymentId`) or `list_payments`. A new `requestId` starts a separate, separately charged purchase: use one only after that read shows the original failed and the human still wants the result. `{"error":"payment_indeterminate"}` means the charge may or may not have landed: check `list_payments` first, and to retry reuse the returned `requestId` verbatim without `fresh` so the retry stays idempotent. `{"error":"per_call_max_exceeded"}` means no charge; raise `maxTotalCents` only after a deliberate decision and retry with the same requestId. `quote_not_found`, `quote_expired`, and `quote_mismatch` are named no-charge quote refusals; quote again rather than paying unpinned. `{"error":"payment_failed"}` is a definite decline (see `code`, `message` and `retryable`). These charge nothing: `{"payable":false}` (not payable via the Router; no upstream URL is ever returned), `service_not_found` (wrong slug), `catalog_unavailable` and `delegation_lookup_failed` (transient; retry later), `no_delegation` (call `setup_delegation`), `router_controls_unavailable` (the API behind this server is too old to enforce `search`, `quoteId`
  - after: Pay for a catalog service from your spend-capped delegation and return the vendor response. This charges real funds. Call `get_service` FIRST: its `requestShape.endpoints[]` lists the callable paths with their HTTP method and price, and each `payServiceArgs` is the `slug`/`path`/`method` to pass here, after replacing any `pathParams` placeholder in `path` with a real value. A bare slug reaches the service base URL, which for a multi-endpoint API answers 404 instead of a payment challenge; only a single-endpoint service is called by slug alone. Send the endpoint's `payServiceArgs`: they carry an example only when it is `paid-run` or `challenge`. A `docs` example (and its `invokePath`) is unverified — use it only deliberately, filling any path parameter with the entity you want; otherwise build `body` from the endpoint description or the provider's docs. `method` may be omitted: it is taken from the catalog endpoint matching `path` (POST when the catalog names none) and echoed back under `request`. To accept a live quote, pass its `quoteId` before `expiresAt` with the exact same call arguments; the Router uses that cached challenge and exact fee-inclusive total. Keep `maxTotalCents` as an independent ceiling. Repeating an identical call (same arguments, no `fresh`) charges nothing new: on a deployment running API 1.48 or later it is answered within 24 hours from the first call's stored result, or its `pending` answer; on an older deployment it comes back as `already_paid`. For an ASYNC service, where you submit once and then poll a status endpoint with the same id, set `fresh: true` on every poll INCLUDING THE FIRST: otherwise each later poll reuses the first poll's idempotency key and gets the first poll's stored answer (or `already_paid`) back, so the status never advances. `fresh` makes each poll a distinct, separately billed call (the merchant charges per status call). Leave `fresh` off the submit and off any retry of a call whose outcome is unsure, because with `fresh` a retry is not de-duplicated and is charged again. A completed call returns `paid`, `upstreamStatus` (the vendor's HTTP status) and `response` (its body); `paid: true` with a non-2xx `upstreamStatus` may still have cost the merchant price. Outcomes to act on: `{"status":"pending"}` means the payment was made and the service is still working; call `get_payment_result` with its `paymentId` every few seconds instead of calling pay_service again. `{"status":"already_paid"}` means this call's idempotency key already carries a payment whose result is not replayed here (the original call failed, its 24-hour result expired, the `requestId` was reused for a different request, or the deployment predates result replay, API 1.48); nothing new was charged, and it does not by itself say whether the original succeeded. Read the original with `get_payment_result` (`paymentId`) or `list_payments`. A new `requestId` starts a separate, separately charged purchase: use one only after that read shows the original failed and the human still wants the result. `{"error":"payment_indeterminate"}` means the charge may or may not have landed: check `list_payments` first, and to retry reuse the returned `requestId` verbatim without `fresh` so the retry stays idempotent. `{"error":"per_call_max_exceeded"}` means no charge; raise `maxTotalCents` only after a deliberate decision and retry with the same requestId. `quote_not_found`, `quote_expired`, and `quote_mismatch` are named no-charge quote refusals; quote again rather than paying unpinned. `{"error":"payment_failed"}` is a definite decline (see `code`, `message` and `retryable`). These charge nothing: `{"payable":false}` (not payable via the Router; no upstream URL is ever returned), `service_not_found` (wrong slug), `catalog_unavailable` and `delegation_lookup_failed` (transient; retry later), `no_delegation` (call `setup_delegation`), `router_controls_unavailable` (the API behind this server is too old to enforce `search`, `quoteId`

Full history: https://api.protogrid.dev/v1/servers/io.github.nevermined-io%2Fcatalog/changes

## Remotes

- https://mcp.live.nevermined.app/mcp (streamable-http, auth none, reachable true, uptime30d 1)

## Packages

_none_

## Tools (13)

- `get_budget`: Read the spending budget pay_service spends from: its cap, what has been spent, what remains, how many payments were made (and the limit, if any), and when it expires. Reading costs nothing and charges nothing. Use it whenever the human asks how much is left, or before a run of paid calls. Money is in CENTS: `capCents` is whole cents; `spentCents` and `remainingCents` can carry up to four decimals because the budget is charged per call at 1/10,000 of a cent (e.g. `"1.632"` = 1.632¢), and `spentCents + remainingCents = capCents` while the budget is within its cap. Tell the human `message` as it stands and never substitute a figure of your own: the budget includes routing fees and rounding, so adding up your calls will not match it. With no `delegationId` it reads the budget pay_service would use; that only includes budgets that can still pay, so `{"status":"no_active_delegation"}` also covers a budget that ran out or expired — pass the `delegationId` from an earlier pay_service result to read that one anyway. On a deployment that reports it, `spentByDeliveryStatusCents` splits the spend by what each payment delivered (`delivered`, `charged_not_delivered`, `charged_unconfirmed`, `not_charged`, `not_delivered`, `pending`, the `deliveryStatus` values list_payments uses), and `unattributedSpentCents` is spend no payment record itemizes; a non-zero `charged_not_delivered` is what was spent on calls that delivered nothing although the merchant charged (the merchant charge plus any routing fee not given back), so tell the human. `not_delivered` is held for calls the merchant answered with an error: not a charge, it comes back unless the merchant redeems the payment before its authorization expires (an older deployment reports it inside `pending`). `lockedInChannels`, when present, is money the wallet this budget pays from has deposited into payment channels with merchants that charge per call (per token, as in wallet_balance). It is that WALLET's total, shared by every budget paying from it, not a figure of this budget's own: it is NOT spent and NOT charged to this budget, it can pay further calls only to the merchant holding each channel, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use; `message` then says so. An empty list means nothing is locked; `null` means it could not be read, and `message` then says that too. When you have a Nevermined Subscription the result also carries `subscription` (`creditsLeft`, a digit string of every unexpired credit; `resetsAt`, when the allowance expires and, unless `cancelAtPeriodEnd`, the next period's is granted; `status`, `suspended` and `plan`) and `subscriptionMessage` to relay as it stands; `subscription.subscribed: false` means none. Whether or not you subscribe, it also carries `credits` (`null`: could not be read, which is not the same as none): `total`, `spendable` (what can pay a call now), `parts` (`kind` allowance | welcome | topup | sla, `credits`, `expiresAt` — null never expires — and `frozen`: null, `renewal_overdue` for allowance credits frozen until a renewal payment goes through, `dispute` for every credit while a card dispute holds them) and `nextExpiry`, with `creditsMessage` to relay as it stands. Every amount is a digit string. Never count credits yourself. Requires your Nevermined API key on the Authorization header.
- `get_payment_result`: Read the result of a paid call, by its `paymentId`. Use it when `pay_service` answered `{"status":"pending"}` (the service was still working when the Router stopped waiting — the payment is made and the call keeps running), or to recover a result whose response you lost. Reading costs nothing and charges nothing. `state: "Pending"` — still running, call again in a few seconds. `state: "Ready"` — `status` is the service's HTTP status and `body` its response (`bodyEncoding` says whether it is parsed JSON, text, or base64). `state: "Failed"` — the call ended without a response; `failureReason` says why. `{"status":"not_available"}` — nothing to return: results are kept for 24 hours for the account that paid, and only then. Do NOT call pay_service again to get a pending result: that returns the same pending answer. Requires your Nevermined API key on the Authorization header.
- `get_service`: Fetch one catalog service by slug with metadata and a `requestShape` block. Read the endpoint's `payServiceArgs` before `pay_service`, replacing every `pathParams` placeholder. A checked invoke contract may include `invokePath`, `requestExample`, merchant-authored `responseSchema`/`responseExample`, and `exampleEvidence`: `paid-run` records a paid response, `challenge` proves only the request shape, and `docs` is unverified provider documentation. Only `paid-run` and `challenge` examples are pre-filled into `payServiceArgs`; adopt a `docs` example deliberately. Merchant response shapes are sanitised, and harvested examples are published only when they validate against their schema. An `endpointCheck` records a dated unpaid failure. An endpoint with `auth: "siwx"` is not paid: it is a follow-up (a job or result poll) that only the wallet which paid an earlier call to the same service can read, so call it with `pay_service` after that call, filling its `pathParams` with the id the paid response returned; the Router signs the wallet challenge and charges nothing. A `requestSchema` is the merchant-declared JSON Schema of its request and is sanitised, not verified. A quote excludes the Router fee, which the budget must also cover. An unknown slug returns an error. Discovery only; no payment. Call `quote_service` for the live fee-inclusive total before paying.
- `get_subscription_checkout`: Read your personal subscription balance and get the link the human opens to subscribe or manage their allowance when credits are short. Charges nothing and never starts a paid checkout. One-time credit top-ups are not currently offered; an existing subscriber gets the dashboard and reset date. After the human finishes checkout, use get_budget to verify the credits, then retry pay_service. OAuth commerce connections must explicitly grant Nevermined credits.
- `list_categories`: List the categories of paid services in the Nevermined Agent Services Catalog, with a count per category. Discovery only; no payment.
- `list_payments`: List your Router payments: the unified ledger across every service and delegation, newest first, at most 1000 records. Each record carries its `id` (the `paymentId` get_payment_result takes), `createdAt`, `status`, `protocol`, `network`, `requestId`, `delegationId` and `amount` in the asset's smallest unit (see `assetDecimals`), not in cents. Each row also carries `deliveryStatus`: `delivered` (request settled), `charged_not_delivered` (request failed and the merchant charge was observed), `charged_unconfirmed` (charge observed; delivery unconfirmed), `not_charged` (reconciliation proved no merchant charge), `not_delivered` (the merchant answered with an error, so nothing was delivered, and no charge has been seen: the amount stays reserved until reconciliation decides, after the payment authorization expires, whether the merchant charged; it is not a charge), or `pending` (charge outcome unknown). On SPT and card rails, `pending` is not proof of no charge; flag `charged_not_delivered` to the user. Use this tool to reconcile an uncertain payment or find a paymentId; it does not return service responses (use get_payment_result) or the remaining budget (use get_budget, whose figures include fees and rounding). Reading costs nothing. Requires your Nevermined API key on the Authorization header.
- `payment_summary`: Count your Router payment requests: `total` is how many there were in the period (uncapped, unlike list_payments) and `series` is that count per day (`date`, `value`), oldest first. `chargedNotDelivered` is the count of failed payments in the period whose merchant charge reconciliation observed on-chain (a failed payment not yet reconciled is not counted); flag a non-zero count to the user. This reports numbers of payments, not money: for what has been spent or what is left, and how much of it was charged without delivery, use get_budget, and for amounts per payment use list_payments. Reading costs nothing. Requires your Nevermined API key on the Authorization header.
- `pay_service`: Pay for a catalog service from your spend-capped delegation and return the vendor response. This charges real funds. Call `get_service` FIRST: its `requestShape.endpoints[]` lists the callable paths with their HTTP method and price, and each `payServiceArgs` is the `slug`/`path`/`method` to pass here, after replacing any `pathParams` placeholder in `path` with a real value. A bare slug reaches the service base URL, which for a multi-endpoint API answers 404 instead of a payment challenge; only a single-endpoint service is called by slug alone. Send the endpoint's `payServiceArgs`: they carry an example only when it is `paid-run` or `challenge`. A `docs` example (and its `invokePath`) is unverified — use it only deliberately, filling any path parameter with the entity you want; otherwise build `body` from the endpoint description or the provider's docs. `method` may be omitted: it is taken from the catalog endpoint matching `path` (POST when the catalog names none) and echoed back under `request`. To accept a live quote, pass its `quoteId` before `expiresAt` with the exact same call arguments; the Router uses that cached challenge and exact fee-inclusive total. Keep `maxTotalCents` as an independent ceiling. Repeating an identical call (same arguments, no `fresh`) charges nothing new: on a deployment running API 1.48 or later it is answered within 24 hours from the first call's stored result, or its `pending` answer; on an older deployment it comes back as `already_paid`. For an ASYNC service, where you submit once and then poll a status endpoint with the same id, set `fresh: true` on every poll INCLUDING THE FIRST: otherwise each later poll reuses the first poll's idempotency key and gets the first poll's stored answer (or `already_paid`) back, so the status never advances. `fresh` makes each poll a distinct, separately billed call (the merchant charges per status call). Leave `fresh` off the submit and off any retry of a call whose outcome is unsure, because with `fresh` a retry is not de-duplicated and is charged again. A completed call returns `paid`, `upstreamStatus` (the vendor's HTTP status) and `response` (its body); `paid: true` with a non-2xx `upstreamStatus` may still have cost the merchant price. Outcomes to act on: `{"status":"pending"}` means the payment was made and the service is still working; call `get_payment_result` with its `paymentId` every few seconds instead of calling pay_service again. `{"status":"already_paid"}` means this call's idempotency key already carries a payment whose result is not replayed here (the original call failed, its 24-hour result expired, the `requestId` was reused for a different request, or the deployment predates result replay, API 1.48); nothing new was charged, and it does not by itself say whether the original succeeded. Read the original with `get_payment_result` (`paymentId`) or `list_payments`. A new `requestId` starts a separate, separately charged purchase: use one only after that read shows the original failed and the human still wants the result. `{"error":"payment_indeterminate"}` means the charge may or may not have landed: check `list_payments` first, and to retry reuse the returned `requestId` verbatim without `fresh` so the retry stays idempotent. `{"error":"per_call_max_exceeded"}` means no charge; raise `maxTotalCents` only after a deliberate decision and retry with the same requestId. `quote_not_found`, `quote_expired`, and `quote_mismatch` are named no-charge quote refusals; quote again rather than paying unpinned. `{"error":"payment_failed"}` is a definite decline (see `code`, `message` and `retryable`). These charge nothing: `{"payable":false}` (not payable via the Router; no upstream URL is ever returned), `service_not_found` (wrong slug), `catalog_unavailable` and `delegation_lookup_failed` (transient; retry later), `no_delegation` (call `setup_delegation`), `router_controls_unavailable` (the API behind this server is too old to enforce `search`, `quoteId` or `maxTotalCents`; tell the human instead of retrying without them) and `credential_refused` (re-authorize). A paid result also carries `delegationId` and `budget`, the spending budget after this call (`capCents`/`spentCents`/`remainingCents`, cents with up to four decimals), so to say what has been spent or what is left, repeat `budget` rather than adding up your calls yourself; `budget: null` means it could not be read this time, not that it is zero (call `get_budget`). FUNDING (`funding`): omit it and the call is paid with your Nevermined credits when you hold credits that can pay it (a Nevermined Subscription allowance, welcome or top-up credits) and the endpoint carries a credits tariff (Nevermined pays the merchant; the call costs the tariff in credits, returned if the service does not answer successfully), otherwise from your delegation; pass `"subscription"` or `"delegation"` to choose. The credits left and the price ceiling are checked only when the call is made: a credits call refused for them (`insufficient_credits`, `subscription_cap_reached`, `subscription_ceiling_exceeded`) charges nothing and is NOT switched to your delegation, so follow its `alternative`. Every result that mentions funding states which paid it: a subscription call returns `funding: "subscription"` with `creditsCharged`, `creditsStatus` and `creditsLeft` (a digit string read after the call; null means unavailable, not zero) (`Committed` = spent, `Reserved` = held or marked for refund, `Refunded` = returned) and no `budget`; `quoteId`, `maxTotalCents` and `delegationId` apply only to a delegation. Subscription refusals charge nothing and no credits: `subscription_unavailable`, `no_active_subscription`, `subscription_not_eligible` (see `reason`), `subscription_rail_unsupported`, `subscription_ceiling_exceeded`, `insufficient_credits`, `subscription_cap_reached` and `subscription_payment_refused`; each says in `alternative` when the delegation can pay instead. `funding_undetermined` means the funding could not be decided; nothing was charged, so retry. Requires your Nevermined API key on the Authorization header.
- `quote_service`: Price ONE call to a catalog service WITHOUT paying it: it charges nothing, signs nothing and reserves no budget. Pass exactly what you would pass to `pay_service` (the same `slug`, `path`, `method`, `search`, `headers`, `body` and `delegationId`): the Router sends that request to the service unpaid, reads the price it asks for, and returns an opaque `quoteId`, its short `expiresAt`, the rail (`protocol`), the network and merchant amount (`settlement`) and the fee-inclusive total (`fee.capChargedCents`, whole cents rounded up; `fee.capChargedMicros` exact, in 1/10,000 of a cent). Unlike the `quote` on a get_service endpoint (the last merchant price the catalog observed, routing fee excluded), this is priced live for your exact request and includes the fee. Because the request really reaches the service, a service that does not charge for it performs it, so take care quoting a method with side effects; and a quote spends the same per-service rate limit as a payment, so quote once per decision rather than polling. It prices the delegation pay_service would charge (`optionSet: "delegation"`, naming its `delegationId`), or, with no delegation set up, what a personal crypto delegation would select (`optionSet: "deployment"`); in that case `nextTool` is `setup_delegation`: set one up and quote again before paying, since the delegation you create can select a different rail and price. It checks neither your remaining budget nor your wallet balance (see get_budget and wallet_balance). Next step (`nextTool: "pay_service"`): if `fee.capChargedCents` fits what you planned to spend, call `pay_service` before expiry with the same arguments, the quoted `delegationId`, `quoteId`, and `maxTotalCents` set to that figure as a number. The quote id fixes the exact challenge and fee-inclusive total while `maxTotalCents` remains an independent ceiling. `paymentRequired: false` means the service did not ask for payment for this request; `upstreamStatus` is its answer, and a non-2xx usually means the path, method or body is wrong. The service response itself is never returned. Outcomes, all charging nothing: `{"payable":false}`, `service_not_found`, `catalog_unavailable` and `delegation_lookup_failed` as in pay_service; `quote_unavailable` (no quote can be made here and retrying will not change that, so bound the price with pay_service `maxTotalCents` instead); `quote_failed` (the Router refused to price the call, or did not answer; see `code`, `message` and `retryable`); `credential_refused` (re-authorize). FUNDING (`funding`): chosen as pay_service would choose it. When you hold Nevermined credits that can pay it (a Nevermined Subscription allowance, welcome or top-up credits) and the endpoint carries a credits tariff the answer is `{"funding":"subscription","credits":…,"tariffVersion":…}`: the credits one call costs from the published tariff (the service is not contacted, and there is no `quoteId` or cent total); then call pay_service with the same arguments. The credits left and the price ceiling are checked only when pay_service makes the call, so this answer does not promise the call will be paid with credits. Pass `funding: "delegation"` to price the delegation instead. Subscription refusals are named as in pay_service. Requires your Nevermined API key on the Authorization header.
- `route_by_intent`: Given a plain-language description of what you need, find, and optionally pay in the same call, the single best payable catalog service, so you do not have to pick among listings yourself. Use it instead of search_services when you want the right service for a task rather than a list to browse: it ranks candidates on Nevermined's own relevance and quality signals (deterministic; no model reads the merchant listings), applies a fail-closed payability gate (listed, healthy, moderated, x402/mpp, not flagged unpayable), and returns the winner as `chosen` (with its opaque invoke handle, never a raw host) plus a ranked `shortlist`; every shortlist item carries a closed `matchReason`, `gateReason`, per-item `rankingSource`, and one scale-specific score. With `autoPay:false` (the default) it returns the pick only and charges nothing; the next step is normally `get_service` on `chosen.slug`, then `pay_service` with the endpoint you need. With `autoPay:true` it also pays the winner through the same path as pay_service and returns the upstream call in `result`: `result.status` and `result.body` are the vendor's answer, and `result.paid: true` means a payment was attempted, not that it settled, so read `result.payment.status` (`Settled`, `Issued` or `Failed`). autoPay calls the winner at its base URL plus any `path` you pass, and you only learn the winner from this call, so it suits single-endpoint services; a multi-endpoint winner typically answers 404 at its base URL. autoPay requires `requestId`; an API-key caller must also pass `delegationId`, while an OAuth-connected caller spends from the grant it approved and needs none. Outcomes: no listed, payable match → `{"status":"no_fundable_match"}` (broaden the intent or filters; nothing charged), never a wrong pick; `missing_autopay_fields` (nothing charged); on autoPay, `payment_indeterminate` (check `list_payments`, and retry only with the same `requestId`) and `already_paid` (this `requestId` was already paid, see `paymentId`; nothing new billed). Every pick and each of these outcomes carries an `instructions` string with the next step; a payment the Router declines on autoPay comes back as a tool error carrying the API's message. Requires your Nevermined API key on the Authorization header.
- `search_services`: Search the Nevermined Agent Services Catalog for paid services, ranked by ARD HYBRID relevance — semantic (meaning) matches merged with lexical (keyword) matches, most relevant first — falling back to pure lexical when the embedding provider is unavailable. Each result includes a closed matchReason, a per-item rankingSource, and one scale-specific score. A query is required; the other filters are optional. Returns matching listings (vendor, protocol, price label, endpoint). Only the first page is returned: the `pageToken` in the result cannot be passed back to this tool, so to see other matches narrow the query or filters, or raise `pageSize` (up to 100). Discovery only; no payment. To have the platform PICK (and optionally pay) the single best service for a need instead of choosing yourself, use route_by_intent.
- `setup_delegation`: Start the spending-delegation ceremony and return ONE URL for a human to open. Use this when `pay_service` returns `{"error":"no_delegation"}` — it is the way out of that state. It sets up a stablecoin (crypto) delegation that spends from the human's personal wallet, so that wallet also needs funds on the network a service settles on (see `wallet_balance`); it does not enroll a card or create a card delegation. The human sets the currency, spending cap, duration and transaction limit themselves in the browser; you CANNOT set them and must not ask the human to pass them to you. Returns `{"status":"human_action_required","url":…}` — relay the url, wait for the human to confirm, then simply call `pay_service` again. `{"status":"already_active"}` means a usable spending budget is in place — for an OAuth commerce caller it is the grant approved on the consent screen — and nobody needs to do anything: tell the human `message` as it stands (it states the cap, spent, remaining and expiry the API reports, in a voice written to be relayed), then follow `instructions` and call pay_service. The url embeds a short-lived session token, so treat it as sensitive and give it only to the account owner. Other outcomes: `delegation_setup_unavailable` (this deployment cannot run the ceremony) and `delegation_setup_failed` (the session could not be started) produce no URL; `return_url_not_allowed` means drop or fix `returnUrl`; a `human_action_required` answer with `delegationCheck: "failed"` means an existing budget could not be ruled out, so follow its `instructions` and try pay_service first. Requires your Nevermined API key on the Authorization header.
- `wallet_balance`: Read the balances of YOUR OWN PERSONAL wallet — the funding source the crypto rails PULL from when pay_service charges a PERSONAL delegation. It answers `how much do I have, and on which chain`. Reading costs nothing and charges nothing. WHAT IT DOES NOT COVER, so you do not mis-diagnose: a delegation backed by an ORGANIZATION wallet is paid from that wallet, not this one; and a CARD delegation has no wallet at all — there `BCK.ROUTER.0009` is the card ISSUER declining, with nothing to top up, so this tool does not apply and the answer is a different card. BY RAIL: on MPP the wallet is checked BEFORE anything is signed, and the `BCK.ROUTER.0009` you get back already names the wallet and the chain — what it never says is HOW MUCH is there, which is what this tool supplies. On x402 there is NO balance pre-check and `BCK.ROUTER.0009` is never raised: the credential is minted, budget is reserved, and a short wallet only surfaces when the merchant's on-chain transfer fails — by which point your budget is already committed, and the reserve comes back only once the reconciler has seen the authorization expire unconsumed. So on that rail read the balance BEFORE you pay, not after. By default this reports EVERY network this deployment settles on, and you must read the one the merchant quoted: a healthy balance on one chain says NOTHING about the other, and most services settle on only one of them. Pass `network` (a chain id) to read a single chain. A token whose `atomic`/`formatted` is `null` was NOT READ (the on-chain read failed) — that is not a zero balance, and reporting it as empty is wrong; a chain that could not be read at all comes back as an entry with `error` instead of `balances`. This tool diagnoses and fixes nothing: there is no on-ramp and you cannot top your own wallet up, so a genuine shortfall is a stop condition — report the network and the amount to your human, and do not retry the payment. Each entry with `balances` also carries `lockedInChannels` when the API reports it, per token (`atomic` in the token's smallest unit, `formatted`, `symbol`): money your payer wallet (the one the Router signs MPP payments with, which is this wallet once your account is migrated) has deposited into payment channels with merchants that charge per call over an MPP session, held in the channel's escrow. It is NOT part of `balances` and it is NOT spent: it is still the human's. It can pay further calls only to the merchant holding that channel, never anyone else, and what is unused comes back to that wallet when the channel closes, after 15 minutes without use. Report it beside the balance, never as spending, and never count it toward paying any other merchant. Here a null `symbol`/`decimals`/`formatted` means a token Nevermined does not recognise, NOT an unread amount: report `atomic` as raw units of `token`. An empty list means nothing is locked; `lockedInChannels: null` means it could not be read, which is not the same as nothing locked. When you have a Nevermined Subscription the result also carries `subscription` (the credits left, reset date and plan, as in get_budget), and whenever you hold credits, subscribed or not, `credits` (total, spendable and by kind and expiry, as in get_budget): credits are not held in this wallet and are not money; calls paid with credits are paid by Nevermined, not from this wallet. Requires your Nevermined API key on the Authorization header.
