MoneyTools · all products

Agent payment-safety suite

Four existing MoneyTools products, used in a fixed order when an AI agent is about to pay. We never hold, move, or sign funds. Settle spend caps are advisory: they cannot block a wallet payment.

Suggested path: Precheck the seller → Settle spend/check against the budget → if the action is high-risk or over a threshold, ask a human via Approval Relay → pay with your own wallet (or Pay Gateway) → record it on Spend Ledger.

The four products

StepProductPriceLive free tier (UTC day)
1Pay Precheck
api.moneytools.dev/v1/precheck
Read 402 terms, payTo, sanctions and price sanity before paying. Verify a settlement at /v1/verify. Optional Pay Gateway at /v1/gateway.
0.005 USDC (precheck)HTTP: 5 free calls per IP per /v1 endpoint.
MCP: 20 free tool calls per client at https://mcp.moneytools.dev/mcp?utm_source=guide.
2Settle spend caps
settle.moneytools.dev/v1/spend/check
Advisory pre-sign check: would this payment exceed the cap? Docs: /docs/spend-caps.
0.005 USDC per checkFree trial key: 50 calls / 7 days, 1 per client per day (POST /v1/trial). Per-call x402 if you have no key.
3Approval Relay
relay.moneytools.dev/v1/approvals
One-time approve link, long-poll, Ed25519-signed receipt. Status, receipt and verify are free. MCP: https://relay.moneytools.dev/mcp.
0.005 USDC per request3 free requests per day.
4Spend Ledger
ledger.moneytools.dev
Where the agent's USDC went, by supplier and day. Gateway receipts, or any Base wallet.
0.05 USDC per wallet reportFree for Pay Gateway users with X-API-Key. Wallet reports are free with any MoneyTools API key, or 0.05 USDC via x402.

Pay Gateway step-up approvals (0.005 USDC) remain at approve.moneytools.dev for existing callers. New integrations should use Approval Relay.

Client wrapper (copy-paste snippet)

To plug Pay Precheck and Settle spend caps into any x402 client, wrap the underlying fetch, axios, requests or httpx session inside your payment wrapper. The hook inspects a 402, may refuse it, and otherwise returns the 402 so the outer client can sign. It never loads a key or sends a payment. Not published to npm or PyPI; copy the file.

Download: x402-guard.ts · x402-guard.py. Source and tests: in-repo sdk/x402-guard/.

import { wrapFetch } from "./x402-guard.ts";
// const paid = wrapFetchWithPayment(wrapFetch(fetch, { payer, maxUsd: 0.05 }), wallet);
const guarded = wrapFetch(fetch, { payer: "0xYourAgentWallet", maxUsd: 0.05, escalate: "high" });
const res = await guarded("https://seller.example/data");

Python: wrap_requests(session, {"payer": payer, "max_usd": 0.05}) or wrap_httpx(client, ...). Set a User-Agent; default Python-urllib is blocked on some workers.dev hosts. If Pay Precheck or Settle itself returns 401/402, the hook fails closed and does not pay MoneyTools automatically (pass apiKey or wait for the daily free-tier reset).

Shared examples (manual hook)

A shorter, call-it-yourself beforePay sketch: TypeScript suite.ts · Python suite.py.

// MoneyTools payment-safety suite — suggested order for an agent about to pay.
// Free tiers (live, UTC day): Pay Precheck HTTP 5/IP/endpoint, MCP 20/client;
// Approval Relay 3/day; Settle free trial 50 calls / 7 days (or 0.005 USDC per check).
// This snippet does not sign a wallet or send a payment.

const PRECHECK = "https://api.moneytools.dev/v1/precheck?utm_source=guide";
const SETTLE = "https://settle.moneytools.dev/v1/spend/check";
const RELAY = "https://relay.moneytools.dev/v1/approvals";
const LEDGER = "https://ledger.moneytools.dev/v1/ledger?utm_source=guide";

export async function beforePay({ sellerUrl, payer, amountUsd, host, risk = "med" }: {
  sellerUrl: string; payer: string; amountUsd: string; host: string; risk?: "low" | "med" | "high";
}) {
  const pre = await fetch(`${PRECHECK}?url=${encodeURIComponent(sellerUrl)}`).then((r) => r.json());
  if (pre.verdict === "block" || pre.ok === false) return { proceed: false, step: "precheck", pre };

  const cap = await fetch(SETTLE, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ payer, amountUsd, host }),
  }).then((r) => r.json());
  if (cap.allow === false) return { proceed: false, step: "spend_check", cap };

  const needsHuman = risk === "high" || cap.allow === false;
  if (needsHuman) {
    const appr = await fetch(RELAY, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({
        action_summary: `Pay ${amountUsd} USDC to ${host} at ${sellerUrl}`,
        risk,
        expires_in_s: 3600,
      }),
    }).then((r) => r.json());
    return { proceed: false, step: "approval_relay", approve_url: appr.approve_url, approval_id: appr.approval_id, poll_url: appr.poll_url };
  }

  return { proceed: true, pre, cap };
}

// After you pay

Free-tier cheat sheet (live, do not assume one number for every host)

Agents: site llms.txt · Precheck llms · Settle llms · Relay llms · Ledger llms · Terms · Privacy · support@moneytools.dev