HTTP 402 Payments

Integrate Axon with HTTP 402 Payment Required flows for bot-to-service payments.

HTTP 402 Payments

HTTP 402 is a status code that means "Payment Required." It enables a simple pattern: a service returns a 402 response with payment details, the client pays, and then retries the request to access the resource. Axon has native support for this flow, letting your bots pay for API access, data, and compute on-the-fly.

How It Works

The standard HTTP 402 flow with Axon:

Bot                          Service                      Axon Relayer
 |                              |                              |
 |  GET /api/resource           |                              |
 |----------------------------->|                              |
 |                              |                              |
 |  402 Payment Required        |                              |
 |  { amount, token, to, ref }  |                              |
 |<-----------------------------|                              |
 |                              |                              |
 |  axon.pay({ to, amount, ... })                              |
 |------------------------------------------------------------>|
 |                              |                              |
 |  { status: "approved", txHash }                             |
 |<------------------------------------------------------------|
 |                              |                              |
 |  GET /api/resource           |                              |
 |  X-Payment-TxHash: 0x...     |                              |
 |----------------------------->|                              |
 |                              |                              |
 |  200 OK { data }             |                              |
 |<-----------------------------|                              |

The key constraint: 402 flows must be synchronous. The service is waiting for payment confirmation before releasing the resource. This means the payment must take the fast path through the relayer and return a txHash immediately.

Fast Path Requirement

For a payment to qualify for the fast path (synchronous txHash), it must:

  1. Be below the bot's aiTriggerThreshold so AI verification is not triggered
  2. Not exceed any velocity window that would trigger a scan
  3. Not be from a bot with requireAiVerification: true
  4. Pass all policy checks (per-tx limit, daily limit, destination whitelist)

If a 402 payment triggers AI verification or human review, the service will time out waiting for payment. Pre-whitelist your 402 destinations and keep payment amounts well below AI thresholds.

Pre-Whitelisting 402 Destinations

To guarantee that 402 payments stay on the fast path, pre-whitelist the service addresses your bots will pay. Whitelisted destinations skip additional scrutiny.

Via Dashboard

Go to Vaults > [Your Vault] > Policies > Destination Whitelist and add the service's payment address. You can add addresses at the vault level (applies to all bots) or per-bot.

Via SDK

Whitelisting destinations is an on-chain transaction. Use the dashboard or call the vault contract directly:

import { AxonVaultAbi } from '@axonfi/sdk';
 
await walletClient.writeContract({
  address: '0xYourVaultAddress',
  abi: AxonVaultAbi,
  functionName: 'addGlobalDestination',
  args: ['0xServicePaymentAddress'],
});

Only the vault owner can add whitelisted destinations. The operator can remove destinations (tightening security) but cannot add new ones (loosening security).

Bot-Side Integration

Here is a complete example of a bot that handles 402 responses:

import { AxonClient, decryptKeystore, Chain, encodeRef } from '@axonfi/sdk';
import fs from 'fs';
 
// Decrypt bot key from encrypted keystore file
const keystore = fs.readFileSync(process.env.AXON_BOT_KEYSTORE_PATH!, 'utf8');
const botPrivateKey = await decryptKeystore(keystore, process.env.AXON_BOT_PASSPHRASE!);
 
const axon = new AxonClient({
  botPrivateKey,
  vaultAddress: process.env.AXON_VAULT_ADDRESS as `0x${string}`,
  chainId: Chain.Base,
});
 
async function fetchWithPayment(url: string): Promise<any> {
  // First attempt — may get a 402
  const response = await fetch(url);
 
  if (response.status !== 402) {
    return response.json();
  }
 
  // Parse 402 payment details from the response
  const paymentDetails = await response.json();
  // Expected shape: { amount, token, to, ref, chainId }
 
  // Pay via Axon
  const result = await axon.pay({
    to: paymentDetails.to,
    token: paymentDetails.token,
    amount: BigInt(paymentDetails.amount),
    ref: encodeRef(paymentDetails.ref),
    memo: `HTTP 402 payment for ${url}`,
    resourceUrl: url,
  });
 
  if (result.status !== 'approved' || !result.txHash) {
    throw new Error(
      `Payment did not complete synchronously. Status: ${result.status}. ` +
        `Ensure the destination is whitelisted and the amount is below AI thresholds.`,
    );
  }
 
  // Retry the request with proof of payment
  const retryResponse = await fetch(url, {
    headers: {
      'X-Payment-TxHash': result.txHash,
      'X-Payment-Chain': '8453',
    },
  });
 
  return retryResponse.json();
}
 
// Usage
const data = await fetchWithPayment('https://api.example.com/v1/data');

The resourceUrl Field

When submitting a 402 payment, include the resourceUrl field in your payment request. This is the URL of the resource being unlocked by the payment. It is not signed on-chain but is stored by the relayer and surfaced in the dashboard audit trail.

const result = await axon.pay({
  to: '0xServiceAddress',
  token: 'USDC',
  amount: 0.50,
  ref: encodeRef('api-call-1337'),
  resourceUrl: 'https://api.example.com/v1/premium-data',
});

This helps owners understand what their bots are paying for when reviewing transaction history.

For bots that primarily make HTTP 402 payments (frequent, small amounts, synchronous), use these settings:

SettingRecommended valueReason
maxPerTxAmountLow (e.g., $10)402 payments are typically micro-transactions
spendingLimitsModerate (e.g., $500/day)Bounds total daily API spend
aiTriggerThresholdHigher than maxPerTxAmountEnsures 402 payments never trigger AI scan
requireAiVerificationfalseAI scan adds latency incompatible with 402
Destination whitelistPre-populatedOnly allow known 402 service addresses

Bot configuration is done through the Axon dashboard or via direct on-chain contract calls. See the Register a Bot guide for details on setting spending limits and AI thresholds programmatically.

Constraints and Limitations

  • Synchronous only. 402 payments that enter the AI scan or human review path will fail from the service's perspective because no txHash is returned immediately.
  • Same-chain only (v1). The service's payment address must be on the same chain as the bot's vault.
  • Swap latency. If the payment requires a token swap (e.g., vault holds USDC but service requests USDT), the swap adds latency. For critical 402 flows, ensure the vault holds the expected token or accept the additional seconds.

Next Steps