How to Build an AI Agent That Can Pay for Its Own APIs

AI agents can write code and manage infrastructure, but most still need a human to set up billing. This tutorial shows how to build an agent that discovers, pays for, and consumes APIs autonomously — using x402 micropayments and hardware-secured wallets.

Alex Daro
Alex Daro
How to Build an AI Agent That Can Pay for Its Own APIs

Every AI agent framework — LangChain, CrewAI, AutoGPT, Claude MCP — eventually hits the same wall: the agent needs to call an external API, and someone has to set up the credentials first.

That "someone" is a human. They create accounts, generate API keys, configure billing, set spending limits, and inject secrets into the agent's environment. For every service the agent needs.

This is the bottleneck nobody talks about. Your agent can orchestrate a dozen services, but it can't sign up for a single one.

This tutorial shows how to build an agent that handles payments autonomously — no pre-provisioned API keys, no human-managed billing, no accounts at all. The agent discovers services, pays per request in stablecoins, and the private key that signs those payments never leaves a hardware-isolated enclave.

What You'll Build

By the end of this tutorial, you'll have:

  1. A hardware-secured wallet running inside a Nitro Enclave
  2. A fetch wrapper that automatically pays for 402 Payment Required responses
  3. A service discovery function that finds payable APIs programmatically
  4. A complete agent loop that discovers, verifies, pays for, and consumes services without human intervention

Prerequisites

Step 1: Create an Enclave Wallet

Traditional agent setups store private keys in environment variables or config files. If the host is compromised, the keys are exposed. We're going to do something different: generate and store the key inside a Trusted Execution Environment.

npm install @treza/sdk @x402/core @x402/evm @x402/fetch
import { TrezaClient, createEnclaveFetch } from '@treza/sdk';
 
const treza = new TrezaClient({
  baseUrl: 'https://app.trezalabs.com',
});
 
const enclave = await treza.createEnclave({
  name: 'agent-wallet',
  region: 'us-east-1',
  walletAddress: '0xYourWallet...',
  providerId: 'aws-nitro',
  providerConfig: {
    dockerImage: 'treza/agent-wallet:latest',
    cpuCount: 2,
    memoryMiB: 512,
  },
});
 
console.log('Enclave deployed:', enclave.id);

The enclave generates a private key at boot time. That key exists only inside the hardware-isolated boundary — the host OS, the hypervisor, and even Treza's own infrastructure cannot read it.

Before the agent trusts this wallet, it should verify the enclave's integrity:

const verification = await treza.verifyAttestation(enclave.id, {
  nonce: 'setup-' + Date.now(),
});
 
if (!verification.isValid || verification.trustLevel !== 'HIGH') {
  throw new Error('Enclave attestation failed — aborting');
}
 
console.log('Enclave verified. Trust level:', verification.trustLevel);

This checks the Platform Configuration Registers (PCRs) — cryptographic hashes of the enclave image, kernel, and application code — against known-good values. If anything has been tampered with, the attestation fails and the agent refuses to proceed.

Step 2: Create an Auto-Paying Fetch

The x402 protocol adds a payment layer to HTTP. When a server responds with 402 Payment Required, the response body contains everything the client needs: price, currency, network, and recipient address.

We wrap the standard fetch function so the agent handles this automatically:

const paidFetch = await createEnclaveFetch(treza, {
  enclaveId: enclave.id,
  verifyAttestation: true,
});

That's it. paidFetch works exactly like fetch, but when it receives a 402 response, it:

  1. Reads the payment requirements from the response
  2. Signs a USDC payment inside the enclave (key never leaves the TEE)
  3. Retries the request with a Payment-Signature header
  4. Returns the successful response

The agent doesn't need to know the price in advance. It reads the 402 and pays what the service charges.

Step 3: Discover Payable Services

An autonomous agent shouldn't have a hardcoded list of APIs. The x402 Bazaar is a registry where services advertise their payable endpoints — price, description, and capabilities. The agent can query it at runtime.

import { discoverPayableServices } from '@treza/sdk';
 
const services = await discoverPayableServices({
  maxPrice: '0.01',
  network: 'eip155:8453',
});
 
for (const service of services) {
  console.log(`${service.description}: ${service.url} ($${service.accepts[0].price})`);
}

This returns a list of services the agent can afford and access right now. No sign-ups, no onboarding flows — just a URL and a price.

Step 4: Build the Agent Loop

Now we wire everything together into a complete autonomous agent:

import { TrezaClient, createEnclaveFetch, discoverPayableServices } from '@treza/sdk';
 
async function runAgent() {
  const treza = new TrezaClient({
    baseUrl: 'https://app.trezalabs.com',
  });
 
  // 1. Create auto-paying fetch with enclave wallet
  const paidFetch = await createEnclaveFetch(treza, {
    enclaveId: 'enc_abc123',
    verifyAttestation: true,
  });
 
  // 2. Discover available services
  const services = await discoverPayableServices({
    maxPrice: '0.05',
    network: 'eip155:8453',
  });
 
  const attestationService = services.find(s =>
    s.description.toLowerCase().includes('attestation')
  );
 
  if (!attestationService) {
    console.log('No attestation services found within budget');
    return;
  }
 
  // 3. Call the service — payment handled automatically
  const response = await paidFetch(attestationService.url);
  const data = await response.json();
 
  console.log('Service response:', data);
  console.log('Payment settled on Base L2');
}
 
runAgent();

The agent discovers services, pays for them, and consumes the response. The private key that signs payments is protected by hardware isolation. The payment settles in USDC on Base. No human touched anything after the initial deployment.

The Security Model

This architecture combines three layers of protection:

LayerWhat it protectsHow
TEE isolationPrivate keyKey is generated and used inside the Nitro Enclave — never exposed to the host, hypervisor, or operator
AttestationCode integrityCryptographic proof that the enclave image, kernel, and application haven't been tampered with
x402 protocolPayment authorizationEach payment is bound to a specific request — replay attacks and double-spending are prevented by the facilitator

Compare this to the standard approach of storing a private key in an environment variable on a cloud VM. The key is accessible to anyone with SSH access, any process running on the host, and potentially the cloud provider itself. With a TEE-backed wallet, even a fully compromised host can't extract the key.

Scaling: Multiple Agents, One Pattern

This pattern extends naturally to fleets of agents. Each agent gets its own enclave wallet, its own budget (funded with USDC), and its own attestation. A orchestrator can:

  • Deploy new agent enclaves on demand
  • Fund each with a specific USDC budget
  • Monitor spending through on-chain transaction history
  • Verify enclave integrity before authorizing high-value operations
  • Terminate enclaves when agents complete their task
const enclave = await treza.createEnclave({
  name: `agent-${taskId}`,
  region: 'us-east-1',
  walletAddress: orchestratorAddress,
  providerId: 'aws-nitro',
  providerConfig: {
    dockerImage: 'myorg/research-agent:latest',
    cpuCount: 2,
    memoryMiB: 1024,
  },
});
 
// Fund the agent's enclave wallet
// (send USDC to the enclave's signing address on Base)
 
// Agent runs autonomously, paying for APIs as needed
 
// When done, terminate
await treza.terminateEnclave(enclave.id, orchestratorAddress);

Every USDC payment is an on-chain transaction. You get a complete, immutable audit trail of every API call every agent made and how much it paid — without building any logging infrastructure.

Testing on Testnet

All of this works on Base Sepolia (testnet) before you spend real money:

  1. Get testnet USDC from Circle's faucet
  2. Fund your enclave's signing address on Base Sepolia
  3. Set the network to eip155:84532 in your configuration
const services = await discoverPayableServices({
  maxPrice: '0.01',
  network: 'eip155:84532', // Base Sepolia
});

Testnet payments go through the same flow — 402 response, signed payment, facilitator verification — but settle on Base Sepolia instead of mainnet.

Why This Matters for Agent Builders

The current model of agent-to-API integration doesn't scale. Every new service an agent needs requires a human to provision credentials. As agents become more capable and compositions become more complex — agents calling agents calling APIs — the credential management burden grows exponentially.

x402 flips this model. Services advertise their price. Agents pay per request. Settlement happens on-chain. The agent's wallet is secured by hardware. No accounts, no API keys, no billing portals, no rate limit negotiations.

This is what permissionless agent commerce looks like.

Next Steps


Treza builds privacy infrastructure for crypto and finance. Deploy workloads in hardware-secured enclaves with cryptographic proof of integrity. Learn more.

Ready to get started?

Get in touch to learn how Treza can help your team build privacy-first applications.