Skip to content

tx402

Turn a 402 challenge into a paid response in three lines — with spend caps enforced before any key is touched.

tx402 wraps a normal HTTP client. When a server answers 402 Payment Required, tx402 interprets the challenge, checks it against your spend policy, picks a payment route across the chains the merchant offered, signs one authorization, and retries the request. You get the response body. Roughly a hundred lines of fragile glue code become three.

It is non-custodial and buyer-side only. tx402 never holds funds, never calls a facilitator’s /verify or /settle — settlement is the merchant’s job — and never accepts a raw private key in its main configuration.

Guardrails before keys

Policy evaluation and an atomic budget reservation both complete before a signer is ever invoked. A refused request costs zero signatures, and a dry run costs zero of both.

Deterministic routing

Offered several chains? The same challenge and the same health state select the same route every time — viability, then your preference, then fee, then health.

Integer money, always

Every amount is an integer in atomic units, end to end. No float, no Number, no rounding surprise between the quote and the signature.

It tells you when it cannot tell

If a signature reached the merchant and the outcome is unknown, you get a distinct error and the budget stays reserved — so the same money is never spent twice by accident.

Terminal window
# TypeScript / Node 20+
npm install tx402 # core + CLI, no chain
npm install tx402 @x402/evm viem # + Base / EVM
# Python 3.10+
pip install tx402 # core + CLI, no chain
pip install "tx402[evm]" # + Base / EVM

Both packages are unscoped and named tx402. Chain support is opt-in: the core import path loads no chain library in either language. Add the chain row for anything that reaches a chain — the quickstart lists Solana’s too.

TypeScript
import { createTx402Client } from "tx402";
const tx402 = createTx402Client({
signers: { evm },
policy: { maxPerRequest: "0.10 USDC", maxPerHour: "5.00 USDC" },
});
const response = await tx402.fetch("https://api.example.com/paid-resource");
Python
from tx402 import Policy, Tx402Client
with Tx402Client(
evm_signer=evm,
policy=Policy(max_per_request="0.10 USDC", max_per_hour="5.00 USDC"),
) as tx402:
response = tx402.get("https://api.example.com/paid-resource")

Or without writing any code at all:

Terminal window
npx tx402 call https://api.example.com/paid-resource --max-spend "0.10 USDC" --dry-run

--dry-run does everything a real call does except reserve budget and sign. It is the fastest way to find out what a merchant is asking for and what tx402 would do about it.

It is not, however, free of setup: planning ranks the offered routes by reading your balance on each, so --dry-run needs a chain row installed and a key configured, and says so with exit 5 if either is missing. The question that needs neither is client.inspect(), which returns the merchant’s terms without touching a chain.

  • Quickstart — a real paid call on a testnet, in under five minutes.
  • The request lifecycle — what happens between your call and the response.
  • Spend policy — the guardrails, and the order they run in.
  • Error reference — all seventeen errors and the nine exit codes.
  • Security model — the threat model, and what tx402 does and does not defend.
  • Hosted tools — free browser tools for inspecting, verifying and debugging x402 endpoints, built on this SDK.