Check before you pay
Your agent is about to send USDC to a URL. One request first tells you whether that endpoint is live, whether it has ever been paid successfully, and whether it was listed here and later removed. Every snippet below does the same thing — only the syntax changes.
GET https://nohumans.directory/v1/resolve?url=<endpoint>
What you get back
match: "active"— listed and currently tracked. Readstatus(verified/unverified/failing),score(0..1 recency-weighted probe success) andpaid_verification(whether we paid it real USDC and what came back).match: "delisted"— it was listed here and removed. Treat as a warning.match: "unknown"(HTTP 404) — never listed, never checked. This is not a verdict. Absence of a record says nothing about an endpoint either way.
Free, unauthenticated, cached 30s. No account, no key.
MCP clients
If your framework speaks MCP, connect once and the check becomes a tool your agent can call on its own — along with search and full listing detail.
claude mcp add --transport http nohumans https://nohumans.directory/mcp
Tools: find_paid_service (search by need), get_service_details (full record by id), resolve_endpoint (pre-spend check of a URL you already hold) and what_agents_are_asking_for (what agents searched for here, for sellers deciding what to build).
Connect from your client — one server, one URL
The MCP server is https://api.nohumans.directory/mcp:
Streamable HTTP, stateless, no key, no session. Pick your client; the config
below is exact for each. Nothing to translate.
Add to Cursor Add to VS Code Add to VS Code Insiders
Claude (desktop or web): Settings → Connectors → Add custom connector → paste the URL. Claude Code:
claude mcp add --transport http nohumans https://api.nohumans.directory/mcp
ChatGPT: Settings → Connectors → Developer mode → add MCP server → paste the URL.
Gemini CLI:
gemini mcp add --transport http nohumans https://api.nohumans.directory/mcp
Windsurf (~/.codeium/windsurf/mcp_config.json), Cline, Roo, and any client that reads a mcpServers block:
{ "mcpServers": { "nohumans": { "type": "http", "url": "https://api.nohumans.directory/mcp" } } }
OpenAI Agents SDK (Python):
from agents.mcp import MCPServerStreamableHttp
nohumans = MCPServerStreamableHttp(name="nohumans", params={"url": "https://api.nohumans.directory/mcp"})
LangChain / LangGraph (langchain-mcp-adapters):
client = MultiServerMCPClient({"nohumans": {"url": "https://api.nohumans.directory/mcp", "transport": "streamable_http"}})
Not on MCP? Function-calling stacks read /openapi.json; A2A agents read the signed agent card; marketplaces (AgentCash, Poncho, x402scan) already carry the same routes. If your client isn’t here and needs a different line, hello@nohumans.directory — it will be added, not translated.
TypeScript — @x402/fetch (v2)
const check = await fetch(`https://nohumans.directory/v1/resolve?url=${encodeURIComponent(url)}`);
const v = check.ok ? await check.json() : { match: "unknown" };
if (v.match === "delisted" || v.detail?.status === "failing") throw new Error("skip: " + v.match);
const res = await fetchWithPayment(url); // your existing paid call
TypeScript — x402-fetch / x402-axios (v1)
The v1 client packages are deprecated upstream but still widely
installed. One extra reason to check first: a v1 client reads payment terms
from the 402 body, so a v2 endpoint that answers with a
payment-required header will look broken to it. We record which
version each endpoint actually used.
const v = await (await fetch(`https://nohumans.directory/v1/resolve?url=${encodeURIComponent(url)}`)).json().catch(() => ({ match: "unknown" }));
if (v.detail?.x402_version === 2) console.warn("v2 endpoint — a v1-only client may not see its terms");
if (v.match === "delisted") return;
const res = await fetchWithPay(url); // x402-fetch
Python
import requests, urllib.parse
r = requests.get("https://nohumans.directory/v1/resolve", params={"url": target})
v = r.json() if r.ok else {"match": "unknown"}
if v["match"] == "delisted" or v.get("detail", {}).get("status") == "failing":
raise RuntimeError(f"skip {target}: {v['match']}")
Any language / curl
curl -sG https://nohumans.directory/v1/resolve --data-urlencode "url=$ENDPOINT" | jq '.match, .detail.status, .detail.score'
Paid verdict — one call, $0.005 USDC on Base
Everything above is free and stays free. For a listing you are about to
spend real money on, GET /v1/listings/:id/verdict folds the whole
record into one word — pay, caution or
avoid — with the reasons, by the rule at
/methodology#verdict. It is an x402 v2
route: the unpaid call answers 402 with its terms in both the
payment-required header and the body, so any v2 client pays it
exactly the way it pays the endpoint you are vetting.
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
const client = registerExactEvmScheme(new x402Client(), { signer }); // viem account
const payFetch = wrapFetchWithPayment(fetch, client);
const v = await (await payFetch(`https://nohumans.directory/v1/listings/${id}/verdict`)).json();
if (v.verdict === "avoid") throw new Error(v.reasons.join("; "));
A real answer, 2026-09-05, for a listing with status
verified: {"verdict":"caution","reasons":["no successful paid
delivery on record from our scout"]} — clean 402 history, stable
payTo, price as declared, but we have not yet bought from it ourselves, and the
verdict says exactly that. caution on a verified listing is the
rule working, not a contradiction; the free record it summarises is the same
/v1/listings/:id above. On Coinbase's hosted wallet,
awal x402 pay <url> buys the same verdict. Settlement runs
through the CDP facilitator; the transaction hash comes back in the
payment-response header.
What this does not tell you
Everything here is endpoint behaviour: correct 402s, a live free sample, a stable payment address, real payment volume, and — where we have paid it ourselves — that a real purchase returned valid data at a point in time. None of it verifies who operates the software behind a URL today, and none of it guarantees the content you buy is accurate. A compromised domain that keeps its payment address and returns well-formed responses passes every check here. That is a structural limit of behavioural verification, not a gap we intend to close quietly.
Full field reference: /llms.txt. Questions or a framework we should cover: hello@nohumans.directory
state of the network · methodology · stats · sellers · integrate · terms · privacy