Payment flow
Request authentication, x402 settlement, credit billing, and recovery by request ID.
Authenticate the business request
Authenticated resource calls use X-SOVRx402-Request-Auth. Its EIP-712 signature binds the agent, requestId, purpose, mode, GET path, canonical query hash, price, paymentId, chain ID, and timestamp to the Registry address. The SDK builds this header when registryAddress and pricePerCall are configured.
Use a random bytes32 requestId as the durable identity of one invocation. Reuse it only for the same payer, path, business parameters, mode, and price. Conflicting reuse returns 409 REQUEST_CONFLICT. Resource signatures expire after 300 seconds; a fresh signature can retrieve the original stored result.
Choose a billing mode
New resource invocations require registration. The handler prepares and stores its JSON output before billing. A handler failure returns 502 RESOURCE_FAILED with charged set to 0; the gateway does not bill that failed preparation.
| Mode | Behavior in the resource gateway |
|---|---|
| auto | Uses credit when debt plus price fits the limit; otherwise selects prepaid settlement. |
| prepaid | Requires x402 payment even when credit is available. |
| credit | Requires available credit. Insufficient credit returns 409 CREDIT_EXHAUSTED. |
Prepaid settlement
- The gateway returns HTTP 402 with PAYMENT-REQUIRED for a prepared prepaid request.
- The SDK validates the exact scheme, network, token, configured amount, and payment-payload consistency. It signs through the x402 client and retries once with PAYMENT-SIGNATURE plus request authentication bound to the payment ID.
- The facilitator broadcasts the supported token settlement to the configured payTo recipient. The gateway reconciles the original transaction and Transfer event before releasing the stored result.
- Prepayment scoring is a separate operator transaction. A paid resource result can return 200 with creditRecorded=false while scoring awaits recovery; payment and delivery do not need a second charge.
Credit billing
A credit call adds the configured price to CreditLedger debt through the operator. The contract enforces the limit, and the resource gateway releases the prepared result after the matching DebtAdded receipt is confirmed. The operator pays gas; the agent incurs a token liability to repay later.
Each credit call still creates an on-chain transaction. The gateway persists the intended transaction hash before broadcasting so a lost response can be reconciled without automatically adding another debt.
Recover the original result
GET /results/:id requires the original payer's signed result-purpose request with price 0, mode auto, and a zero paymentId. BaseAgent.getResult(requestId) creates this signature. Retrieval does not create a new payment or debt, and already charged results remain readable during gateway maintenance when storage and RPC reads are available.
Pending billing returns 202 BILLING_PENDING, not a completed result. Prepared but unpaid records return 409 NOT_CHARGED; failed credit billing returns 409 BILLING_FAILED. The SDK throws GatewayError for non-200 responses, including 202, and attaches requestId to call/retrieval errors. It does not poll or automatically retry ambiguous failures.
Preserve the request ID and inspect the original result/receipt before deciding whether another invocation is needed. Keep the gateway result store, shared settlement journal, credit nonce history, and gas budget records intact across restarts.
Legacy /alpha behavior
Without a resource-auth header, /alpha retains its older payment path. It accepts an agent query and optional X-SOVRx402-Credit-Auth proof for credit; missing credit proof falls back to prepayment when registration is valid. It returns fixed example data.
The legacy path can return 502 after a successful payment if score recording fails. Treat that response as potentially paid and reconcile its paymentId and transaction through the settlement journal. Legacy responses do not provide the newer durable result contract. Replaying a completed legacy payment returns 402; it is not a result-retrieval operation.