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. Conto sits in the middle to enforce policies before the agent pays. This guide is a walkthrough. For the endpoint reference (request/response shapes, scopes, error codes), see SDK > x402 payments.

Prerequisites

An active agent with an SDK key (Quickstart)
A funded wallet (Base USDC or Tempo USDC.e for production, or Tempo Testnet pathUSD for testing)
An x402-enabled API to call (or use the examples below to simulate)

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 TypeCOMPOSITE
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
Value{"maxAmount": 50, "period": "DAILY"}
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 with a JSON array value such as ["api.example.com", "data.provider.io"] 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 (amount, recipient, facilitator) and check them against Conto with POST /api/sdk/x402/pre-authorize. Conto evaluates your x402 policies plus your general spend limits and responds one of two ways:
  • Authorized: the response includes the wallet to pay from. The agent signs the payment and retries the API call.
  • Denied: the response lists the violated rules. The agent should log the denial and either skip the API call or escalate.
See Pre-Authorization in the SDK reference for the full request and response shapes.

Step 3: Record the Transaction

After the x402 payment executes onchain, record it with POST /api/sdk/x402/record so it counts toward budgets and shows up in analytics. For high-frequency API calls, batch multiple records in one request. See Recording Transactions and Batch Recording for the request shapes.
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.

Step 4: Monitor Spending

Check how much your agent has spent and what’s remaining with GET /api/sdk/x402/budget, and list the x402 API services it has interacted with via GET /api/sdk/x402/services. See Budget Tracking and Querying Services for details, including session-scoped budget views.

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: The TypeScript SDK currently exposes standard payment helpers. For x402 flows, call the SDK REST endpoints directly:
const CONTO_API_BASE = 'https://conto.finance';
const contoApiKey = process.env.CONTO_API_KEY;

type PreAuthorizeResponse = {
  authorized: boolean;
  reasons: string[];
  wallet?: { id: string; chainId: string; address: string };
};

async function postConto<T>(path: string, body: unknown): Promise<T> {
  if (!contoApiKey) {
    throw new Error('CONTO_API_KEY is required');
  }

  const response = await fetch(`${CONTO_API_BASE}${path}`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${contoApiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });

  if (!response.ok) {
    throw new Error(`Conto ${path} failed: ${await response.text()}`);
  }

  return response.json() as Promise<T>;
}

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');
  if (!paymentHeader) {
    throw new Error('Missing X-Payment header');
  }

  const { amount, recipient, facilitator, paymentId } = JSON.parse(paymentHeader) as {
    amount: number;
    recipient: string;
    facilitator?: string;
    paymentId?: string;
  };

  // Step 3: Pre-authorize through Conto
  const auth = await postConto<PreAuthorizeResponse>('/api/sdk/x402/pre-authorize', {
    amount,
    recipientAddress: recipient,
    resourceUrl: url,
    facilitator,
    scheme: 'exact',
    paymentId,
  });

  if (!auth.authorized || !auth.wallet) {
    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 postConto('/api/sdk/x402/record', {
    amount,
    recipientAddress: recipient,
    txHash,
    resourceUrl: url,
    facilitator,
    scheme: 'exact',
    paymentId,
    walletId: auth.wallet.id,
    chainId: auth.wallet.chainId,
  });

  return paidResponse.json();
}

x402 Policy Reference

The complete list of x402 rule types, value formats, and operators lives in Advanced Policies > x402 Protocol Rules.

Anomaly Detection

Conto automatically monitors x402 patterns and creates alerts for price spikes, high-frequency bursts, new services, budget burn, duplicate payments, and failed streaks. See Anomaly Detection in the SDK reference for what triggers each alert and where to configure thresholds.

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 onchain 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