diff --git a/.amazonq/rules/nevermined-router.md b/.amazonq/rules/nevermined-router.md
index 039c2619..43478e67 100644
--- a/.amazonq/rules/nevermined-router.md
+++ b/.amazonq/rules/nevermined-router.md
@@ -106,6 +106,11 @@ Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs
- `BCK.ROUTER.0008` (403) — legacy API key; create a new one.
- Only `BCK.ROUTER.0006` (500) and `0007` (429, too many concurrent) are **retryable**. Everything
else is a decision — retrying unchanged gives the same answer.
+- `BCK.ROUTER.0010` (500) — internal. **Never blind-retry it:** a credential was already minted and
+ no record was written, so `requestId` will not suppress the retry. Report it.
+- `BCK.ROUTER.0011` (402) — card rail: needs cardholder 3-D Secure, which an agent can't complete.
+ Nothing was charged. **Don't auto-retry** — each attempt re-demands 3DS and strands a fresh
+ single-use card credential. Surface it to a human.
**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the
user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one
diff --git a/.clinerules/nevermined-router.md b/.clinerules/nevermined-router.md
index a1897952..48a084c3 100644
--- a/.clinerules/nevermined-router.md
+++ b/.clinerules/nevermined-router.md
@@ -115,6 +115,11 @@ Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs
- `BCK.ROUTER.0008` (403) — legacy API key; create a new one.
- Only `BCK.ROUTER.0006` (500) and `0007` (429, too many concurrent) are **retryable**. Everything
else is a decision — retrying unchanged gives the same answer.
+- `BCK.ROUTER.0010` (500) — internal. **Never blind-retry it:** a credential was already minted and
+ no record was written, so `requestId` will not suppress the retry. Report it.
+- `BCK.ROUTER.0011` (402) — card rail: needs cardholder 3-D Secure, which an agent can't complete.
+ Nothing was charged. **Don't auto-retry** — each attempt re-demands 3DS and strands a fresh
+ single-use card credential. Surface it to a human.
**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the
user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one
diff --git a/.cursor/rules/nevermined-router.mdc b/.cursor/rules/nevermined-router.mdc
index 30b6992b..806d4182 100644
--- a/.cursor/rules/nevermined-router.mdc
+++ b/.cursor/rules/nevermined-router.mdc
@@ -111,6 +111,11 @@ Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs
- `BCK.ROUTER.0008` (403) — legacy API key; create a new one.
- Only `BCK.ROUTER.0006` (500) and `0007` (429, too many concurrent) are **retryable**. Everything
else is a decision — retrying unchanged gives the same answer.
+- `BCK.ROUTER.0010` (500) — internal. **Never blind-retry it:** a credential was already minted and
+ no record was written, so `requestId` will not suppress the retry. Report it.
+- `BCK.ROUTER.0011` (402) — card rail: needs cardholder 3-D Secure, which an agent can't complete.
+ Nothing was charged. **Don't auto-retry** — each attempt re-demands 3DS and strands a fresh
+ single-use card credential. Surface it to a human.
**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the
user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one
diff --git a/.windsurf/rules/nevermined-router.md b/.windsurf/rules/nevermined-router.md
index 039c2619..43478e67 100644
--- a/.windsurf/rules/nevermined-router.md
+++ b/.windsurf/rules/nevermined-router.md
@@ -106,6 +106,11 @@ Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs
- `BCK.ROUTER.0008` (403) — legacy API key; create a new one.
- Only `BCK.ROUTER.0006` (500) and `0007` (429, too many concurrent) are **retryable**. Everything
else is a decision — retrying unchanged gives the same answer.
+- `BCK.ROUTER.0010` (500) — internal. **Never blind-retry it:** a credential was already minted and
+ no record was written, so `requestId` will not suppress the retry. Report it.
+- `BCK.ROUTER.0011` (402) — card rail: needs cardholder 3-D Secure, which an agent can't complete.
+ Nothing was charged. **Don't auto-retry** — each attempt re-demands 3DS and strands a fresh
+ single-use card credential. Surface it to a human.
**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the
user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one
diff --git a/products/router/guardrails.mdx b/products/router/guardrails.mdx
index 0bbb2417..bc01c53d 100644
--- a/products/router/guardrails.mdx
+++ b/products/router/guardrails.mdx
@@ -58,7 +58,7 @@ At most one payment is minted per `(caller, requestId)`. A duplicate returns **`
Use **one stable id per logical purchase**, not per HTTP attempt:
-- Retrying a timed-out call with the **same** id → returns the original payment. Safe.
+- Retrying a timed-out call with the **same** id → `409 BCK.ROUTER.0002` with the original `paymentId`, **not the resource**. Safe — but don't escape that 409 by minting a fresh id.
- Retrying with a **fresh** id → buys again. Also safe, but only if that's what you meant.
## What the Router won't fetch
@@ -97,8 +97,20 @@ Exceeding the concurrency limit returns **`429 BCK.ROUTER.0007`**, which *is* re
| `BCK.ROUTER.0007` | 429 | Too many concurrent routed requests in flight. | **Yes** |
| `BCK.ROUTER.0008` | 403 | Legacy API key. Create a new one — see [the quickstart](/products/router/quickstart#1-get-an-api-key). | No |
| `BCK.ROUTER.0009` | 402 | You couldn't fund the payment. MPP only, and it covers two cases: MPP-tempo read your balance and found it short, or MPP-stripe attempted your card and it declined. Either way nothing was signed and no budget was reserved. x402 never raises this — it has no balance check, so a short wallet fails on-chain instead. | No |
+| `BCK.ROUTER.0010` | 500 | Internal: a rail reported a charge amount the Router can't reserve against the cap. | No — **never blind-retry** |
+| `BCK.ROUTER.0011` | 402 | Card rail: the charge needs cardholder 3-D Secure, and an agent has no browser to complete it. Nothing was charged and the seller got no usable credential. | No — **needs a human** |
-Only `0006` and `0007` are worth retrying automatically. The rest are decisions, and retrying them unchanged will produce the same answer.
+Across the whole Router surface, only `0006` and `0007` are worth retrying automatically. The rest are decisions, and retrying them unchanged will produce the same answer. On the *paying* path the set is narrower still — see below.
+
+
+**`0010` is a 500 that must never be retried** — which makes it the exception to "retry the 5xx". In fact `0006`, the one retryable 500, is raised only by the payments *summary* read and never by a payment, so on the paying path **`0007` is the only code worth retrying at all**.
+
+`0010` fails *after* a payment credential has already been minted, and because no payment record was written, your `requestId` can't suppress a retry. Idempotency is enforced against the record, and there isn't one — so a retry is treated as a fresh purchase, mints another credential, and then fails identically, because the cause is a deterministic defect rather than a transient blip.
+
+**And `0011` is its mirror image on the other side of the status code.** A card needing 3-D Secure returns a `402` that reads like a routine payment error, and is equally un-retryable: the Router can't complete the challenge, so every retry re-demands it and strands another single-use card credential. Route it to a human. The general lesson is that **the HTTP status does not tell you whether to retry** — read the code.
+
+Nothing was charged to your Delegation and no payment record exists. On the card rail the minted credential is a Stripe Shared Payment Token which is left stranded: there is no revoke path, so it stands until it expires, and that expiry is `min(the merchant challenge's expiry, your Delegation's expiry, 89 days)` — not necessarily soon. Nothing you can do about it from the outside, which is precisely why this should be reported rather than looped on.
+
## Notes for autonomous agents
diff --git a/skills/nevermined-router/SKILL.md b/skills/nevermined-router/SKILL.md
index 1d884d06..e3a91d2a 100644
--- a/skills/nevermined-router/SKILL.md
+++ b/skills/nevermined-router/SKILL.md
@@ -192,7 +192,7 @@ curl -sX POST "$NVM_API_URL/api/v1/router/route" \
`status` and `body` are the merchant's own, unchanged. `paid: false` with no `payment` block means the resource was free — the Router relayed it and charged nothing.
-**`requestId` is required, and it is an idempotency key — not a request counter.** Use **one stable id per logical purchase** and reuse it across retries of that purchase. Retrying a dropped call with the same id returns the original payment instead of buying twice; a fresh id buys twice, on purpose. Derive it from the work you are doing (`"search-nevermined-router-v1"`), not from `uuid4()` per HTTP attempt — a fresh UUID on every retry is how an agent double-spends.
+**`requestId` is required, and it is an idempotency key — not a request counter.** Use **one stable id per logical purchase** and reuse it across retries of that purchase. Retrying a dropped call with the same id returns `409 BCK.ROUTER.0002` carrying the original `paymentId` — **not the resource** — instead of buying twice; a fresh id buys twice, on purpose. **Never answer that 409 by minting a fresh id**: that is the double-spend the key just prevented. If the purchase genuinely failed, report it. Derive it from the work you are doing (`"search-nevermined-router-v1"`), not from `uuid4()` per HTTP attempt — a fresh UUID on every retry is how an agent double-spends.
Mode A (you call the merchant yourself), the streaming `/proxy` variant, and passing the merchant's own auth: `references/paying.md`.
@@ -217,7 +217,7 @@ The Router signs payments from your wallet in response to instructions written b
1. **`402 BCK.ROUTER.0003` (over cap / expired) and `402 BCK.ROUTER.0009` (wallet short) are stop conditions.** They mean "out of budget" and "out of money". Report them to the human. Do not route around them.
2. **Never widen a Delegation, and never create a second one, in response to a refusal.** The cap is the user's decision, not a runtime obstacle. Creating a fresh Delegation to escape an exhausted one defeats the entire mechanism — it is the single worst thing you can do with this API.
3. **One `requestId` per purchase**, reused across retries of that purchase. See [above](#requestid).
-4. **Only `0006` (500) and `0007` (429) are retryable.** Everything else is a decision, and retrying it unchanged produces the same answer. Back off on `0007`; it means you have too many routed calls in flight.
+4. **Only `0006` (500) and `0007` (429) are retryable.** Everything else is a decision, and retrying it unchanged produces the same answer. Back off on `0007`; it means you have too many routed calls in flight. **The HTTP status does not tell you whether to retry** — `0010` is a 500 you must not retry and `0011` is a 402 you must not retry. Read the code, not the status.
**Check the price before you commit.** `priceLabel` in the catalog is indicative; `settlement.approxCents` on the response is what you were actually charged. Budget is debited in whole cents rounded up, so a run of sub-cent calls still burns a cent each.
@@ -234,6 +234,14 @@ The Router signs payments from your wallet in response to instructions written b
| `BCK.ROUTER.0007` | 429 | Too many concurrent routed requests in flight. | **Yes**, after backoff |
| `BCK.ROUTER.0008` | 403 | Legacy API key. Create a new one. | No |
| `BCK.ROUTER.0009` | 402 | Wallet doesn't hold enough of the asset on the target network. Nothing was signed. | No — **stop** |
+| `BCK.ROUTER.0010` | 500 | Internal: the rail reported a charge amount the Router can't reserve against the cap. | No — **never blind-retry** |
+| `BCK.ROUTER.0011` | 402 | Card rail: the charge needs cardholder 3-D Secure, and an agent has no browser to complete it. Nothing was charged and the seller got no usable credential. | No — **needs a human** |
+
+**`0011` needs a human, not a retry.** The card issuer is demanding 3-D Secure and the Router has no browser to answer it. Nothing was charged. Do **not** loop: 3DS is often mandated per charge, so every attempt re-demands it and mints a fresh single-use card credential that is then abandoned. A later *human-driven* attempt may succeed — that is a decision, not a retry.
+
+**`0010` is the one 500 you must never retry.** A payment credential **was already minted** before it failed — and because no payment record was written, your `requestId` will *not* suppress the retry. So a retry mints a **fresh** credential and then fails identically, because the cause is a deterministic defect in the rail's amount derivation, not a transient blip. Report it to the human.
+
+Note `0006`, the retryable 500, is only ever raised by the payments *summary* read — never by a payment. **On the paying path `0007` is the only code worth retrying at all.** And seeing `0010` at all means a Nevermined-side regression: no rail emits a non-numeric amount today, so it is a bug report, not a condition to handle. (On the card rail the minted credential is a Stripe Shared Payment Token, left stranded with no revoke path until `min(challenge expiry, Delegation expiry, 89 days)`.)
Catalog errors: `BCK.CATALOG.0001` (404, no listed service with that slug — slugs are case-sensitive), `BCK.CATALOG.0002` (500, transient, retryable), `BCK.CATALOG.0003` (400, `protocol` filter must be one of `x402`, `mpp`, `rest`, `a2a`, `other`).
diff --git a/skills/nevermined-router/references/errors.md b/skills/nevermined-router/references/errors.md
index d1f41c9b..4cfa1d01 100644
--- a/skills/nevermined-router/references/errors.md
+++ b/skills/nevermined-router/references/errors.md
@@ -20,10 +20,56 @@ obstacles is exactly the failure mode this design exists to prevent.
| `BCK.ROUTER.0007` | 429 | Too many concurrent routed requests in flight | **Yes**, after backoff |
| `BCK.ROUTER.0008` | 403 | Legacy API key — create a new one | No |
| `BCK.ROUTER.0009` | 402 | Wallet doesn't hold enough of the asset on the target network. **Nothing was signed** | No — **stop** |
+| `BCK.ROUTER.0010` | 500 | Internal: the rail reported a charge amount that isn't a non-negative integer, so the Router can't reserve anything against the cap | No — **never blind-retry** |
+| `BCK.ROUTER.0011` | 402 | Card rail: the charge needs cardholder 3-D Secure, and an agent has no browser to complete it. Nothing was charged and the seller got no usable credential. | No — **needs a human** |
**Only `0006` and `0007` are worth retrying automatically.** The rest are decisions; retrying them
unchanged produces the same answer.
+### `0011` — the 402 that needs a human, not a retry
+
+Card rail only. The issuer demands **3-D Secure / SCA** before the charge can be used, and the Router
+has no human at a browser to complete it. **Nothing was charged, and the seller never received a
+usable credential** — the one Stripe created cannot be charged while it awaits authentication.
+
+Do **not** auto-retry. 3DS is often mandated per charge by industry rules, so every attempt
+re-demands it and mints another single-use card credential that is then abandoned — each expiring on
+its own at `min(the merchant's quoted expiry, your Delegation's expiry, 89 days)`. A later attempt
+*may* succeed, since whether authentication is demanded is decided per charge by the issuer, the card
+networks and Stripe's risk checks — but treat that as a human decision, not a loop.
+
+It is distinct from both other 402s: `0003` is your cap, `0009` is a card refused for lack of funds.
+Here the card is fine; it simply has not been authenticated for this charge.
+
+### `0010` — the 500 you must not retry
+
+`0006` and `0010` are both 500s and behave in opposite ways, so "retry 5xx" is the wrong reflex
+here. Note also that `0006` is raised **only by the payments summary read**, never by a payment —
+so on the paying path, `0007` is the only code worth retrying at all.
+
+`0010` means a payment handler reported a settlement amount in cents that isn't a non-negative
+integer, so the routing-fee arithmetic can't compute what to reserve. It deliberately fails rather
+than defaulting to zero — reserving nothing would let the payment through free.
+
+What that leaves behind is the important part:
+
+- **No budget was reserved and no payment record was written.**
+- **But a payment credential WAS already minted**, because the fee is quoted after the signing step.
+- **Therefore your `requestId` cannot protect you.** Idempotency is enforced against the payment
+ record, and there is no record — so a retry is treated as a brand-new purchase and mints a
+ **fresh** credential.
+- The cause is a deterministic defect in that rail's `approxCents` derivation, not a transient
+ blip, so the retry fails in exactly the same way.
+
+**How much that actually costs you depends on the rail.** On the crypto rails the credential never
+leaves the Router process on this path, so no funds can move and nothing is at risk. On the card
+rail it is a Stripe Shared Payment Token that is left **stranded**: there is no revoke path, so it
+stands until `min(the merchant challenge's expiry, your Delegation's expiry, 89 days)`. You cannot
+clean it up from the outside.
+
+**Seeing `0010` at all is a Nevermined-side regression.** No rail emits a non-numeric amount today,
+so this is a bug to report, not a condition to handle. Report it to the human. Do not loop.
+
Catalog codes: `BCK.CATALOG.0001` (404, unknown slug — case-sensitive), `BCK.CATALOG.0002` (500,
transient, retryable), `BCK.CATALOG.0003` (400, bad `protocol` filter).
diff --git a/skills/nevermined-router/references/paying.md b/skills/nevermined-router/references/paying.md
index 4dceffb4..552bf830 100644
--- a/skills/nevermined-router/references/paying.md
+++ b/skills/nevermined-router/references/paying.md
@@ -82,7 +82,7 @@ you actually wanted.
**Use one stable id per logical purchase, reused across retries of that purchase.**
-- Same id on retry → returns the original payment. Safe.
+- Same id on retry → `409 BCK.ROUTER.0002` with the original `paymentId`, **not the resource**. Safe — and never escape that 409 with a fresh id.
- Fresh id on retry → buys again. Also safe, *if that is what you meant*.
Derive it from the work (`"search-nevermined-router-v1"`, a hash of the query, a task id). **A fresh