Skavio x402 MCP: handle expired payment terms without blindly paying again

Skavio x402 MCP separates free tool discovery from paid execution. Retry logic should preserve that distinction: refreshing payment terms must not silently authorize another purchase of the same operation. Before signing again, establish whether the original paid request was never submitted, has an uncertain outcome or has already settled.

Separate the task from its payment authorization

The central recovery rule is to preserve the identity of the intended task while investigating what happened to its payment. As a client-side design, persist an operation record and a fingerprint of the tool name and arguments before submission. Track payment attempts separately from result delivery, and allow only one active attempt per operation. These are integration recommendations, not verified Skavio-side duplicate protection. In the documented MCP payment flow, PaymentRequired arrives as an isError tool result, with structuredContent and a JSON text representation. An MCP client should not rely solely on an HTTP 402 status. A payment-aware client retries the same tool and arguments with payment in params._meta["x402/payment"]. Settlement information belongs in result._meta["x402/payment-response"]. Connecting a client or discovering tools does not authorize spending; paid execution requires an x402-aware wallet client. Timing fields also have different meanings. In x402 v2, maxTimeoutSeconds describes a payment-completion duration. For EIP-3009 authorizations, validBefore is an absolute Unix expiry timestamp. Neither establishes a Skavio job-quote lifetime. The reviewed documentation does not establish a Skavio-specific quote-renewal endpoint, exact expiry error or recovery lookup. The following branches are therefore recovery guidance, not an endpoint-by-endpoint renewal recipe. They cover public per-call x402 tools, not authenticated processing relays with their separate quote and credit workflow.

Case 1: the authorization was never submitted

If your durable records establish that no paid request was submitted, obtain current payment requirements through the documented unpaid challenge flow. Keep the original application operation record rather than creating another task merely because the payment terms expired. Compare the fresh requirements with the intended tool, arguments, network, token, recipient and amount. Obtain approval under the user's consent policy before signing; changed terms are not automatically covered by an earlier approval. If the arguments changed, review whether this is still the same intended operation rather than treating it as a routine retry. This branch requires evidence of non-submission. A missing response or an incomplete local log is not enough to conclude that nothing was sent. If you cannot establish non-submission, use the uncertain-outcome branch instead.

Case 2: the request was submitted, but the outcome is unknown

Stop automatic re-signing. Skavio's documentation explicitly warns against blindly creating another authorization after an uncertain response and directs developers to inspect the payment receipt and result, accounting for RPC outages and other failures. A timeout means the client did not obtain a conclusive response. It does not establish that payment failed. Likewise, an authorization that is expired now might have been used earlier. Where the x402 settlement_pending code is returned, the core specification treats it as nonterminal and requires a broadcast transaction hash and network. Preserve those references for reconciliation rather than interpreting the state as permission to pay again. Inspect available settlement metadata, payment evidence and result information using documented facilities. If the outcome remains unresolved, block another paid attempt and hand the operation to support. A bounded retry policy should end in an explicit unresolved state, not an endless cycle of fresh signatures.

Case 3: payment settled, but the result is missing

Treat this as a result-recovery problem, not a new paid invocation. Recover the original response through a documented facility if one is available. If no supported recovery route can be established, escalate rather than issuing another paid call. The optional x402 payment-identifier extension describes response recovery using a persisted payment ID, request-fingerprint binding and cached responses within a configured retention window. Those protections depend on the server advertising and implementing the extension; they are not verified Skavio guarantees. A fingerprint mismatch should be handled as a conflict. Do not blindly reuse a payment identifier or generate another one merely to bypass that conflict. After the configured cache TTL expires, the same identifier may be processed normally again, so it must not be treated as permanent duplicate protection. For an unresolved Skavio call, contact support@getskavio.com with nonsecret request references and available transaction hashes. Do not include wallet secrets or full signed payment payloads. Keep confirmed settlement separate from result delivery: evidence of payment does not itself establish that the requested tool result was delivered.

Test recovery before allowing unattended paid retries

Use mocked responses to exercise the failure paths before enabling live spending. The goal is to check that your client preserves one intended operation through interruption—not to claim that token-transfer controls guarantee exactly-once tool execution. These are suggested tests, not completed Skavio acceptance results. The research behind this guide was documentation-only; no funded retry, concurrent invocation or lost-response recovery test was performed.

Read the Skavio x402 MCP documentation →