diff --git a/development-guide/api-errors/codes.mdx b/development-guide/api-errors/codes.mdx index d4a7e4f..a733461 100644 --- a/development-guide/api-errors/codes.mdx +++ b/development-guide/api-errors/codes.mdx @@ -30,7 +30,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. - [`BCK.METRIC`](#bck-metric) — 5 codes - [`BCK.METRICS`](#bck-metrics) — 1 code - [`BCK.NOTIF`](#bck-notif) — 9 codes -- [`BCK.OAUTH`](#bck-oauth) — 29 codes +- [`BCK.OAUTH`](#bck-oauth) — 30 codes - [`BCK.OBSERVABILITY`](#bck-observability) — 5 codes - [`BCK.ORGANIZATIONS`](#bck-organizations) — 36 codes - [`BCK.ORG_INTEGRATION`](#bck-org_integration) — 2 codes @@ -40,7 +40,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. - [`BCK.PLANS`](#bck-plans) — 1 code - [`BCK.POINT`](#bck-point) — 19 codes - [`BCK.PROTOCOL`](#bck-protocol) — 57 codes -- [`BCK.ROUTER`](#bck-router) — 9 codes +- [`BCK.ROUTER`](#bck-router) — 10 codes - [`BCK.STRIPE`](#bck-stripe) — 34 codes - [`BCK.STRIPE.CONNECT`](#bck-stripe-connect) — 8 codes - [`BCK.TRANSCODING`](#bck-transcoding) — 4 codes @@ -106,7 +106,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | Code | HTTP | Category | Retryable | Message | Hint | |---|---|---|---|---|---| | `BCK.AUTH.0001` | 500 | internal | — | Error registering API Key | Inspect the underlying error in the logs by correlation id. API-key registration failed with an unexpected server-side error (usually a DB-layer fault). | -| `BCK.AUTH.0002` | 401 | auth | — | Authentication required: credentials are missing, expired or invalid | Send an Authorization: Bearer header or a valid Nevermined API key. Anonymous access is not permitted on this endpoint. | +| `BCK.AUTH.0002` | 401 | auth | — | Authentication required: credentials are missing, expired or invalid | Send an Authorization: Bearer <token> header or a valid Nevermined API key. Anonymous access is not permitted on this endpoint. | | `BCK.AUTH.0003` | 403 | auth | — | Forbidden: caller is not the owner of this resource and lacks an admin role | Authenticate as the resource owner or an admin who has access to it. Cross-account access is rejected unless you carry an admin role. | | `BCK.AUTH.0004` | 403 | auth | ❌ | Organisation admin privileges required | The caller is not an active admin of the target organisation. Prefer the more specific siblings (BCK.AUTH.0005-0009) at new throw sites; this code remains as a catch-all. | | `BCK.AUTH.0005` | 403 | auth | ✅ | Unable to verify organisation membership | The membership lookup itself failed (e.g. transient DB error). Check the cause field on the server log; retry once. | @@ -221,10 +221,10 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | Code | HTTP | Category | Retryable | Message | Hint | |---|---|---|---|---|---| -| `BCK.CREDITS.0001` | 400 | business | — | Mint amount must be positive | Send mint amount > 0. Zero or negative mints are rejected; cleanup of bad lots must happen through a refund path. | -| `BCK.CREDITS.0002` | 400 | business | — | Burn amount must be positive | Send burn amount > 0. Zero or negative burns are rejected. | +| `BCK.CREDITS.0001` | 400 | business | — | Mint amount must be positive | Send mint amount > 0. Zero or negative mints are rejected; cleanup of bad lots must happen through a refund path. | +| `BCK.CREDITS.0002` | 400 | business | — | Burn amount must be positive | Send burn amount > 0. Zero or negative burns are rejected. | | `BCK.CREDITS.0003` | 402 | business | — | Insufficient credits for plan | Buy or top up credits before retrying. The buyer wallet does not hold enough credits for the requested redemption. | -| `BCK.CREDITS.0004` | 400 | business | — | Refund amount must be positive | Send refund amount > 0. Zero or negative refunds are rejected; they are also bounded by the original mint amount. | +| `BCK.CREDITS.0004` | 400 | business | — | Refund amount must be positive | Send refund amount > 0. Zero or negative refunds are rejected; they are also bounded by the original mint amount. | | `BCK.CREDITS.0005` | 500 | business | — | Credit lots do not satisfy the burned amount — FIFO invariant violated | Inspect the underlying error and the planId/userId in params. The FIFO credit-lots ledger could not satisfy the burn — this indicates a data-integrity issue; do not retry blindly. | | `BCK.CREDITS.0006` | 500 | internal | ❌ | Cannot enqueue on-chain order mirror without a corresponding minted credit lot | enqueueFiatOrderMirror must be called after a successful creditsService.mint with the same sourceTx. This usually indicates an out-of-order call by a service, not a runtime data issue. | @@ -307,7 +307,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | Code | HTTP | Category | Retryable | Message | Hint | |---|---|---|---|---|---| -| `BCK.METRICS.0001` | 401 | auth | ❌ | Unauthorized metrics scrape | The internal metrics endpoint is token-protected (METRICS_SCRAPE_TOKEN is set). Send "Authorization: Bearer " matching the configured scrape token. | +| `BCK.METRICS.0001` | 401 | auth | ❌ | Unauthorized metrics scrape | The internal metrics endpoint is token-protected (METRICS_SCRAPE_TOKEN is set). Send "Authorization: Bearer <token>" matching the configured scrape token. | ## `BCK.NOTIF` @@ -356,6 +356,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | `BCK.OAUTH.0027` | 403 | auth | ❌ | This credential cannot create authorizations or spend mandates | An `account_access` credential is minted to SPEND against the card delegation it is bound to (via x402), NOT to run a new authorization ceremony or create another card mandate. It could otherwise mint itself a second, larger mandate on the same card, defeating the consented cap. Authorize from the human browser session, or use an agent-specific key for agent flows. #2574 B1. | | `BCK.OAUTH.0029` | 500 | internal | ❌ | Internal error creating the agent binding | A server-side data-integrity condition — an agent-specific (credits_purchase) binding reached persistence without an agent id, which the database CHECK forbids. No action is required from the caller; inspect the API logs (the failing authorization request id is on the error `details`/`params`). #2578. | | `BCK.OAUTH.0030` | 403 | auth | ❌ | This credential cannot use the Router spend rails or create delegations | An OAuth-minted credential (`credits_purchase` or `account_access`) may not call `POST /router/{payments,route,proxy}` or `POST /delegation/create`: those routes sign from the account wallet, outside the session-key policy the credential advertises — and a `credits_purchase` key owns no delegation, so any delegation it reaches was never consented for. Use a plain API key from the account owner, or the credential’s own x402 spend rail. #2575. | +| `BCK.OAUTH.0031` | 400 | auth | ❌ | Invalid client metadata document | The `client_id` was treated as a CIMD (Client ID Metadata Document) URL but did not resolve to a valid document. It must be an https URL on a public host that returns a JSON document whose `client_id` equals the URL and which declares a non-empty `client_name` and `redirect_uris`. If your host uses static registration instead, register it out-of-band and use its issued `client_id`. | ## `BCK.OBSERVABILITY` @@ -404,7 +405,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | `BCK.ORGANIZATIONS.0031` | 403 | business | ❌ | Realtime event streaming is not available for this organization tier | The realtime (WebSocket) activity stream is an Enterprise-only feature. Upgrade the organization to Enterprise to manage WebSocket secrets and subscribe to the live event stream. | | `BCK.ORGANIZATIONS.0032` | 404 | business | ❌ | WebSocket secret not found | No WebSocket secret with that id exists for the current member in this organization. It may have already been deleted, or belongs to a different member. | | `BCK.ORGANIZATIONS.0033` | 500 | business | ✅ | Failed to onboard customer | White-label customer provisioning failed unexpectedly (e.g. a Privy or key-minting outage). Inspect the underlying error in logs and retry — provisioning is idempotent by email. | -| `BCK.ORGANIZATIONS.0034` | 409 | business | ❌ | This customer is blocked by your organization | Your organization has blocked this customer, so no new credential can be issued to them. Unblock them first (POST /organizations/{orgId}/customers/{customerId}/unblock) if this was in error. | +| `BCK.ORGANIZATIONS.0034` | 409 | business | ❌ | This customer is blocked by your organization | Your organization has blocked this customer, so no new credential can be issued to them. Unblock them first (POST /organizations/{orgId}/customers/{customerId}/unblock) if this was in error. | | `BCK.ORGANIZATIONS.0035` | 409 | business | ❌ | This account has been disabled | The Nevermined account behind this email is disabled, so no credential can be issued for it. Contact support if the account should be reactivated. | | `BCK.ORGANIZATIONS.0036` | 500 | business | ✅ | Could not securely complete the member invitation | The bootstrap key minted while provisioning the invitee could not be revoked, so the invitation was failed closed rather than leave a live credential on the invitee account. Inspect the underlying error in logs and retry — provisioning is idempotent by email. | @@ -533,7 +534,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | `BCK.PROTOCOL.0052` | 400 | validation | ❌ | Unsupported settlement network | The requested network (chainId) is not served by this environment. Use a supported network — sandbox serves Base Sepolia (84532) and Tempo Moderato (42431); live serves Base (8453) and Tempo (4217). Off-chain plans (org-tier) do not settle on a chain (#1929). | | `BCK.PROTOCOL.0053` | 400 | validation | ❌ | Plan and agent must settle on the same network | A plan can only be linked to an agent on the same settlement network (chainId). A Tempo plan cannot be linked to a Base agent (and vice versa). Register the plan and agent on the same network, or link a plan that already settles on the agent’s network (#1929). | | `BCK.PROTOCOL.0054` | 503 | integration | ❌ | Could not migrate the agent ownership to your current wallet | Your agent was registered by a wallet that has since been migrated, and handing it over to your current wallet failed on-chain (bundler/paymaster/RPC), or a recent attempt is in its cooldown window. Do NOT retry in a loop — wait a few minutes and try the operation again. See #2152. | -| `BCK.PROTOCOL.0055` | 404 | validation | ❌ | Payment plan does not exist on-chain | The request references a planId that is not registered on the settlement network, so the on-chain call reverted with PlanNotFound. Check the planId (it is a uint256 decimal string, not a DID) and that it was created on the SAME network you are writing to. GET /api/v1/protocol/plans/{planId} confirms whether it exists (#2163). | +| `BCK.PROTOCOL.0055` | 404 | validation | ❌ | Payment plan does not exist on-chain | The request references a planId that is not registered on the settlement network, so the on-chain call reverted with PlanNotFound. Check the planId (it is a uint256 decimal string, not a DID) and that it was created on the SAME network you are writing to. GET /api/v1/protocol/plans/{planId} confirms whether it exists (#2163). | | `BCK.PROTOCOL.0056` | 409 | business | ❌ | This plan can only be purchased once per account, and you already own it | The plan installs the one-time-purchase hook (OneTimeCreatorHook), which allows a single agreement per (plan, buyer). Your account has already ordered it, so the on-chain call reverted with CreatorAlreadyCreatedAgreement. Nothing was charged. Use the credits you already hold, or order a different plan (#2164). | | `BCK.PROTOCOL.0057` | 400 | validation | ❌ | A value in the request could not be encoded for the on-chain call | An address or numeric value in the payload is malformed, so the call could not even be encoded — most commonly a token/receiver address whose EIP-55 checksum is wrong (mixed-case addresses are checksum-verified). Send the address all-lowercase, or with a correct checksum. `params.detail` names the offending value (#2478). | @@ -550,6 +551,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | `BCK.ROUTER.0007` | 429 | business | ✅ | Too many concurrent routed requests | You have too many in-flight mode-B routed requests (/route, /proxy) open at once. Let some complete before starting more, or slow the request rate. | | `BCK.ROUTER.0008` | 403 | business | ❌ | Router requires an EIP-7702 (v2) API key | This is a legacy (v1) API key bound to the old smart account, which cannot sign EIP-3009 from the unified funded wallet. Create a new API key — it will be issued as v2 (EIP-7702) and works with the Router. Existing v1 keys keep working for credit-based (nvm:erc4337) flows until they expire. | | `BCK.ROUTER.0009` | 402 | business | ❌ | Insufficient wallet balance to fund the payment | The buyer's custodial wallet does not hold enough of the payment asset on the target network to cover this charge. This is distinct from the delegation cap (BCK.ROUTER.0003): the cap authorizes the spend, but the wallet must also actually hold the funds. Fund the wallet on the target chain and retry. (MPP-tempo / crypto pulls settle from the wallet's own balance; the router never holds funds.) | +| `BCK.ROUTER.0010` | 500 | internal | ❌ | Router could not determine the amount to charge against the delegation cap | The payment handler reported a settlement amount in cents that is not a non-negative integer, so the routing-fee arithmetic (#2191) cannot compute what to reserve. This is an internal invariant violation, not a bad request — the value is produced by Nevermined, not the caller. It deliberately fails rather than defaulting to zero, which would reserve nothing and let the payment through free. DO NOT BLIND-RETRY: no budget was reserved and no payment record was written, but a payment credential WAS already minted (on the card rail, a Stripe Shared Payment Token that will auto-expire). Because no record exists, your requestId will not suppress a retry — and the cause is a deterministic defect in the rail's approxCents derivation, so a retry re-mints a fresh credential and fails identically. Report it instead. | ## `BCK.STRIPE` @@ -679,7 +681,7 @@ Every error response from the Nevermined API carries a stable `code` (e.g. `BCK. | `BCK.VISA.0017` | 502 | integration | — | Stripe Connect account lookup failed while resolving Visa merchant context | Inspect Stripe dashboard logs for the connected account id in params. Connect account lookup failed transiently — retry; if it persists, check the seller’s Connect status. | | `BCK.VISA.0018` | 409 | business | — | This card is already enrolled to a different account | Deprecated: no longer thrown. Visa enrolment no longer rejects a card already on file under another account (RFC-1 relaxed uniqueness, epic #1958). | | `BCK.VISA.0019` | 500 | internal | ❌ | Visa provider misconfigured for this environment | The Visa provider is otherwise wired but VGS_AGENTIC_BROWSER_CLIENT_ID/SECRET are missing. The browser-token endpoint would silently fall back to the privileged backend service account in this state. Provision the narrower Client-Side Service Account or unset the Visa env vars to disable the provider. See VIS-011 in security audit 2026-05-27. | -| `BCK.VISA.0020` | 502 | integration | ❌ | VGS GA Network-Token rail call failed | A server-to-server VGS GA Network-Token operation failed — provisioning a network token (POST /cards/{id}/network-tokens) or minting a GA cryptogram (POST /cards/{id}/cryptogram). Inspect cardId, status, and detail in params. This is the GA rail (no device binding), distinct from the Agentic-Tokens rail (BCK.VISA.0004). | +| `BCK.VISA.0020` | 502 | integration | ❌ | VGS GA Network-Token rail call failed | A server-to-server VGS GA Network-Token operation failed — provisioning a network token (POST /cards/{id}/network-tokens) or minting a GA cryptogram (POST /cards/{id}/cryptogram). Inspect cardId, status, and detail in params. This is the GA rail (no device binding), distinct from the Agentic-Tokens rail (BCK.VISA.0004). | | `BCK.VISA.0021` | 502 | integration | ❌ | VGS network-token provision-on-create failed (best-effort) | Provisioning a portable network token for a freshly enrolled VGS-canonical card failed (epic #1958, T2.A / #1976). This is BEST-EFFORT and never surfaced to the client: enrolment completes, the credential persists with networkToken NULL, and the charge path falls back to the legacy/instrument rail. Used as a stable code on the swallowed log line so the gap is alertable and backfill-able. Inspect cardId/credentialId in the log context. | ## `BCK.WIDGET`