docs: add the Nevermined Router section - #264
Conversation
Adds a top-level "Nevermined Router" group to the Guides tab, sibling to Payments — the buyer side of Nevermined, documented for the first time. Neither rail had any docs-site coverage before this: not MPP, not even x402. Pages: overview, how-it-works, quickstart, rails-x402, rails-mpp, guardrails, ledger. Everything is grounded in the merged Router code (apps/api/src/router/) — the controller's OpenAPI annotations, the DTOs, the error catalogue, and the in-repo MPP guide — rather than restated from the roadmap. Two further pages (discover-services, agent-autonomy) are deliberately deferred pending the seam with the Agents Catalog section in #241. Refs nevermined-io/nvm-monorepo#2593 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
…ns unrestricted Self-review caught an overstatement: the Router enforces recipient scope only when the delegation actually carries a recipient list (router.service.ts guards on `allowedRecipients.length > 0`). A delegation without one can pay any reachable merchant, with the cap and expiry as its only limits — the opposite of what the first draft implied. Also corrects the MPP splits rationale: that refusal is unconditional, not a consequence of recipient scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aaitor
left a comment
There was a problem hiding this comment.
Approve. This is an unusually well-grounded docs set — I cross-checked the concrete, falsifiable claims against the merged Router source and they hold up end to end. The writing earns its density: each page stands alone (deliberate repetition of the pull/custody model across rails is correct for docs, not debt), the agent-facing framing is genuinely useful, and the error/guardrail pages are precise rather than aspirational. One LOW inline nit; nothing gating.
Verification I ran (against apps/api/src/router/** + libs/helpers/src/lib/output/api-errors.ts on the local monorepo checkout)
- Error table (guardrails): all 9
BCK.ROUTER.*codes match the catalogue — statuses0001→400, 0002→409, 0003→402, 0004→404, 0005→409, 0006→500, 0007→429, 0008→403, 0009→402, and the retryable set is exactly{0006, 0007}. ✅ - Endpoints:
routes.tsmaps/api/v1/routerand/api/v1/delegation; controller routes resolve toPOST /route,ALL /proxy,POST /payments,POST /payments/:id/settled,GET /payments,GET /payments/summary, andPOST /delegation/create/GET /delegation/:id. Every path in the docs is correct. ✅ - Delegation DTOs:
providerenum includeserc4337,currencyincludesusdc/eurc,spendingLimitCents/durationSecsrequired; the step-3 JSON (providerPaymentMethodId,remainingBudgetCents,amountSpentCents,expiresAt, …) matches the response DTO. The{delegationId}step-2 shape is a fair simplification (delegationTokenis the optional JWT, not needed for the HTTP flow). ✅ - x402 rail:
base=8453 /base-sepolia=84532, CAIP-2 form,USDC/EURC6-dec,exact/EIP-3009,extra.namesymbol filter, ceil-to-cent rounding ((atomic + 9999)/10000),settlement.approxCents,MAX_AUTH_TTL_SECS=3600 — all confirmed. ✅ - MPP rail: Tempo 4217 / Moderato 42431 →
tempo/tempo-moderato, fail-closedROUTER_TEMPO_ASSETS_<chainId>allowlist,splitsrefused unconditionally (mppxexpectedRecipientsbackstop + re-decode compare),Payment-Receipt→txHash,method=stripecard rail behindROUTER_STRIPE_SPT_ENABLED(the code's own comment calls it "sandbox-only"). ✅ - Env defaults:
ROUTER_MAX_CONCURRENT_PER_USER=10,STREAM_IDLE_MS=30000,STREAM_MAX_MS=300000,MAX_RELAY_BYTES=100MB,FUNDED_NETWORKS=base,base-sepolia,FUNDED_SYMBOLS=USDC,EURC,PREFER_SYMBOL=USDC. All match. ✅ - SSRF / relay (guardrails): loopback / RFC1918 / link-local / 169.254.169.254 metadata blocked at literal-IP + name layer, DNS-rebinding caught by resolve-then-pin, redirects
manualwithlocationstripped,X-Router-*control headers stripped both directions, proxy header names all correct. ✅ - Ledger: list-response fields,
format=csv,from/to, and the summary (total+series[{date,value}],normalizeGranularityday/week/month → day fallback) match the DTOs. ✅ - Leanness (
/ponytail-review): nothing to cut. Cross-page repetition of the custody/0009model is intentional standalone-page design for docs, not over-engineering. Lean already. - Nav / links:
docs.jsongroup is well-formed and correctly placed (sibling to Payments); cross-link/products/x402-facilitator/overviewresolves on the branch; heading anchors (#3-fund-your-wallet,#how-settlement-gets-recorded, …) are correct. Onlysandbox/liveenv names appear. - CI: 2/2 green; Mintlify preview 🟢.
Nice catch on the seam with #241 (catalog owns discovery, Router owns payment) — worth pinning that in one of the two PRs before both merge so the boundary doesn't drift.
…cent) aaitor review, LOW. The page states 10,000 atomic units = 1 cent, so the 4,500 example was 0.45 cent, not half a cent. The rounding point was unaffected — both round up to 1 — but on the one page whose job is the atomic-unit -> cent math, the example has to be exact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
What
Adds a top-level Nevermined Router group to the Guides tab, sibling to Payments — the buyer
side of Nevermined, documented on the site for the first time.
Before this PR the docs site had no Router page at all: not for MPP, and not even for x402. The
only user-facing guide was the in-repo
apps/api/src/router/README.md, which covers MPP only.Pages
overviewhow-it-works/proxyvariant), where custody sits, how settlement is recordedquickstartrails-x402exactscheme, Base + Base-Sepolia, USDC/EURC, v1 vs v2 negotiation, the cents rounding, operator configrails-mppcharge, the fail-closed asset allowlist, receipts, why split-bearing challenges are refused, the flag-gated card railguardrailsBCK.ROUTER.*codeledgerGET /paymentswith filters and CSV export, the aggregate summary, record statuses, closing a mode-A record, reconciliationGrounding
Every claim is taken from the merged Router code — the controller's OpenAPI annotations, the DTOs,
api-errors.ts,x402-exact.ts,mpp/, and the in-repo MPP guide — rather than restated from aroadmap. Specifics that came out of reading the source rather than assuming:
fundable one remains.
accepts[].extra.name, so a service that omits it won't match.Issuedis a success state, not an error — the Router deliberately won't fail an already-paidhop over a missing or malformed receipt.
0xvalue islegitimate. Documented as an anchor to verify, not as proof of payment.
BCK.ROUTER.0003(cap) and0009(wallet balance) are genuinely different failures — a cap ispermission, not funds.
Scope — two pages deliberately deferred
discover-servicesandagent-autonomyare not in this PR. They overlap#241 (Agents Catalog), and the agreed seam is:
Anything payment-related in the catalog section should become a link into this one, so there is only
ever one description of how to call through the Router. Happy to do that trim here or leave it to
#241 — whichever the author prefers.
Related
BCK.ROUTER.*namespace is still absent from the published catalogue on thissite. #248 already contains all 9 codes and just
needs a rebase onto the current path layout.
Validation
mintlify broken-links→ no broken links.title/description/iconfrontmatter; component tags balance.docs.jsonedited surgically (13-line diff, no reformat) and parses.api-reference/**untouched — it is generated from the SDK repos.sandbox/liveenvironment names appear.🤖 Generated with Claude Code