AI agents are now spending real money autonomously. Here's how to add a simple trust check before your agent transacts with any domain.
AI agents are spending real money now. The x402 protocol has processed over 165 million transactions across ~69,000 active agents. That's a lot of autonomous USDC flying around to domains your agent has never seen before.
The problem is a pretty natural consequence of that: agents can't easily tell if a domain they're about to pay is legitimate or not. A human glances at a URL and picks up on a dozen signals — the TLD, whether they recognize the registrar, how old the site looks. An agent doing the same thing has to either skip that check entirely or build the verification infrastructure itself.
This post is about how to add a lightweight trust check to your agent before it transacts, using a pay-per-use API on the x402 protocol.
Why this matters
Consider an agent that searches for a service, finds a matching x402 endpoint, and prepares to pay. Without any trust verification, it's essentially trusting that:
- The domain is what it claims to be
- It wasn't registered yesterday as a throwaway
- It has some real operational presence (DNS, mail, etc.)
- It's using a legitimate registrar
None of that is guaranteed. High-risk domains — .xyz, .tk, .click — cost pennies and are disproportionately used in phishing and fraud. A domain registered three weeks ago with no MX records and an obscure registrar is a different risk profile than api.somestablecompany.io that's been around for five years.
A trust check doesn't solve everything. It's one signal among several. But it's a cheap, fast, structured signal your agent can act on before committing funds.
The API
TrustSource is an x402-enabled domain trust scoring API. You send a domain or URL, it returns a 0–100 score, a risk tier, and the underlying signals that drove the score. No API key, no account — it uses x402, so your agent pays 0.003 USDC per query and gets the result.
The full OpenAPI spec is at trustsource.cc/openapi.json if you want the machine-readable version.
Here's what a response looks like:
{
"domain": "google.com",
"score": 90,
"maxScore": 100,
"tier": "TRUSTED",
"breakdown": {
"domainAge": 30,
"tld": 20,
"dnsPresence": 30,
"registrar": 10
},
"details": {
"age": {
"days": 10477,
"label": "established (5+ years)",
"created": "1997-09-15T07:00:00+0000",
"expires": null
},
"tld": ".com",
"dns": {
"hasARecord": true,
"hasMxRecord": true,
"mxRecords": ["smtp.google.com"]
},
"registrar": "markmonitor, inc."
},
"meta": {
"checkedAt": "2026-05-24T10:00:00.000Z",
"apiVersion": "1.0",
"paidWith": "x402/USDC",
"cached": false
}
}
The four scoring signals:
| Signal | Max points | What it measures |
|---|---|---|
| Domain age | 30 | WHOIS creation date — older = more trusted |
| TLD | 20 |
.com/.org/.io = trusted, .tk/.xyz/.click = risky |
| DNS presence | 30 | Has A record (+20) and MX records (+10) |
| Registrar | 20 | Known established registrar vs. unknown |
Tiers: TRUSTED (75+) / MODERATE (50–74) / CAUTION (25–49) / HIGH_RISK (0–24)
Results are cached for 1 hour per domain, so repeat lookups are fast and the underlying WHOIS servers don't get hammered.
Integrating with your agent
Your agent needs to handle x402 payments to call this. If you're already using x402 in your stack, adding a trust check is straightforward. Here's a complete example:
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
// Set up x402 client (your agent's wallet)
const signer = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
async function checkTrustBeforePaying(targetUrl) {
const domain = new URL(targetUrl).hostname;
// Query trust score — agent pays 0.003 USDC automatically
const response = await fetchWithPayment(
`https://trustsource.cc/trustscore?domain=${domain}`
);
const trust = await response.json();
console.log(`${domain}: ${trust.score}/100 (${trust.tier})`);
return trust;
}
async function agentPurchaseFlow(serviceUrl, purchaseAmount) {
const trust = await checkTrustBeforePaying(serviceUrl);
if (trust.tier === "HIGH_RISK") {
throw new Error(`Aborting: ${trust.domain} is HIGH_RISK (score: ${trust.score})`);
}
if (trust.tier === "CAUTION") {
// Your agent might want to flag this for review rather than abort
console.warn(`Proceeding with caution: ${trust.domain} scored ${trust.score}/100`);
}
// Proceed with the actual purchase...
}
Decision logic patterns
How you act on the score depends on your agent's risk tolerance. A few approaches that make sense depending on context:
Hard block on HIGH_RISK:
if (trust.tier === "HIGH_RISK") {
return { action: "abort", reason: `Domain scored ${trust.score}/100` };
}
Threshold-based with escalation:
if (trust.score < 50) {
return { action: "escalate", requiresHumanApproval: true };
} else if (trust.score < 75) {
return { action: "proceed_with_log", riskFlag: true };
} else {
return { action: "proceed" };
}
Cost-proportional gating (sensible for variable-cost purchases):
// Require higher trust for larger transactions
const minimumScore = purchaseAmount > 1.00 ? 70 : 50;
if (trust.score < minimumScore) {
return { action: "abort" };
}
What it doesn't cover
Worth being explicit about the limitations:
- WHOIS privacy protection — many domains redact registration data under GDPR. When that happens, the age score falls back to 0 ("unknown"). This is a known limitation of the public WHOIS system, not something this API can work around.
-
Recently compromised legitimate domains — a 10-year-old
.comwith good DNS can still be a phishing site if the domain was hijacked. This API scores structural signals, not content. - Very new legitimate services — a startup that launched last month will score low on domain age even if it's completely legitimate. Context matters.
The score is best used as a filter to catch obvious red flags, not as a definitive verdict on any domain.
Using it without x402
If your agent stack doesn't support x402 yet, you can still test it by running the payment manually. Get some Base Sepolia testnet USDC from faucet.circle.com, switch to testnet (NETWORK=eip155:84532, FACILITATOR_URL=https://x402.org/facilitator), and use the example client from the x402 quickstart for buyers.
Resources
- API endpoint: trustsource.cc
- OpenAPI spec: trustsource.cc/openapi.json
- Agentic.Market listing: agentic.market
- x402 protocol docs: docs.x402.org
- x402 buyer quickstart: docs.cdp.coinbase.com/x402/quickstart-for-buyers
If you're building agent payment flows and have thoughts on what other trust signals would be useful, happy to hear them.
Top comments (0)