Come un agente AI paga una ricerca web a chiamata con x402

Niente account, niente chiave API: la vera challenge 402 che restituisce FastAF, il client Node che la paga in USDC su Base e come limitare quanto l'agente può spendere per chiamata.

A un agente che deve fare una ricerca su Google non dovrebbero servire un modulo di registrazione, una chiave API in un secrets manager e un saldo prepagato. Con x402 manda la richiesta, riceve un prezzo, lo paga dal proprio wallet e ottiene i dati. Ecco l’intero giro su FastAF, con la challenge vera e il codice client vero.

Cos’è x402?

x402 recupera lo status HTTP 402 Payment Required, rimasto inutilizzato nella specifica per decenni. Il server risponde a una richiesta non pagata con un 402 e un prezzo leggibile da una macchina; il client paga e ripete la stessa richiesta. Nella versione 2 del protocollo tutto questo viaggia in tre header, ognuno con un JSON codificato in base64: PAYMENT-REQUIRED (dal server al client, il prezzo), PAYMENT-SIGNATURE (dal client al server, il pagamento firmato) e PAYMENT-RESPONSE (dal server al client, l’esito del regolamento), come descritto su docs.x402.org, verificato il 19 ottobre 2026.

Il pagamento in sé è un trasferimento di stablecoin, in pratica USDC su Base. Il client firma un’autorizzazione; un facilitator la confronta con i requisiti del server e la invia on chain. La documentazione del facilitator è esplicita: il facilitator “does not hold funds or act as a custodian”, cioè non detiene fondi e non fa da custode. Il protocollo è nato in incubazione presso Coinbase ed è stato conferito alla x402 Foundation sotto la Linux Foundation, con un annuncio del 2 aprile 2026, con licenza Apache-2.0.

Com’è fatta la challenge 402?

Ogni endpoint FastAF è disponibile sotto https://api.fastaf.co/x402/v1/{endpoint} con gli stessi parametri dell’API con chiave. La prima richiesta non costa nulla:

curl -i "https://api.fastaf.co/x402/v1/serp?query=x402+payment+protocol"

Il 19 ottobre 2026 la risposta è stata HTTP/2 402 in 0,24 secondi. Decodificando l’header payment-required si ottiene (accorciato):

{
  "x402Version": 2,
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "5000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x05B75e13f071A09A26B50a18Ce5BD02a0755d76F",
    "maxTimeoutSeconds": 300,
    "extra": { "name": "USD Coin", "version": "2" }
  }]
}

Campo per campo:

  • scheme: "exact": si paga esattamente questo importo, non di più.
  • network: "eip155:8453": la mainnet di Base, in notazione CAIP-2.
  • amount: "5000": unità atomiche. USDC ha 6 decimali, quindi 5000 sono $0,005, il prezzo di una ricerca.
  • asset: il contratto USDC su Base. La tabella degli asset predefiniti dell’SDK riporta lo stesso indirizzo come USDC.
  • payTo: l’indirizzo che riceve il pagamento.
  • maxTimeoutSeconds: 300: l’autorizzazione firmata vale cinque minuti.
  • extra.name ed extra.version: il dominio EIP-712 del token, che serve al client per firmare un’autorizzazione di trasferimento valida.

Un dettaglio che vale la pena conoscere: i parametri vengono validati prima di qualsiasi preventivo. Lo stesso URL senza q ha restituito 400 invalid_parameters, non un 402, quindi a un agente non viene mai chiesto di pagare per una richiesta malformata.

Come la paga l’agente in Node?

Parsing, firma e nuovo tentativo li fanno i pacchetti ufficiali. Le versioni qui sotto sono quelle attuali su npm (@x402/fetch 2.28.0, con @x402/core e @x402/evm alla stessa versione):

import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const client = new x402Client();
registerExactEvmScheme(client, {
  signer: privateKeyToAccount(process.env.AGENT_WALLET_KEY),
  networks: ["eip155:8453"],
});

// Rifiuta qualsiasi singolo pagamento sopra un centesimo.
client.setSpendControls({ maxAmountPerPayment: "$0.01" });

// Smette di pagare quando questa esecuzione ha speso $0,05 (unità atomiche USDC).
let spent = 0n;
client.onBeforePaymentCreation(async ({ selectedRequirements }) => {
  const amount = BigInt(selectedRequirements.amount);
  if (spent + amount > 50_000n) return { abort: true, reason: "run budget exhausted" };
  spent += amount;
});

const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPayment("https://api.fastaf.co/x402/v1/serp?query=x402+payment+protocol");
console.log(res.status, res.headers.get("X-FastAF-Credits-Used"));

Senza setSpendControls, @x402/core limita già ogni pagamento a DEFAULT_MAX_AMOUNT_PER_PAYMENT, che nel sorgente installato vale "$1". Per un’API di ricerca è fin troppo generoso: impostalo a quanto costa la tua chiamata più cara.

Abbiamo eseguito questo script il 19 ottobre 2026 con un wallet appena generato e senza USDC, quindi nessuna chiamata a pagamento è andata in porto: la risposta 200 con la ricevuta PAYMENT-RESPONSE è quello che l’SDK fa con un wallet finanziato. Ecco cosa è successo davvero: con il limite a $0.002 l’SDK ha rifiutato in locale in 91 ms, prima di firmare qualsiasi cosa (“rejected by spendControls.maxAmountPerPayment”). Con il limite a $0.01 ha fatto il parsing del 402, ha firmato, ha riprovato, e il server ha risposto di nuovo 402 con invalid_exact_evm_insufficient_balance. Nessuna ricerca è partita e nulla è stato regolato.

Perché per gli agenti conta il “regolato solo se va a buon fine”?

Gli agenti sbagliano parecchie chiamate: una query sbagliata, una pagina che va in timeout, un target non consentito. Su FastAF il pagamento firmato viene regolato solo dopo che la richiesta a monte è andata a buon fine. Se la chiamata fallisce, l’autorizzazione non viene mai inviata e scade dopo maxTimeoutSeconds, quindi i soldi restano nel wallet. L’API con chiave segue la stessa regola: le richieste fallite non vengono mai addebitate.

I prezzi sono il costo in crediti dell’API con chiave, a $0,001 per credito. Questi importi sono stati letti da challenge live il 19 ottobre 2026:

Richiesta Crediti Importo x402 Prezzo
/scrape, pagina statica 1 1000 $0,001
/serp, ricerca Google 5 5000 $0,005
/shopping 10 10000 $0,01
Profilo /linkedin 60 60000 $0,06

Quando conviene di più usare crediti prepagati?

x402 è la scelta giusta per un agente che fa chiamate occasionali, gira in un posto dove non puoi fornirgli una chiave, o deve pagare con un budget suo. I crediti prepagati vincono in tre casi:

  • Volumi. Un pacchetto Starter da $10 vale 20.000 crediti, quindi 1.000 ricerche costano $2,50 invece dei $5,00 via x402, e $1,50 con il pacchetto Pro. I crediti restano validi 12 mesi, senza abbonamento.
  • MCP. Il server MCP ospitato su https://api.fastaf.co/mcp si autentica con una chiave Bearer; non accetta pagamenti x402.
  • Un tetto rigido sull’account. Un saldo esaurito restituisce 402 insufficient_credits e si ferma, qualunque cosa decida l’agente. L’articolo sul tetto di spesa spiega come affiancarlo a un budget per singola esecuzione.

Come si tiene al sicuro il wallet dell’agente?

La chiave privata sta nell’ambiente dell’agente e firma senza chiedere a nessuno, quindi trattala come un hot wallet:

  • Usa un wallet dedicato per ogni agente, mai uno che contiene altro.
  • Caricalo con piccole somme e ricaricalo di proposito: il saldo è il tuo caso peggiore.
  • Imposta maxAmountPerPayment al prezzo della tua chiamata più cara, più un budget per esecuzione nell’hook.
  • Fissa networks su eip155:8453, così il client non paga mai su una chain che non avevi previsto.

La versione breve

x402 trasforma una risposta 402 in un cartellino del prezzo: decodifichi PAYMENT-REQUIRED, firmi l’autorizzazione in USDC, riprovi con PAYMENT-SIGNATURE. Su FastAF una ricerca costa $0,005, viene regolata solo se va a buon fine, e gli spend control dell’SDK limitano ogni pagamento prima che venga firmato qualsiasi cosa. Il flusso completo è nella sezione x402 e ogni prezzo è nella pagina dei prezzi. Per i volumi o per l’MCP, crea un account gratuito e parti con 500 crediti, senza carta.