{"openapi":"3.1.0","info":{"title":"ERPC x402 RPC (Solana + Ethereum)","version":"1.2.0","description":"Stablecoin-gated JSON-RPC proxies plus an account-bound EURC credit top-up. POST /v1/solana-mainnet (Solana mainnet) and POST /v1/eth-mainnet (Ethereum mainnet) charge per JSON-RPC method via the x402 protocol; POST /v1/credits/topup lets an ERPC account (x402 billing JWT from /v1/account/mint) buy ERPC credits with EURC on Base (eip155:8453) — priced by the account VAT quote, receipt and credit grant issued by the ERPC receipt service. Two payment rails are advertised in every 402 `accepts`: USDC on Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) and USDC on Base (eip155:8453; EURC on Base when enabled). Ethereum L1 is never a settlement network — the Coinbase CDP facilitator cannot settle there — so the Ethereum RPC is paid for on Base or Solana. Every payment is verified and settled through the Coinbase CDP facilitator."},"servers":[{"url":"https://x402.erpc.global"}],"paths":{"/v1/credits/topup/sessions/{sessionId}/cancel":{"post":{"operationId":"cancelGaslessCreditSession","summary":"Cancel an undispatched purchase preparation","description":"Access through the authenticated user-api Dashboard wrapper. Required JSON {} cancels only ready preparation. Returns the actual owned state if dispatch already won; it does not revoke any exposed authorization on-chain. No quote, payment, recovery or completion is invoked. No-store.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"200":{"description":"Actual cancelled, expired, submitting, outcome_unknown, pending, granted or stuck state with original purchase"},"400":{"description":"Invalid body"},"401":{"description":"Unauthorized"},"404":{"description":"No owned session"},"429":{"description":"Ingress rate limit"},"503":{"description":"Unavailable; recover same session by GET"}}}},"/v1/credits/topup/sessions":{"post":{"operationId":"prepareGaslessCreditSession","summary":"Prepare an account-bound Base EURC purchase session","description":"Dashboard clients use POST /v3/user/credit-gasless-sessions through user-api. This backend endpoint validates the forwarded Dashboard bearer through USER_API. A UUID clientRequestId replays the immutable purchase; changed payer or amount conflicts. Ready contains EIP-3009 typed data and purchase, never quoteToken or internal requirements. Prepare failures include creationOutcome: not_started means this invocation did not dispatch creation, not absence of historical sessions; unknown requires recovery with the saved clientRequestId. Request body limit: 4 KiB. Responses are no-store.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["clientRequestId","amountCredits","payer"],"properties":{"clientRequestId":{"type":"string","format":"uuid"},"amountCredits":{"type":"integer","minimum":1,"maximum":10000},"payer":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$"}}}}}},"responses":{"200":{"description":"Stored ready or replayed session with original purchase summary"},"400":{"description":"Invalid request or ineligible payer"},"401":{"description":"Unauthorized"},"409":{"description":"Conflicting request or expired quote"},"429":{"description":"Purchase limit"},"503":{"description":"Unavailable; no signable data"}}}},"/v1/credits/topup/sessions/{sessionId}/submit":{"post":{"operationId":"submitGaslessCreditSession","summary":"Dispatch one immutable EURC authorization","description":"Access through the user-api Dashboard wrapper. Canonical 65-byte ECDSA signature only. Durable claim permits one application settlement invocation. After dispatch, uncertainty is resumable by sessionId and never requests another payment. Expired unused sessions reject with quote_expired.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["signature"],"properties":{"signature":{"type":"string","pattern":"^0x[0-9a-fA-F]{130}$"}}}}}},"responses":{"200":{"description":"Granted purchase"},"202":{"description":"Submitting, unknown, or pending purchase; no typed data"},"400":{"description":"Invalid signature or request"},"401":{"description":"Unauthorized"},"404":{"description":"No session owned by this account"},"409":{"description":"Conflicting signature, changed/expired quote, or stuck purchase"},"503":{"description":"Unavailable; resume this session"}}}},"/v1/credits/topup/sessions/{sessionId}":{"get":{"operationId":"getGaslessCreditSession","summary":"Resume a durable Base EURC purchase","description":"Account-owned status through user-api. Returns stored purchase on every success. Unknown settlement scans one bounded safe nonce page; only the existing invoice verifier can grant credit. Empty evidence never proves unpaid. No-store.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ready, submitting, outcome_unknown, pending, granted, stuck, or expired with immutable purchase"},"401":{"description":"Unauthorized"},"404":{"description":"No session owned by this account"},"503":{"description":"Status unavailable"}}}},"/v1/solana-mainnet":{"post":{"operationId":"solanaJsonRpc","summary":"Solana JSON-RPC (paid)","description":"Pay-per-request Solana JSON-RPC proxy. Accepts single or batch JSON-RPC 2.0 bodies. Pricing follows the canonical ERPC token model: standard JSON-RPC methods cost a flat 42 tokens, getProgramAccounts 4200, getTokenLargestAccounts 2400, and getMultipleAccounts 420 × the number of pubkeys in params[0] (min 1). Unknown methods default to 42 tokens. Every payment is floored to a minimum charge of 1000 atomic USDC = $0.001 (the Coinbase CDP facilitator minimum settlement amount), so standard methods that would otherwise be 42 atomic ($0.000042) are charged $0.001. The first call returns 402 with an x402 payment challenge whose amount is max(summed token weight, 1000) times the base token price (1 token = $0.000001 = 1 atomic USDC, i.e. $1 per 1,000,000 tokens). The same body retried with X-Payment is settled in USDC on Solana mainnet and proxied to the upstream Solana RPC.","x-pay-pricing":{"model":"per_method_weight","base_token_price_usd":0.000001,"min_charge_atomic":1000,"min_charge_usd":0.001,"currency":"USDC","network":"solana","settlement_networks":["solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","eip155:8453"]},"parameters":[{"name":"X-Payment","in":"header","required":false,"description":"x402 payment payload (base64-encoded). Omitted on the first call, which returns 402 with an x402 challenge. On the retry the client re-sends the same JSON-RPC body with this header carrying the signed Solana USDC payment for the challenged amount; the worker verifies and settles it before proxying upstream. The legacy header name Payment-Signature is also accepted as a fallback. Each settled payment signature is single-use within the settlement TTL — replaying it returns 409 duplicate_payment.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/JsonRpcRequest"},{"type":"array","items":{"$ref":"#/components/schemas/JsonRpcRequest"},"minItems":1,"maxItems":100}]},"examples":{"getBalance":{"summary":"Single getBalance (42 canonical tokens, floored to $0.001)","value":{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["11111111111111111111111111111111"]}},"batch":{"summary":"Batch (getSlot 42 + getBlockHeight 42 = 84 tokens, floored to $0.001)","value":[{"jsonrpc":"2.0","id":1,"method":"getSlot"},{"jsonrpc":"2.0","id":2,"method":"getBlockHeight"}]},"getMultipleAccounts":{"summary":"getMultipleAccounts (420 × pubkey count; 2 pubkeys = 840 tokens, floored to $0.001)","value":{"jsonrpc":"2.0","id":1,"method":"getMultipleAccounts","params":[["vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg","4fYNw3dojWmQ4dXtSGE9epjRGy9pFSx62YypT7avPYvA"]]}}}}}},"responses":{"200":{"description":"Upstream JSON-RPC response. Includes X-Payment-Response header from the facilitator.","headers":{"X-Payment-Response":{"schema":{"type":"string"},"description":"Base64-encoded x402 settlement receipt for the X-Payment submitted on this request. Also mirrored as the Payment-Response header."},"Payment-Response":{"schema":{"type":"string"},"description":"Human-readable mirror of X-Payment-Response."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"400":{"description":"Invalid JSON-RPC body."},"402":{"description":"Payment Required. Returned (a) before payment with x402 challenge headers, and (b) when a submitted payment is invalid/rejected by the facilitator. The error.code is payment_required, payment_invalid, price_mismatch, or payment_amount_too_low (amount below the 1000-atomic / $0.001 facilitator minimum). Facilitator verify/settle errors are surfaced here as a descriptive 402 rather than an HTTP 500. A replayed (already-used) payment signature is rejected separately as 409 duplicate_payment, not 402.","headers":{"X-Payment-Required":{"schema":{"type":"string"},"description":"x402 challenge (base64) describing accepted scheme/network/asset/amount/recipient"},"Payment-Required":{"schema":{"type":"string"},"description":"Human-readable challenge mirror"},"X-Rpc-Weight":{"schema":{"type":"integer"},"description":"Charged token weight of the JSON-RPC body: max(summed canonical weight, 1000-atomic minimum). Standard methods report 1000 after the floor. See x-pay-pricing."},"X-Rpc-Price-Usd":{"schema":{"type":"string"},"description":"Computed (floored) price in USD for this request; minimum $0.001"},"X-Rpc-Rails-Degraded":{"schema":{"type":"string"},"description":"Present when an advertised rail could not be built this time (comma-separated <network>/<asset>); the remaining rails in accepts are still payable."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequiredBody"}}}},"409":{"description":"Duplicate payment. The payment signature has already been used within the settlement TTL (replay / double-spend protection enforced by the SettlementCache). error.code is duplicate_payment; the client must obtain a fresh payment before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicatePaymentBody"}}}},"413":{"description":"Batch size exceeds MAX_BATCH_SIZE (100)."}}}},"/v1/eth-mainnet":{"post":{"operationId":"ethereumJsonRpc","summary":"Ethereum mainnet JSON-RPC (paid)","description":"Pay-per-request Ethereum mainnet JSON-RPC proxy, geo-routed to the nearest ERPC Ethereum origin. Accepts single or batch JSON-RPC 2.0 bodies. Pricing uses a separate Ethereum table with the same token arithmetic as Solana: standard methods cost a flat 42 tokens (the ERPC Ethereum plan rate), eth_call / eth_estimateGas / eth_createAccessList / eth_getProof / txpool_contentFrom 420, eth_getLogs / eth_getFilterLogs / eth_getBlockReceipts / txpool_content / txpool_inspect 2400, eth_simulateV1 / eth_callMany 4200, and eth_getBlockByNumber / eth_getBlockByHash 42 with transaction hashes or 2400 with full transaction objects (params[1] === true). Batches are summed, then floored once to the 1000-atomic ($0.001) facilitator minimum. Methods outside the ERPC Ethereum catalog — including the debug_* and trace_* namespaces and the WebSocket-only eth_subscribe / eth_unsubscribe — are rejected with 400 method_not_supported BEFORE any payment is requested. The 402 challenge advertises every enabled rail (Solana USDC, Base USDC, Base EURC when enabled); the same body retried with X-Payment is settled on the rail the payer chose and proxied upstream.","x-pay-pricing":{"model":"per_method_weight","base_token_price_usd":0.000001,"min_charge_atomic":1000,"min_charge_usd":0.001,"currency":"USDC","network":"base","settlement_networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"],"rpc_chain":"ethereum-mainnet"},"parameters":[{"name":"X-Payment","in":"header","required":false,"description":"x402 payment payload (base64-encoded). Omitted on the first call, which returns 402 with an x402 challenge listing every accepted rail. On the retry the client re-sends the same JSON-RPC body with this header carrying the signed payment for the challenged amount — an EIP-3009 transferWithAuthorization on Base (USDC or EURC) or a Solana USDC transfer — and the worker verifies and settles it before proxying upstream. The legacy header name Payment-Signature is also accepted as a fallback. Each settled payment is single-use within the settlement TTL, scoped by network — replaying it returns 409 duplicate_payment.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/JsonRpcRequest"},{"type":"array","items":{"$ref":"#/components/schemas/JsonRpcRequest"},"minItems":1,"maxItems":100}]},"examples":{"blockNumber":{"summary":"Single eth_blockNumber (42 canonical tokens, floored to $0.001)","value":{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}},"getLogs":{"summary":"eth_getLogs (2400 tokens = $0.0024)","value":{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"latest","toBlock":"latest"}]}},"fullBlock":{"summary":"eth_getBlockByNumber with full transactions (2400 tokens = $0.0024)","value":{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",true]}}}}}},"responses":{"200":{"description":"Upstream JSON-RPC response. Includes X-Payment-Response header from the facilitator.","headers":{"X-Payment-Response":{"schema":{"type":"string"},"description":"Base64-encoded x402 settlement receipt for the X-Payment submitted on this request (includes the settlement transaction hash and network). Also mirrored as the Payment-Response header."},"Payment-Response":{"schema":{"type":"string"},"description":"Human-readable mirror of X-Payment-Response."},"X-Rpc-Methods":{"schema":{"type":"string"},"description":"Comma-separated unique methods in the body"},"X-Rpc-Weight":{"schema":{"type":"integer"},"description":"Charged (floored) token weight"},"X-Rpc-Price-Usd":{"schema":{"type":"string"},"description":"Charged price in USD"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"400":{"description":"Invalid JSON-RPC body, or a method the ERPC Ethereum edge does not offer (error.code method_not_supported: debug_*, trace_*, eth_subscribe / eth_unsubscribe, and anything outside GET /pricing → ethereum.methods). No payment is requested in this case.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MethodNotSupportedBody"}}}},"402":{"description":"Payment Required. Returned (a) before payment with x402 challenge headers, and (b) when a submitted payment is invalid/rejected by the facilitator. `accepts` lists one PaymentRequirements entry per enabled rail: Solana USDC (asset = USDC mint), Base USDC and — when enabled — Base EURC (asset = ERC-20 contract address, extra.name / extra.version = EIP-712 domain for EIP-3009). error.code is payment_required, payment_invalid, price_mismatch, or payment_amount_too_low.","headers":{"X-Payment-Required":{"schema":{"type":"string"},"description":"x402 challenge (base64) describing every accepted scheme/network/asset/amount/recipient"},"Payment-Required":{"schema":{"type":"string"},"description":"Human-readable challenge mirror"},"X-Rpc-Methods":{"schema":{"type":"string"},"description":"Comma-separated unique methods in the body"},"X-Rpc-Weight":{"schema":{"type":"integer"},"description":"Charged token weight of the JSON-RPC body: max(summed canonical weight, 1000-atomic minimum)."},"X-Rpc-Price-Usd":{"schema":{"type":"string"},"description":"Computed (floored) price in USD for this request; minimum $0.001"},"X-Rpc-Rails-Degraded":{"schema":{"type":"string"},"description":"Present when an advertised rail could not be built this time (comma-separated <network>/<asset>); the remaining rails in accepts are still payable."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequiredBody"}}}},"409":{"description":"Duplicate payment. The payment signature has already been used within the settlement TTL on its network (replay / double-spend protection enforced by the SettlementCache). error.code is duplicate_payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicatePaymentBody"}}}},"413":{"description":"Batch size exceeds MAX_BATCH_SIZE (100)."}}}},"/v1/credits/topup":{"post":{"operationId":"creditTopup","summary":"Buy ERPC credits with EURC on Base (account-bound x402 payment)","description":"Second product on this host: instead of paying per JSON-RPC call, an ERPC account tops up its credit balance (1 credit = 1 EURC net of VAT) and then buys hourly resources through the ERPC User API with the same billing JWT. Flow: (1) `Authorization: Bearer <access token from POST /v1/account/mint>` + `{ \"amountCredits\": N }` → 402 whose `accepts` carries exactly ONE requirement — EURC on Base (eip155:8453), `amount` = the VAT-inclusive total the User API quoted for THIS account (`topup` block echoes it), `payTo` = the ERPC treasury; (2) sign an EIP-3009 `transferWithAuthorization` for that requirement and re-POST with `X-Payment` (or `Payment-Signature`); (3) the worker verifies and settles through the CDP facilitator, durably records the settlement, then asks the User API to issue the EUR receipt and grant the credits. 200 = granted (invoice in body, `Payment-Response` header), 202 = settled but the grant is still pending — poll `statusUrl` (GET below) with the SAME Bearer; it is completed on your poll. 409 `topup_completion_failed` = settled but refused by the receipt service; the payment is recorded for operator review — do NOT pay again. Re-presenting the same X-Payment within 5 minutes returns the recorded status instead of settling twice. Eligibility (EU-27 billing address, €5 card authentication, EU-issued card when cards are saved) is enforced by the User API quote; a refused quote is relayed as 400 `topup_rejected`. Caps: `amountCredits` ≤ 10,000 per payment, ≤ 5 top-ups per account per hour (429).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amountCredits"],"properties":{"amountCredits":{"type":"integer","minimum":1,"maximum":10000,"description":"ERPC credits to buy (1 credit = 1 EURC net; VAT is added by the quote)."}}}}}},"parameters":[{"name":"X-Payment","in":"header","required":false,"description":"x402 payment payload for the requirement returned in the 402 (EIP-3009 authorization, EURC on Base). Also accepted as Payment-Signature.","schema":{"type":"string"}}],"responses":{"200":{"description":"Settled and granted. Body carries the receipt; `Payment-Response` carries the facilitator settle receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}},"202":{"description":"Settled; grant pending (receipt service temporarily unavailable). Poll `statusUrl` with the same Bearer; `Retry-After: 60`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}},"400":{"description":"Invalid body / amount outside 1..10000 (`invalid_request`), or the User API refused the quote (`topup_rejected`, message relayed: billing address, EU country, card gate)."},"401":{"description":"Missing or invalid billing JWT (uniform)."},"402":{"description":"Payment required / invalid / mismatched. `accepts` has exactly one EURC-on-Base requirement; `topup` echoes the quote.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupPaymentRequiredBody"}}}},"409":{"description":"Settled but the receipt service refused the completion (`topup_completion_failed`) — recorded for operator review, do not pay again; or `duplicate_payment` when the same X-Payment is replayed without a record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}},"429":{"description":"Per-IP limit or the per-account hourly cap (`rate_limited`)."},"500":{"description":"Top-up rail closed (`configuration_error`): EVM rail off, not Base mainnet, EURC not enabled, or PAY_TO_EVM_ADDRESS ≠ the ERPC treasury constant. Never charges."},"502":{"description":"Facilitator settle failure (`settlement_failed`)."},"503":{"description":"Quote service unavailable (`service_busy`). Retry later."}}}},"/v1/credits/topup/{txHash}":{"get":{"operationId":"creditTopupStatus","summary":"Status of a credit top-up (drives a pending completion)","description":"Returns the durable record of a top-up settled through POST /v1/credits/topup for the authenticated account. A `pending` (or freshly `settled`) record is re-attempted against the receipt service on this call: the worker reports its own settle result (the account it verified, the payer of the settled authorization and the settle tx) to the worker-only completion route of user-api using the service bearer of this worker; your Bearer only identifies which record you may read and drive and is never forwarded. Records of other accounts answer 404.","security":[{"bearerAuth":[]}],"parameters":[{"name":"txHash","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"granted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}},"202":{"description":"still pending — poll again (`Retry-After: 60`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}},"400":{"description":"Malformed txHash."},"401":{"description":"Missing or invalid billing JWT."},"404":{"description":"No such top-up for this account."},"409":{"description":"stuck — settled but refused; operator review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupStatusBody"}}}}}}},"/health":{"get":{"operationId":"health","summary":"Public health probe (free)","responses":{"200":{"description":"Health status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"network":{"type":"string","description":"Solana settlement network (solana | solana-devnet)"},"region":{"type":"string"},"evmNetwork":{"type":"string","description":"EVM settlement network (base | base-sepolia)"},"evmRailEnabled":{"type":"boolean"},"evmConfigError":{"type":"string","description":"Present only when EVM settings exist but did not parse (e.g. mis-checksummed PAY_TO_EVM_ADDRESS, unknown EVM_ASSETS). The EVM rail is then off; every route keeps serving."},"ethUpstreamConfigured":{"type":"boolean","description":"False while /v1/eth-mainnet has no Ethereum upstream (no override URL, no proxy-rpc-eth service binding, no origin Basic credential) — it then answers 500 configuration_error before any payment."},"ethUpstreamMode":{"type":"string","enum":["override","binding","origin-basic","unconfigured"],"description":"Which Ethereum upstream /v1/eth-mainnet uses, in precedence order: UPSTREAM_ETH_RPC_URL override, PROXY_RPC_ETH service binding (proxy-rpc-eth x402 lane), geo-routed origins with a Basic credential."},"rails":{"type":"array","description":"Enabled payment rails","items":{"$ref":"#/components/schemas/PaymentRail"}},"endpoints":{"type":"array","items":{"type":"string"}},"ethBindingNote":{"type":"string","description":"Present when the proxy-rpc-eth binding exists but X402_LANE_SECRET is unset (binding unused)."},"topup":{"type":"object","description":"Credit top-up rail (POST /v1/credits/topup).","properties":{"enabled":{"type":"boolean"},"topupTreasuryMatch":{"type":"boolean","description":"PAY_TO_EVM_ADDRESS equals the checked-in ERPC Base EURC treasury constant — the fence that keeps the 402 payTo, the User API quote and the receipt-service verifier on one address. False closes the rail before any payment."},"closedReason":{"type":"string"},"maxCreditsPerTx":{"type":"integer"},"maxPerAccountPerHour":{"type":"integer"}}}}}}}}}}},"/pricing":{"get":{"operationId":"pricing","summary":"Public weight + USD price table (free)","responses":{"200":{"description":"Per-method weight and price","content":{"application/json":{"schema":{"type":"object","properties":{"tokenPriceUsd":{"type":"number"},"minChargeAtomic":{"type":"integer","description":"Minimum charge per payment in atomic USDC (CDP facilitator floor); 1000 = $0.001"},"minChargeUsd":{"type":"number","description":"Minimum charge in USD ($0.001)"},"defaultUnknownMethodWeight":{"type":"integer","description":"Charged (floored) weight for unknown methods"},"defaultUnknownMethodRawWeight":{"type":"integer","description":"Canonical pre-floor weight for unknown methods (42)"},"defaultUnknownMethodPriceUsd":{"type":"number"},"solana":{"type":"object","description":"Solana table (/v1/solana-mainnet); same entries as top-level methods","properties":{"endpoint":{"type":"string"},"methods":{"type":"array","items":{"$ref":"#/components/schemas/PricingTableEntry"}}}},"ethereum":{"type":"object","description":"Ethereum table (/v1/eth-mainnet). Methods outside it are rejected with 400 method_not_supported.","properties":{"endpoint":{"type":"string"},"standardMethodWeight":{"type":"integer"},"standardMethodRawWeight":{"type":"integer"},"unknownMethodPolicy":{"type":"string","enum":["reject_400_method_not_supported"]},"methods":{"type":"array","items":{"$ref":"#/components/schemas/PricingTableEntry"}}}},"methods":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string"},"weight":{"type":"integer","description":"Charged token weight after the minimum-charge floor"},"rawWeight":{"type":"integer","description":"Canonical token weight before the floor"},"floored":{"type":"boolean","description":"True when the floor raised this method above its canonical weight"},"price_usd":{"type":"number"},"price":{"type":"string"},"dynamic":{"type":"boolean","description":"True when the weight scales with request params (e.g. getMultipleAccounts)"},"perPubkeyWeight":{"type":"integer","description":"Token weight charged per pubkey for dynamic methods"},"note":{"type":"string"}}}}}}}}}}}},"/.well-known/x402":{"get":{"operationId":"wellKnownX402","summary":"x402 scheme and network metadata (free)","responses":{"200":{"description":"x402 capabilities","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"facilitator":{"type":"string"},"accepts":{"type":"array","description":"One entry per (endpoint × enabled rail)","items":{"type":"object","properties":{"scheme":{"type":"string"},"network":{"type":"string"},"asset":{"type":"string"},"assetAddress":{"type":"string"},"endpoint":{"type":"string"},"methods":{"type":"array","items":{"type":"string"}}}}},"endpoints":{"type":"array","items":{"type":"object","properties":{"endpoint":{"type":"string"},"chain":{"type":"string","enum":["solana","ethereum"]},"methods":{"type":"array","items":{"type":"string"}},"accepts":{"type":"array","items":{"$ref":"#/components/schemas/PaymentRail"}},"status":{"type":"string","enum":["ready","unconfigured"],"description":"unconfigured = the endpoint answers 500 configuration_error before payment until its upstream is configured"}}}}}}}}}}}}},"components":{"schemas":{"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"method":{"type":"string"},"params":{}}},"JsonRpcResponse":{"type":"object","properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"},{"type":"null"}]},"result":{},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"},"data":{}}}}},"PaymentRail":{"type":"object","description":"A (network, asset, scheme) a buyer may settle with.","properties":{"scheme":{"type":"string","enum":["exact"]},"network":{"type":"string","description":"CAIP-2 network: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | eip155:8453 | eip155:84532"},"asset":{"type":"string","enum":["USDC","EURC"]},"assetAddress":{"type":"string","description":"EVM rails only: ERC-20 contract address"}}},"PaymentRequirements":{"type":"object","description":"x402 PaymentRequirements (one per rail in `accepts`). For Solana, asset is the USDC mint and extra carries the facilitator feePayer. For Base, asset is the USDC/EURC ERC-20 address and extra.name / extra.version is the EIP-712 domain the EIP-3009 transferWithAuthorization must be signed against. extra.erpc echoes the priced methods.","properties":{"scheme":{"type":"string","enum":["exact"]},"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string","description":"Atomic units (6 decimals for USDC / EURC)"},"payTo":{"type":"string"},"maxTimeoutSeconds":{"type":"integer"},"extra":{"type":"object","properties":{"name":{"type":"string","description":"EVM: EIP-712 domain name (e.g. \"USD Coin\", \"EURC\")"},"version":{"type":"string","description":"EVM: EIP-712 domain version (\"2\")"},"feePayer":{"type":"string","description":"Solana: facilitator fee payer"},"erpc":{"type":"object","properties":{"methods":{"type":"array","items":{"type":"string"}},"weight":{"type":"integer"},"priceUsd":{"type":"number","description":"USD-denominated price (1 token = $0.000001)"},"tokenPriceUsd":{"type":"number"},"settlement":{"type":"object","description":"EVM rails only: what is actually settled. On a EURC rail the same atomic amount is charged at par with USDC (no FX), which `note` states.","properties":{"asset":{"type":"string","enum":["USDC","EURC"]},"amountAtomic":{"type":"integer"},"decimals":{"type":"integer"},"note":{"type":"string"}}}}}}}}},"PricingTableEntry":{"type":"object","properties":{"method":{"type":"string"},"weight":{"type":"integer","description":"Charged token weight after the minimum-charge floor"},"rawWeight":{"type":"integer","description":"Canonical token weight before the floor"},"floored":{"type":"boolean"},"priceUsd":{"type":"number"},"price":{"type":"string"},"dynamic":{"type":"boolean"},"perPubkeyWeight":{"type":"integer"},"note":{"type":"string"}}},"MethodNotSupportedBody":{"type":"object","description":"Returned at HTTP 400 when a method is outside the ERPC Ethereum catalog.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["method_not_supported","invalid_request"]},"message":{"type":"string"},"request_id":{"type":"string"}}}}},"PaymentRequiredBody":{"type":"object","properties":{"x402Version":{"type":"integer"},"resource":{"type":"object","properties":{"url":{"type":"string"},"description":{"type":"string"},"mimeType":{"type":"string"}}},"accepts":{"type":"array","description":"One PaymentRequirements per enabled rail (Solana USDC, Base USDC, Base EURC when enabled)","items":{"$ref":"#/components/schemas/PaymentRequirements"}},"error":{"type":"object","properties":{"code":{"type":"string","enum":["payment_required","payment_invalid","price_mismatch","payment_amount_too_low"]},"message":{"type":"string"},"request_id":{"type":"string"}}},"pricing":{"type":"object","description":"Computed pricing for the submitted JSON-RPC body.","properties":{"weight":{"type":"integer","description":"Charged (floored) token weight"},"rawWeight":{"type":"integer","description":"Canonical pre-floor token weight"},"floored":{"type":"boolean"},"minChargeAtomic":{"type":"integer","description":"1000 ($0.001)"},"priceUsd":{"type":"number"},"price":{"type":"string"}}}}},"TopupPaymentRequiredBody":{"type":"object","description":"402 for POST /v1/credits/topup: one EURC-on-Base requirement priced by the account quote.","properties":{"x402Version":{"type":"integer"},"resource":{"type":"object","properties":{"url":{"type":"string"},"description":{"type":"string"},"mimeType":{"type":"string"}}},"accepts":{"type":"array","description":"Exactly one PaymentRequirements: network eip155:8453, asset = EURC contract, amount = totalEurcAtomic, payTo = ERPC treasury, maxTimeoutSeconds 300, extra.erpc.topup echoes the stable part of the quote (uidHash, amountCredits, totalEurc, totalEurcAtomic, vatRate, vatNote, settlement); the per-request quoteToken and quoteExpiresAt are deliberately absent so the requirement matches on the paid re-POST (quoteExpiresAt is in the body topup block).","items":{"$ref":"#/components/schemas/PaymentRequirements"}},"error":{"type":"object","properties":{"code":{"type":"string","enum":["payment_required","payment_invalid","price_mismatch","payment_amount_too_low","settlement_failed"]},"message":{"type":"string"},"request_id":{"type":"string"}}},"topup":{"type":"object","properties":{"amountCredits":{"type":"integer"},"totalEurc":{"type":"string","description":"VAT-inclusive EURC to pay, 2 decimals"},"totalEurcAtomic":{"type":"string","description":"Same amount in 6-decimal atomic units (= accepts[0].amount)"},"vatRate":{"type":"string","description":"4-decimal rate, e.g. \"0.2100\""},"vatNote":{"type":"string"},"quoteExpiresAt":{"type":"string","format":"date-time"},"receivingAddress":{"type":"string","description":"ERPC Base EURC treasury (lowercase)"},"duplicateWindowSeconds":{"type":"integer","description":"How long the same X-Payment returns the recorded status instead of settling again (300)"}}}}},"TopupStatusBody":{"type":"object","description":"Durable record of a settled top-up (200 granted / 202 pending / 409 stuck).","properties":{"status":{"type":"string","enum":["settled","pending","granted","stuck"]},"transaction":{"type":"string","description":"Base settle transaction hash (facilitator-submitted EIP-3009)"},"network":{"type":"string","enum":["eip155:8453"]},"payer":{"type":"string"},"amountAtomic":{"type":"string"},"amountCredits":{"type":"integer"},"attempts":{"type":"integer","description":"Completion attempts so far"},"invoiceNumber":{"type":"string"},"invoice":{"type":"object","description":"Receipt as issued by the ERPC receipt service (CreditGrantSubmitSuccess.invoice)"},"lastError":{"type":"string"},"statusUrl":{"type":"string","format":"uri"},"retryAfterSeconds":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"},"error":{"type":"object","description":"Present on 409: code topup_completion_failed","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}}}}},"DuplicatePaymentBody":{"type":"object","description":"Returned at HTTP 409 when a payment signature is replayed within the settlement TTL.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["duplicate_payment"]},"message":{"type":"string"},"request_id":{"type":"string"}}}}}}}}