Skip to main content
A short, reusable manifesto for anyone driving the Nevermined Catalog from an agent harness — Claude Code, Cursor, an MCP client, or your own runtime. No code — just the flow, the principles, and the links.
This page is meant to be handed to your agent as-is. Point your harness at it (or share the link) and it has everything it needs to discover, pay, and reconcile safely.

See it in action

New here? Watch the Song from the Headlines example drive the whole flow from a harness, end to end — then read on for the machine-readable version your agent follows (the video is the one part of this page a harness can’t consume).

Song from the Headlines — a Catalog use case driven from a harness.

What the Catalog is

The Nevermined Catalog is a curated directory of external AI services your agent can pay for per call — no per-vendor signup, no subscriptions. Each service settles a single request through Nevermined using the x402 or MPP payment protocols. Your agent discovers a service, calls it, and the payment happens in the background against a budget you control.

The mental model

Five pieces, and it clicks: The agent never holds card numbers or wallet keys and never calls Stripe or a chain directly. It holds an API key and a delegation; Nevermined does the rest.

Who does what

A human is needed only for the account, the money and the key. Everything else is the agent’s job — including creating the budget it spends within. Ask a human only for the left column. Don’t wait for one to create the delegation.

Step 0 — One-time setup (the only human steps)

The Catalog is Live-only for payment. Discovery works on either host, but listed services settle on mainnet and the sandbox Router funds testnets only — so paying one from sandbox fails (400 BCK.ROUTER.0001). The only things a sandbox key can buy are the two free testnet test merchants kept there for rehearsal (see the Commerce MCP page). Every step here uses the Live network and real (if tiny) money; keep caps small and rehearse with a sub-cent service.
  • App (sign in, keys, delegations): nevermined.app
  • Live API base: https://api.live.nevermined.app — your API key for this network is prefixed live: (send the whole string, prefix included).
Sign in and get a plain key. Open nevermined.app, sign in, and get a plain Nevermined API Key — a one-time, human-in-the-loop step (created in the app, SDK-minted, or through the embedded /auth/cli login). Don’t use the device flow (RFC 8628) here: like every OAuth-minted key, its key can’t create a delegation or pay through the Router’s delegation routes (403 BCK.OAUTH.0030). See Get a Nevermined API key for the embedded-login and SDK paths, and Authentication for the OAuth ones. Store it, reuse it, and keep it out of logs.
The agent-facing version of this step is auth.md — the machine-readable manifest kept in lockstep with the API: the discovery documents, the bearer contract and key format, every ceremony that ends in a key (SDK, device flow, and the OAuth commerce consent), and what needs a human. Hand it to your harness alongside this page; where the two differ, auth.md is the one that names endpoints that exist today.
Or let your assistant get it for you. If your harness is an AI assistant that runs OAuth on your behalf — Claude (the claude.ai connector), ChatGPT, Claude Code, LangSmith Fleet, or another MCP host whose client Nevermined’s operator has listed (following the MCP authorization spec buys a host its identity, not this authority — an unlisted host is refused at the consent screen) — you skip the key, and Step 1’s delegation: add the Catalog MCP with no key, and the assistant sends you to Nevermined to approve a spending cap once — when you add the server on the strict host, on the first paid call on the public one. That approval is the delegation of Step 1 and the credential of this step, in one screen; the assistant renews the credential silently. The cap bounds what it can spend — not what the grant can see or do on your account (it reads your Router payment history and wallet balance, lists and can revoke your delegations, and can start a new delegation ceremony for you to approve); auth.md §6 has the full list. Which host and client each assistant uses (two of the four above need the strict mcp.api.<tier> host), and the mechanics the host follows, are auth.md §6. Funding is not skipped: a commerce grant spends stablecoin from your own wallet, so the next bullet still applies. Fund a way to pay. A stablecoin method exists by default — fund it on the networks the Catalog settles on: Base and Tempo. Services settle on different rails (some on Base, some on Tempo), so keeping a small balance on both keeps any service payable — otherwise a call can fail simply because your funds are on the other network. To pay by card instead, enroll one once (a one-time in-browser step) — card enrolment funds the card rails only; a commerce grant from an assistant always spends stablecoin from your own wallet.

Step 1 — The agent creates its budget (the delegation)

The delegation is your capped, server-enforced spending authority (see the mental model above) — the single most important safety control here. With a plain API key, the agent creates it itself. This is not a human step.
The response carries the delegationId every paid call names (X-Router-Delegation-Id, or delegationId in a JSON body). erc4337 is the stablecoin delegation the Catalog’s rails pay from; it needs no card.
  • Set the cap to the budget the user gave you (spendingLimitCents is in cents: 100 above is $1). It’s your spending limit: every price, the Router fee and any retries come out of it. Keep a soft stop a little below it in your agent so a run halts cleanly rather than erroring at the wall.
  • Count transactions for a retry. maxTransactions counts every paid attempt, including one the service then refuses, so set it above the number of calls you plan — or omit it and let the cap bound the spend. A transaction limit of exactly the planned calls can’t recover from one bad result.
  • Reuse before you create. GET /api/v1/delegation?accessible=true lists the Active delegations your key can spend; reuse one with enough budget left.
  • Ask a human only when creating it answers 403 BCK.OAUTH.0030 (your key was minted by OAuth — you need a plain key) or 412 with "error": "consent_required" (the account must accept updated terms in the app). Any other refusal here (a 401 for an invalid or expired key, for example): stop and report the exact error to the user.
  • Never create another delegation to get past a cap or budget refusal (402 BCK.ROUTER.0003, even though its hint suggests creating one): report it and stop. The cap is the user’s decision.
A human can set the cap instead — in the app (Payment Methods → Delegate), or through the Catalog MCP’s setup_delegation tool, which returns a link for them to approve — but neither is required.

Step 2 — Discover services (free, no key required)

The catalog’s read surface is public — browse or filter it before spending a cent. Every listing tells you what you need to choose: its slug (how you address it), protocol (x402 or MPP — handled for you), a price label, its endpoints, and tags/category. Filter by task (e.g. web search, email enrichment, scraping, social data) and by price, and shortlist the cheapest service that answers the need. Listings are returned in a recommended order — Nevermined’s own quality ranking, not alphabetical — so the top of the list is a sensible default rather than something you score yourself. Treat that order as guidance, not a contract: it is recomputed as health and traction change. Each feed entry also carries a displayPriceSource of settled or quoted (a settled price means real, multi-payer settlement — the service is genuinely used, not just advertised) and partner/featured flags you can weigh.
Read an endpoint’s request schema before you call it — never guess parameter names. Discover with the feed if you like, but ai-catalog.json never carries request schemas, by design. Before calling an endpoint, read its requestSchema — the merchant-declared JSON Schema of the query or body fields it takes, and which are required — from a detail-shaped read:
  • One service you already picked: Catalog MCP get_service with its slug → requestShape.endpoints[].requestSchema (no key needed), or ARD search POST https://api.live.nevermined.app/api/v1/ard/search with { "query": { "text": "<the service's name or what you need>" } } → results[].nvm:catalog.endpoints[].requestSchema.
  • Browsing: ARD list GET https://api.live.nevermined.app/api/v1/ard/agents → items[].nvm:catalog.endpoints[].requestSchema. It is paged (20 per page by default, up to 100) and filters only by type, tags, publisher and updatedAt, so it cannot fetch one service by slug.
Use the exact names the schema gives: an endpoint whose schema requires ticker rejects a call that sends symbol with a 422. Where an endpoint has no requestSchema, build the request from its requestExample (pre-filled in get_service’s payServiceArgs when it is verified) and description, or from the provider’s documentation — not from a guess. Multi-model services, for example, expect a provider-prefixed model id (openai/gpt-4o-mini, google/gemini-2.5-flash-lite); a bare gpt-4o-mini is usually rejected with a typed 400.
Don’t know which service to pay? Let the Router pick instead of scoring listings yourself: POST /api/v1/router/select with a plain-language intent (and optional filters — category, protocol, network, maxPriceLabel) returns the single best payable service plus a ranked shortlist, chosen deterministically on Nevermined’s own relevance and quality signals behind a payability gate. Take the returned order as authoritative — read the order, not the numbers: the relevance scores can sit on different scales (semantic vs keyword), so re-sorting by them yourself can pick worse. Add autoPay: true (with requestId + delegationId) to select and pay in one call. This uses your API key — see the Router quickstart, and Let the platform pick a service for the full shortlist shape.

Step 3 — Connect the harness to the Catalog

Two paths — pick one: Either way the shape is the same: name the service (by slug), pass your delegation, get the result back. The Router reads the vendor’s payment challenge, pays from your delegation, and returns the response.

Using the Catalog MCP

If your harness speaks MCP, the server drops discovery and payment in as native tools. Point your client at the server URL and put your Nevermined API key on the Authorization header — or, in an assistant that runs OAuth (Claude, ChatGPT, LangSmith Fleet), connect by URL alone and approve a spending cap once:
Use https://mcp.sandbox.nevermined.app/mcp to rehearse. The tools your agent then has — discovery is free, the rest need the credential, and only pay_service / route_by_intent (with autoPay) move money: Every argument, return field and refusal is in the Catalog MCP reference; the product page has the per-assistant setup walkthroughs.

The calling convention (one canonical shape)

If you drive the Router API directly, there is one convention in three forms — all settle identically; they differ only in how you pass the target and where the result comes back. Pick the one that fits your client. Full copy-paste curl lives in the Router quickstart; this is the map.
Use one form per call — never mix them. /router/proxy with X-Router-Target-Slug reaches only the service’s base URL. To call an endpoint under it, use /router/svc/<slug>/<subpath> and send no X-Router-Target-Slug (or X-Router-Target-Url) header: the Router refuses a /svc call that carries one with 400 BCK.ROUTER.0001, before anything is paid. Take the <subpath> from the listing (the endpoint’s invokePath, or payServiceArgs.path in the Catalog MCP).
All three forms need the same two facts — which delegation pays and an idempotency id — but they carry them differently. The JSON form (/router/route) takes them as body fields: delegationId and requestId (both required — a header-only /route call fails validation), and returns the payment in the JSON response envelope (payment.paymentId, payment.status, payment.txHash, payment.failureReason). The two transparent forms (/router/proxy, /router/svc) carry them as X-Router-* request headers instead, and return the payment as response headers: The transparent response carries X-Router-Payment-Id, X-Router-Payment-Status, X-Router-Tx-Hash, and — on a failed/unsettled payment — X-Router-Failure-Reason.
Address a cataloged service by its slug, never a raw URL: the Router hides the vendor’s host on purpose, so paying one by raw URL is refused (409 BCK.ROUTER.0014). Keep raw URLs and hosts out of the path — a security guard blocks anything there that looks like it changes the destination host. The resolved slug in /svc/<slug> is exempt, because the Router maps it to the host server-side.

Paying with Nevermined credits

If the user holds Nevermined credits — the free credits a new account gets, top-up packs, or a Nevermined Subscription’s monthly allowance — some catalog endpoints can be paid with them instead of the delegation: Nevermined pays the merchant, the call costs a fixed number of credits with no routing fee, and the credits come back if the service doesn’t answer 2xx. Credits pay only the endpoints that carry a rate, so keep a delegation for the rest. Price a call in credits — this charges nothing. A listing’s USD priceLabel is not its credits price; don’t convert one into the other.
  • Catalog MCP, connected with your API key: get_service shows subscription.creditsPerCall on each endpoint credits can pay (no subscription field means credits can’t pay it). quote_service with funding: "subscription" prices one call.
  • REST: GET /api/v1/subscription/catalog/credits lists every endpoint credits can pay, with its creditsPerCall. POST /api/v1/router/subscription/quote with slug, path and method prices one call.
  • ARD discovery, with your API key: a keyed POST /api/v1/ard/search or GET /api/v1/ard/agents read carries subscription.creditsPerCall inline on each endpoint credits can pay (nvm:catalog.endpoints[].subscription), so the credits price comes back with discovery in one call. An unauthenticated read omits it — send your key to see it.
Pay with credits. Credits are spent only through these two paths:
  • The Catalog MCP connected with your API key, or through an OAuth connection the human allowed to spend credits (below). pay_service pays with credits by default when the credits and the endpoint qualify, and from the delegation otherwise. Pass funding: "subscription" to insist on credits; the result’s funding and creditsCharged say what paid.
  • POST /api/v1/router/subscription/route with slug, path, method, body and requestId — no delegationId, no URL. The streaming form is /api/v1/router/subscription/svc/<slug>/<subpath> with an X-Router-Request-Id header.
The delegation routes (/router/route, /router/proxy, /router/svc) never spend credits. An OAuth connection (the claude.ai connector, ChatGPT, or a host connected through the OAuth consent) spends them only if the human ticked Let this assistant spend my Nevermined credits when connecting it; otherwise it pays from the cap the human approved, and the credits routes refuse it (403 BCK.OAUTH.0037, or 0030 for an OAuth key that isn’t a commerce connection). Use a personal API key and no X-Current-Org-Id header. GET /api/v1/credits/balance returns the credits that can pay now. Every rule and refusal code: Pay with Nevermined credits.

Async services (generate, then poll)

Some services are asynchronous — media generation, for example. The first call returns a taskId instead of the result, and you poll a status endpoint until the result appears. It is fully supported; keep these in mind:
  • A placeholder callBackUrl is fine. Some generators require the field even when you intend to poll — pass any well-formed URL; you do not need to receive the callback.
  • Know whether the status endpoint is paid or free. If it answers 402, each poll is a paid call (see the next bullet). If it is free (non-402) on a cataloged service, the Router relays only the status and withholds the body by default — the free-follow-up window is off unless the deployment enabled it and the merchant declared the path — so a free poll can return 200 with no result. Check the endpoint on the listing.
  • Give every poll a fresh X-Router-Request-Id. The Router de-duplicates on that id, so reusing one makes each repeat a duplicate that is refused (409 BCK.ROUTER.0002, the original paymentId in params, no result) — it is not a new charge, but it never reaches the service either, so a naive poller stalls and never advances. A fresh id per poll advances it — and on a paid (402) status endpoint each real poll is a separately-billed call (the merchant charges per status check), so bound the number of polls against your delegation cap. (A free status endpoint relays with paid: false — no charge.) The Catalog MCP’s pay_service exposes a fresh flag that mints the fresh id for you.
  • Read the generate and status endpoints — and the field that carries the taskId and the result — from the service’s detail (requestSchema / requestExample / responseSchema, via ARD /search · /agents or MCP get_service).

The principles that make it smooth

These are the habits that turn trial-and-error into a clean run. Treat them as the manifesto:
  1. Discovery is free — use it first. Confirm a service’s slug, price, and endpoints from the live feed before every task, and each endpoint’s request schema from a detail read (ARD /search · /agents, or MCP get_service) before you call it. Prices and listings drift.
  2. A failed call is not reliably free — don’t treat it as a cheap probe. Once the payment credential is minted, the merchant leg stands even if the upstream call then errors; only the routing fee may be released, and only on specific paths. Whether the merchant leg settles before or after the upstream 2xx depends on the call mode. Confirm how a service wants to be called from its listing and docs, not by paying to find out — see when a fee is not collected.
  3. Judge every result — on junk or a refusal, move to the next service. A 2xx is not proof the answer is useful. If the result is irrelevant or empty, or the service refuses the call (a 4xx: BCK.ROUTER.0019 on /proxy · /svc, or a 4xx status with body: null on /route), don’t stop and don’t report the junk as the answer. First tell a free refusal from a possibly paid one (see Step 4): a refusal that names no paymentId cost nothing, so fix the request and resend; a 202, a 5xx or any answer naming a paymentId may already have paid the merchant, so look the purchase up by its request id before doing anything else. Otherwise try the next matching service from discovery (or the next shortlist entry from /router/select) as a new purchase with a fresh idempotency id. The cap is the budget, so retries come out of it (Step 1).
  4. Address a service by its slug and let the Router resolve the endpoint. Don’t fight it with hand-assembled sub-paths — the common failure is a mis-resolved path, not a payment problem.
  5. Put target URLs in the request body, never in the path. A security guard blocks anything in the path that looks like it changes the destination host.
  6. Give every purchase a stable idempotency id. Reuse the same id when you retry, so a network hiccup never double-charges; use a fresh id only for a genuinely new purchase.
  7. Async services: poll, don’t wait on a callback. Synchronous services are simplest, but async ones (e.g. media generation) are fully supported — see Async services above. The one trap is a naive poller: give each poll a fresh idempotency id. Reuse one and the Router refuses each repeat as a duplicate (409, no charge) so the poll never advances; a fresh id per poll advances it, and each paid (402) poll is a separately-billed call.
  8. The delegation is the source of truth for spend. Reconcile against your delegation’s remaining budget, not a local tally.
  9. Prove the flow cheaply — payment is Live-only. Sandbox can rehearse the mechanics against its two free testnet test merchants, but no real service is payable there (its Router funds testnets only) — so validate discovery → pay → result end-to-end on Live with a small delegation cap and the cheapest sub-cent service before scaling spend up.

Step 4 — Track and reconcile spend

Read your delegation’s remaining budget and the Nevermined payment ledger to see exactly what each call cost and how much of the cap is left. This is also your audit trail. See the environment’s OpenAPI reference for the delegation and payment endpoints. A refused call is not always a free one. A refusal that names no paymentId — no X-Router-Payment-Id header, no payment in a /router/route reply, and no paymentId in the error’s params — cost nothing: fix the request and resend. Anything else may already have paid the merchant: a 202, any 5xx, or any answer that names a paymentId. A paid hop that gets no response, for instance, answers 502 BCK.ROUTER.0034 (or 0025 when its reply was too large to deliver) with the paymentId only in the error’s params. Before doing anything else, look the purchase up: GET /api/v1/router/payments?requestId=<your request id> — "presence": "absent" means nothing is recorded, so resend with the same id.
  • A 202 is still running — on /router/route, and on /router/proxy · /router/svc before the service starts answering. Poll its resultUrl (the Location header on the streaming forms), and never buy it again.
  • A paid error is undecided, not proof of a charge. A paid call the service answers with an error other than 402 stays Issued until Nevermined reconciles it, with its price reserved against your cap; if the merchant never collects, that reserve is released once the payment’s window closes, and if it did collect, the charge stands. A paid hop with no response is marked Failed, and the merchant may still have collected. Don’t count either as spent or as refunded yet.
  • Retry the same purchase only with the same X-Router-Request-Id (or requestId): the Router never pays one id twice. Leave room for any held reserve when you buy elsewhere.
When a call errors on /router/proxy or /router/svc (BCK.ROUTER.0019 / 0020) — on /router/route the same condition arrives as the envelope’s status with body: null, no typed code — status is the primary read — it is what you got (a non-2xx leaves the row unsettled). On the x402 rail there is also merchantSettlementObservedAt: when it is set alongside status: Issued/Failed, the merchant redeemed the payment on-chain and delivered nothing (charged-but-undelivered — worth alerting on). It is null on a clean settlement and on both MPP rails (which cannot record it), so null is not proof you weren’t charged — fall back to txHash / status there. Either way, the Router never takes its own routing fee for a call that did not deliver.

Safety & etiquette

  • Live means real money. The Catalog is Live-only — keep delegation caps tight and rehearse with a sub-cent service before scaling.
  • Mind the data. Some services return personal or third-party data; use them only where you have a lawful basis, and remember the query is sent to a third-party vendor.
  • Protect the key. Never commit it, log it, or paste it into a shared transcript.