402 Payment Required with a payment challenge. The x402 protocol standardizes this flow. The agent checks each payment with Conto before it pays.
x402 endpoints enforce explicit API-key scopes. Pre-authorization requires
payments:request,
managed signing (pay) and recording execution require payments:execute, and budget or service analytics require
analytics:read.Prerequisites
An active agent with an SDK key (Quickstart)
A funded wallet with
USDC on the network the API settles on (Base for production, or Base Sepolia for
testing). x402 is not offered on Tempo: pre-authorize and pay return 422 UNSUPPORTED_NETWORK for a
wallet on a network with no USDC.An x402-enabled API to call (or a test service that returns an x402 challenge)
How x402 works
See Conto-signed payments for the managed path.
Step 1: Set up x402 policies
Without x402-specific policies, only your general spend limits apply. The policy rule reference lists every x402 rule type and value format.Recommended starter policy
The two rules below belong to different x402 policy types, so this example usesCOMPOSITE.
1
Create the policy
Go to Policies > Create Policy.
2
Add rules
Rule 1: Cap per API call
No single x402 payment can exceed $0.50.Rule 2: Budget per service
Spend with any one API domain cannot exceed $50 in a rolling 24 hours.
3
Assign to agent
Go to the agent’s Permissions tab and assign the policy.
You can also add
X402_ALLOWED_SERVICES with a JSON array value such as ["api.example.com", "data.provider.io"]. This is the strongest guardrail: the agent can pay only the API domains you
list.Step 2: Pre-authorize a payment
When your agent receives an HTTP 402, send the payment details toPOST /api/sdk/x402/pre-authorize.
Conto evaluates your x402 policies plus your general spend limits. An approved payment returns a
single-use grantId and grantSignature and reserves the amount for 10 minutes. The agent signs the
payment and retries the API call. A declined payment returns reasons and reasonCodes, and the
agent skips the call. See Pre-authorization.
If Conto returns 503 PAYMENTS_PAUSED, no grant was issued. Stop before signing or retrying the
resource request. Ask the owner to check payment availability, then retry with the same payment
identity after service resumes. LIVE_PAYMENTS_PAUSED and the LIVE_PAYMENT_CAP_* codes are
separate mainnet controls. See error handling.
Step 3: Record the transaction
After the payment settles onchain, record it withPOST /api/sdk/x402/record and include the
grantId and grantSignature from Step 2. See Recording transactions.
Step 4: Monitor spending
Open Machine Spend in the dashboard for spend, calls, and average cost per service and endpoint. Conto also raises anomaly alerts on recorded payments. From the API, use Budget tracking and Querying services.Full integration example
This example uses an external wallet: your agent signs, and Conto checks the payment first and records it after. It follows the x402 wire format:- The API answers
402. x402 v1 puts the payment requirements in the response body. x402 v2 puts them, base64 encoded, in thePAYMENT-REQUIREDheader. - The agent retries with a signed payload in the
X-PAYMENTheader (v1) orPAYMENT-SIGNATUREheader (v2). - The API returns the settlement, including the transaction hash, in the
X-PAYMENT-RESPONSEheader (v1) orPAYMENT-RESPONSEheader (v2).
eip155:8453 for Base. v1 challenges use names like
base, so convert them first.
conto.x402.pay(). Pass the same
fields plus x402Version and paymentRequirements: requirement, then retry the API call with the
returned paymentHeaderName header set to xPaymentHeader. Record the settlement the same way.
Troubleshooting
Budget shows less spend than expected
Budget shows less spend than expected
Conto counts x402 spend only from recorded payments. Record every payment after it settles.
X402_ALLOWED_SERVICES blocks everything
X402_ALLOWED_SERVICES blocks everything
The allowlist is strict. Only listed domains can receive x402 payments. Add the exact domain
(for example
api.example.com, not example.com or www.api.example.com).API reference
Pre-authorization
With the SDK, callconto.x402.preAuthorize() with the same fields.
serviceDomain from resourceUrl, so you do not need to send it. Send the
facilitator, scheme, payment ID, and session ID when available so matching policies evaluate the
actual x402 challenge.
Send payerAddress and network together. Use the exact signing address and the CAIP-2 network
from the selected x402 requirement. This binds policy evaluation to the wallet that will pay. The
binding is required when an agent has more than one active wallet.
Response (Approved):
paymentId returns the same live grant instead of reserving the amount twice.
Response (Denied):
reasons and reasonCodes. Conto does not queue a
review_required payment for a person, so handle it like a decline. x402 decisions use the shared
payment reasons. x402 price, endpoint, service and session
limits return SPENDING_LIMIT. Blocked or unlisted services and facilitators return
RECIPIENT_NOT_ALLOWED.
Recording transactions
With the SDK, callconto.x402.record().
txHash is required. Before recording spend, Conto verifies a successful settlement on the
wallet’s configured chain with the exact sender, recipient, asset, and amount. A pending receipt
returns SETTLEMENT_PENDING. A mismatched transfer returns SETTLEMENT_MISMATCH. An unavailable RPC
returns a temporary service error. Only verified settlements are stored as confirmed.
Repeat the same payerAddress and network used for pre-authorization. Conto resolves the pair to
one active wallet and uses that wallet for settlement verification and spend tracking.
Grants and policy bypass
Send thegrantId and grantSignature from the approved pre-authorization. Conto checks the
onchain transfer against the grant’s recipient and amount, not the values in the record request,
then marks the grant used. The reserved amount becomes actual spend, so it is counted once.
A record without a valid grant means the payment settled without an approval from Conto. Conto
still records it, because the money has already moved, but it flags the transaction for review and
raises a critical alert to the account owner.
bypassReason is GRANT_MISSING,
GRANT_INVALID, or GRANT_EXPIRED. agentFrozen is true when Conto froze the agent for this
bypass. A frozen agent’s API key is rejected until an owner unfreezes the agent from the dashboard.
While that alert is still open, further bypasses by the same agent update it (occurrence count and
recent transactions) instead of sending another email.
The grant is a check, not a signing control. An agent that holds its own signing key can still pay
without asking Conto. Conto detects that when the payment is recorded. To stop the payment before
it is signed, keep the key behind a signer that requires a Conto approval.
Batch recording
To record several calls settled together, send one record with the per-call details inbatchItems:
txHash is the transaction that paid for every
item. The record endpoint does not accept a top-level payments array. The sum of all batchItems
must equal the top-level amount, and the grant must come from a pre-authorization for that same
total.
Use optional context.department and context.project values during pre-authorization and
recording to apply scoped budgets and persist those dimensions on the transaction.
Conto-signed payments (managed wallets)
When the agent’s wallet is a managed EVM wallet, the agent holds no key. Conto approves and signs the payment. Call/api/sdk/x402/pay (conto.x402.pay() in the SDK) instead of pre-authorize, with
the same fields plus the accepted entry from the 402 challenge:
TransferWithAuthorization for exactly the approved payee, amount, USDC contract, and chain:
paymentHeaderName header set to xPaymentHeader, then call
/api/sdk/x402/record with the grant and the settlement txHash as usual. Send "x402Version": 2
for a v2 challenge. Conto then returns a PAYMENT-SIGNATURE header.
Managed signing covers only USDC, the stablecoin that supports EIP-3009. The authorization is valid until
the earlier of the grant expiry and
maxTimeoutSeconds from now. Each grant is signed once, so
pay is not retried automatically. If the payment is never recorded, Conto checks the
authorization nonce onchain after it expires: an unused authorization releases the reserved
amount, and a used one is recorded as a confirmed payment.
If
/api/sdk/x402/pay returns 404, managed signing is off. Use pre-authorize and record
instead. After a wallet’s key is exported, whoever holds the exported key can sign without Conto.Querying services
List the x402 services this agent has paid. Optionalperiod is 24h, 7d (default), 30d, or
90d. Optional limit defaults to 50, max 100. With the SDK, call
conto.x402.services({ period, limit }).
Budget tracking
Check the agent’s spend, limits, and burn rate. With the SDK, callconto.x402.budget({ sessionId }).
sessionId is supplied,
spend.session also reports the call count and amount recorded with that customer-defined ID.