Skip to main content

Paying for APIs with x402

When your AI agent calls a paid API, the API returns HTTP 402 Payment Required with a payment challenge. The x402 protocol standardizes this flow — and Conto sits in the middle to enforce policies before the agent pays. This guide walks through the complete cycle: receive a 402, check it with Conto, pay, and track spending.

Prerequisites

How x402 Works

Agent calls API  →  HTTP 402  →  Conto pre-authorizes  →  Agent pays & retries  →  Conto records
StepWhoWhat happens
1AgentCalls an x402-enabled API
2APIReturns 402 Payment Required with amount, recipient, facilitator
3AgentSends payment details to Conto for policy check
4ContoEvaluates x402 policies — returns authorized or denied
5AgentIf authorized, signs payment and retries the API call
6AgentRecords the completed transaction in Conto for tracking
Conto never touches the x402 payment itself — it acts as the policy and tracking layer. Your agent (or wallet provider like Sponge) handles the actual signing and payment.

Step 1: Set Up x402 Policies

Before your agent starts paying for APIs, set guardrails. Without x402-specific policies, only your general spend limits apply.
1

Create the policy

Go to PoliciesNew Policy.
FieldValue
Namex402 API Guardrails
Policy TypeX402_CONTROLS
2

Add rules

Add these rules to cap per-request cost and total per-service spend:Rule 1: Cap per API call
FieldValue
Rule TypeX402_MAX_PER_REQUEST
OperatorLTE
Value0.50
ActionALLOW
No single x402 payment can exceed $0.50.Rule 2: Budget per service
FieldValue
Rule TypeX402_MAX_PER_SERVICE
OperatorLTE
Value50
ActionALLOW
Total spend per API service domain cannot exceed $50.
3

Assign to agent

Go to the agent’s Permissions tab and assign the policy.
You can also add X402_ALLOWED_SERVICES to restrict which API domains your agent can pay. This is the strongest guardrail — the agent can only pay APIs you’ve explicitly approved.

Step 2: Pre-Authorize a Payment

When your agent receives an HTTP 402, extract the payment details and check them against Conto:
curl -X POST https://conto.finance/api/sdk/x402/pre-authorize \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 0.05,
    "recipientAddress": "0xFacilitatorAddress",
    "resourceUrl": "https://api.example.com/data",
    "serviceDomain": "api.example.com",
    "facilitator": "0xFacilitatorAddress",
    "scheme": "exact"
  }'

If Authorized

{
  "authorized": true,
  "wallet": {
    "id": "wal_123",
    "address": "0xAgentWallet",
    "chainId": "8453",
    "availableBalance": 500.00
  },
  "reasons": ["Within x402 service budget", "Service domain allowed"]
}
The agent proceeds to sign the payment and retry the API call.

If Denied

{
  "authorized": false,
  "reasons": ["X402 price ceiling exceeded: $0.05 > $0.01 max"],
  "violations": [
    {
      "type": "X402_PRICE_CEILING",
      "limit": 0.01,
      "current": 0.05,
      "message": "Amount exceeds x402 price ceiling"
    }
  ]
}
The agent should log the denial and either skip the API call or escalate.

Step 3: Record the Transaction

After the x402 payment executes on-chain, record it in Conto so it counts toward budgets and shows up in analytics:
curl -X POST https://conto.finance/api/sdk/x402/record \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 0.05,
    "recipientAddress": "0xFacilitatorAddress",
    "transactionHash": "0xabc123...",
    "resourceUrl": "https://api.example.com/data",
    "serviceDomain": "api.example.com",
    "facilitator": "0xFacilitatorAddress",
    "scheme": "exact",
    "walletId": "wal_123",
    "chainId": "8453"
  }'
If you skip recording, Conto can’t track budget consumption. Your per-service limits won’t enforce correctly because Conto doesn’t know the payment happened.

Batch Recording

For high-frequency API calls, batch multiple records in one request:
curl -X POST https://conto.finance/api/sdk/x402/record \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "batch": [
      {
        "amount": 0.01,
        "recipientAddress": "0xFacilitator",
        "transactionHash": "0x1...",
        "resourceUrl": "https://api.example.com/v1/data",
        "serviceDomain": "api.example.com"
      },
      {
        "amount": 0.02,
        "recipientAddress": "0xFacilitator",
        "transactionHash": "0x2...",
        "resourceUrl": "https://api.example.com/v1/search",
        "serviceDomain": "api.example.com"
      }
    ]
  }'

Step 4: Monitor Spending

Check Budget

See how much your agent has spent and what’s remaining:
curl https://conto.finance/api/sdk/x402/budget \
  -H "Authorization: Bearer $CONTO_API_KEY"

View Services Used

List all x402 API services your agent has interacted with:
curl https://conto.finance/api/sdk/x402/services \
  -H "Authorization: Bearer $CONTO_API_KEY"

Dashboard

Go to Analytics in the dashboard to see:
  • x402 spend trends over time
  • Per-service cost breakdown
  • Request frequency and average cost per call

Full Integration Example

Here’s how an agent handles the complete x402 flow in TypeScript:
import { Conto } from '@conto/sdk';

const conto = new Conto({ apiKey: process.env.CONTO_API_KEY });

async function callPaidApi(url: string) {
  // Step 1: Call the API
  const response = await fetch(url);

  if (response.status !== 402) {
    return response.json(); // No payment needed
  }

  // Step 2: Parse the 402 payment challenge
  const paymentHeader = response.headers.get('X-Payment');
  const { amount, recipient, facilitator } = JSON.parse(paymentHeader);
  const serviceDomain = new URL(url).hostname;

  // Step 3: Pre-authorize through Conto
  const auth = await conto.x402.preAuthorize({
    amount,
    recipientAddress: recipient,
    resourceUrl: url,
    serviceDomain,
    facilitator,
    scheme: 'exact',
  });

  if (!auth.authorized) {
    console.error('Policy denied x402 payment:', auth.reasons);
    throw new Error(`x402 denied: ${auth.reasons.join(', ')}`);
  }

  // Step 4: Sign and pay (via your wallet provider)
  const { txHash } = await walletProvider.signX402Payment({
    amount,
    recipient,
    facilitator,
  });

  // Step 5: Retry the API call with payment proof
  const paidResponse = await fetch(url, {
    headers: { 'X-Payment-Signature': txHash },
  });

  // Step 6: Record in Conto
  await conto.x402.record({
    amount,
    recipientAddress: recipient,
    transactionHash: txHash,
    resourceUrl: url,
    serviceDomain,
    facilitator,
    scheme: 'exact',
    walletId: auth.wallet.id,
    chainId: auth.wallet.chainId,
  });

  return paidResponse.json();
}

x402 Policy Reference

All available x402-specific policy rules:
Rule TypeWhat It Controls
X402_MAX_PER_REQUESTMax amount per single API call
X402_PRICE_CEILINGHard ceiling on any x402 payment
X402_MAX_PER_ENDPOINTBudget per specific API endpoint
X402_MAX_PER_SERVICEBudget per service domain
X402_ALLOWED_SERVICESAllowlist of API domains
X402_BLOCKED_SERVICESBlocklist of API domains
X402_ALLOWED_FACILITATORSAllowed facilitator addresses
X402_VELOCITY_PER_ENDPOINTRate limit per endpoint
X402_SESSION_BUDGETSession-level spending cap
See Advanced Policies for value formats and operators.

Anomaly Detection

Conto automatically monitors x402 patterns and creates alerts for:
AlertTrigger
Price SpikeAPI suddenly charging more than usual
High FrequencyUnusual burst of API calls
New ServiceAgent paying an API for the first time
Budget BurnApproaching per-service budget limit
Duplicate PaymentSame amount + endpoint in quick succession
Failed StreakRepeated authorization failures
Configure alert thresholds in Alerts in the dashboard.

Troubleshooting

Your general spend limits still apply to x402 payments. If the x402 amount plus today’s spend exceeds your daily limit, it’s denied. Check your wallet-level and agent-level spend limits.
Ensure you’re recording transactions after they execute. If you skip the record step, Conto can’t decrement the budget correctly. Also check if batch records are being sent for high-frequency calls.
The allowlist is strict — only listed domains can receive x402 payments. Make sure you’ve added the exact domain (e.g., api.example.com, not example.com or www.api.example.com).
Pre-authorization is a policy check, not an on-chain operation. If it’s slow, it’s likely network latency to the Conto API. Consider caching authorization results for repeated calls to the same endpoint within a short window.

Next Steps

MPP Sessions

Session-based micropayments for streaming APIs

x402 SDK Reference

Full API reference for x402 endpoints

Advanced Policies

All x402 policy rule types and value formats

Recipes

Copy-paste x402 recipes