Back to Academy
Level 315 min

Custom Agent Integration

Build x402 support into any agent framework. Raw HTTP, full control, no dependencies.

1

Implement the 402 handler

The core pattern: try the call, handle 402, sign USDC, retry. Works with any HTTP client.

TypeScript
async function x402Fetch(url: string, init?: RequestInit) {
  const res = await fetch(url, init);

  if (res.status !== 402) return res;

  // Parse payment requirements from response
  const requirements = await res.json();
  const { price, recipient, network } = requirements;

  // Sign EIP-712 USDC payment
  const payment = await wallet.signTypedData({
    domain: usdcDomain,
    types: paymentTypes,
    message: { recipient, amount: price, nonce: randomNonce() }
  });

  // Retry with payment header
  return fetch(url, {
    ...init,
    headers: { ...init?.headers, "X-PAYMENT": btoa(JSON.stringify(payment)) }
  });
}
2

Add session support

For frequent calls, buy a session pass. One payment unlocks unlimited calls within the time window.

TypeScript
async function getSessionToken(slug: string) {
  const res = await x402Fetch(`/api/v1/proxy/${slug}`, {
    headers: { "X-SESSION-REQUEST": "true" }
  });
  const { sessionToken } = await res.json();
  return sessionToken; // JWT, reuse for all subsequent calls
}

// Use session token (no payment needed)
const res = await fetch(`/api/v1/proxy/${slug}`, {
  headers: { "X-SESSION-TOKEN": sessionToken }
});
3

Implement error handling

Handle the common failure modes: insufficient balance, expired signatures, seller downtime.

TypeScript
async function safeCall(slug: string, body: unknown) {
  try {
    const res = await x402Fetch(`/api/v1/proxy/${slug}`, {
      method: "POST",
      body: JSON.stringify(body)
    });

    if (!res.ok) {
      const error = await res.json();
      if (error.code === "INSUFFICIENT_BALANCE") { /* top up */ }
      if (error.code === "SELLER_DOWN") { /* try alternative */ }
      throw new Error(error.message);
    }

    return res.json();
  } catch (err) {
    // Network error, timeout, etc.
    console.error("x402 call failed:", err);
    throw err;
  }
}