<!--
Sitemap:
- [Newton Agent NeoBank](/index)
- [Getting Started](/getting-started)
- [Onboard an Agent](/guides/onboard-an-agent)
- [Give an Agent a Budget](/guides/agent-budget)
- [Pay for an API](/guides/pay-for-an-api)
- [Issue a Card](/guides/issue-a-card)
- [Meter Your API](/guides/meter-your-api)
- [Handle Approvals](/guides/handle-approvals)
- [Listen for Events](/guides/listen-for-events)
- [SDK Essentials](/reference/sdk)
- [ModularVault](/reference/sdk/modular-vault)
- [PlatformClient](/reference/sdk/platform-client)
- [FacilitatorClient](/reference/sdk/facilitator-client)
- [createX402Fetch](/reference/sdk/create-x402-fetch)
- [buildPolicyParams](/reference/sdk/build-policy-params)
- [Networks & Addresses](/reference/networks)
-->

# createX402Fetch

A drop-in `fetch` that pays for you. When a server answers `402 Payment Required`, it signs a payment with the agent's key and retries automatically.

```typescript
import { createX402Fetch } from "@newton-xyz/isaac";

const fetch402 = createX402Fetch({
  agentKey: "0x...", // agent private key
  rpcUrl: "https://sepolia.base.org",
  chainId: 84532, // optional, defaults to Base Sepolia
});
```

`createX402Fetch(config)` returns a fetch-like function. Have an agent's key held in a managed signing session instead of a raw key? Use `createX402FetchFromSigner({ signer, rpcUrl, chainId })`.

## Making a paid request

```typescript
const result = await fetch402("https://api.example.com/data", {
  method: "GET",
  maxPayment: "1000000", // optional cap, in token base units
});

if (result.success) {
  const data = await result.response.json();
  console.log("paid", result.txHash, "on", result.network);
}
```

The call takes the same options as `fetch`, plus `maxPayment` — the most the agent will pay in token base units (for example `"1000000"` is 1 USDC at 6 decimals). If the server asks for more, the request aborts and `result.success` is `false` without paying.

A successful `result` carries the HTTP `response` and, when a payment was made, the settlement `txHash`, `network`, and `payer`. If the endpoint returns a normal (non-402) response, it comes straight back with no payment.

## Smart-payer payloads

Use `createSmartPayerPaymentPayload` when the payer is an isolated `SessionBudgetSmartPayer` instead of the agent's general EOA.

```typescript
import {
  createSmartPayerPaymentPayload,
  eip3009AuthorizationFromPaymentPayload,
} from "@newton-xyz/isaac";

const paymentPayload = await createSmartPayerPaymentPayload(
  {
    session,
    readContract: publicClient.readContract,
    signSessionApprovalHash: async ({ hash }) => {
      return sessionSigner.sign({ hash });
    },
  },
  paymentRequired,
  { maxPayment: "1000000" },
);

const authorization = eip3009AuthorizationFromPaymentPayload(paymentPayload);
```

The helper builds an x402 EIP-3009 payload with the smart-payer address as `authorization.from`. Its signature field is an ABI-encoded ERC-1271 envelope containing the EIP-3009 authorization, the session terms, and the authorized session signer's signature over `sessionApprovalHash(terms)`. The signed terms bind the exact EIP-3009 amount as well as the session max amount.

It rejects mismatched token, recipient, network, non-exact schemes, explicit non-EIP-3009 transfer methods, inactive or expired sessions, over-budget requirements, and non-Base-Sepolia sessions before it calls `readContract` or `signSessionApprovalHash`. Omitted `extra.assetTransferMethod` is treated as the upstream x402 EIP-3009 default.

## See also

* [Pay for an API](/guides/pay-for-an-api) — the full walkthrough.
* [PlatformClient](/reference/sdk/platform-client) — create and read smart-payer sessions.
* [buildPolicyParams](/reference/sdk/build-policy-params) — cap what an agent is allowed to spend.
