Agent-callable has to mean something testable

“Agent-callable” can’t mean “there’s an API somewhere.”

That bar is too low. A human can read docs, guess missing fields, retry with a different shape, inspect a dashboard, and decide whether a $0.12 call is sane. An agent needs less romance. It needs a URL, a payment requirement, a request schema, a response schema, and a reason to trust that the call won’t waste budget.

So here’s the working definition for agentutility.ai:

An endpoint is agent-callable when a fresh agent can discover it, price it, pay for it over x402 on Base mainnet, call it with valid input, parse the output, and decide what to do next.

No private email. No sales form. No hidden auth step.

The current registry has 254 paid endpoints across edge-finance, locale, edge-market, prooflayer, wordmint, web-probe, mediakit, and synthforge. Prices run from $0.001 to $0.30 per call. That range only helps agents if each price is exposed before payment.

Test 1: cold curl works

Cold curl means a caller with no session can hit the endpoint and get a clear x402 payment response.

The first request should fail in a useful way:

curl -i https://agentutility.ai/api/x402/example-endpoint \
  -H "content-type: application/json" \
  -d '{"input":"example.com"}'

A good unpaid response tells the caller what’s missing:

HTTP/1.1 402 Payment Required
content-type: application/json
x-accepts: x402
{
  "error": "payment_required",
  "network": "base-mainnet",
  "asset": "USDC",
  "amount": "0.003",
  "payTo": "0x...",
  "resource": "https://agentutility.ai/api/x402/example-endpoint"
}

An agent can route from that. It can compare cost, check wallet policy, and decide.

A bad response says “unauthorized,” links to a docs page, or returns HTML. That’s human-callable at best.

Test 2: JSON-LD says what the endpoint is

Agents need machine-readable meaning. Plain OpenAPI tells a caller how to send bytes. JSON-LD can tell a planner what the call is for.

A minimum endpoint descriptor should include name, category, input, output, price, chain, and payment asset:

{
  "@context": "https://schema.org",
  "@type": "WebAPI",
  "name": "Secrets exposure check",
  "url": "https://agentutility.ai/api/x402/secrets-exposure-check",
  "applicationCategory": "prooflayer",
  "description": "Checks public text for exposed API keys, tokens, and credential patterns.",
  "offers": {
    "@type": "Offer",
    "price": "0.01",
    "priceCurrency": "USDC"
  },
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://agentutility.ai/api/x402/secrets-exposure-check",
      "httpMethod": "POST",
      "encodingType": "application/json"
    }
  }
}

Look at that from the router’s side. Can the model tell when this beats a local regex? Can it tell the cost before it calls? Can it explain why it picked prooflayer instead of web-probe?

If not, the metadata is too thin.

Test 3: validation is strict and boring

Input validation should reject bad calls before payment when possible. If validation must happen after payment, the paid error needs to be parseable and narrow.

Good validation says exactly which field failed:

{
  "error": "invalid_input",
  "field": "url",
  "expected": "absolute HTTPS URL",
  "received": "example"
}

Output validation matters just as much. Agent chains break when an endpoint returns prose one day and JSON the next.

Use stable fields:

{
  "ok": true,
  "risk": "high",
  "findings": [
    {
      "type": "api_key",
      "label": "OpenAI-style key",
      "start": 184,
      "end": 235
    }
  ],
  "checkedAt": "2026-06-18T00:00:00Z"
}

Don’t make the agent scrape a paragraph. Don’t hide the result under changing keys. And don’t return “success” when the business result is a failed check.

Test 4: MCP discovery matches the HTTP contract

MCP is where many agents will first meet the endpoint. The MCP tool entry should match the HTTP endpoint, not reinterpret it.

That means the same required fields. Same price. Same error names. Same response shape.

If MCP says domain and HTTP says url, you’ve made the agent translate between two contracts. That’s wasted context. Worse, it creates bugs that look like reasoning failures when they’re just schema drift.

A clean MCP listing gives the planner enough to choose:

{
  "name": "secrets_exposure_check",
  "description": "Checks text or a URL for exposed secrets.",
  "inputSchema": {
    "type": "object",
    "required": ["url"],
    "properties": {
      "url": {
        "type": "string",
        "format": "uri"
      }
    }
  },
  "x402": {
    "network": "base-mainnet",
    "asset": "USDC",
    "amount": "0.01"
  }
}

Short. Specific. Routable.

Test 5: price is a field, not a sentence

Agents can’t manage spend from copy like “low-cost checks” or “premium analysis.” They need numbers.

Every paid endpoint should publish price as data in at least three places: registry entry, 402 response, and MCP metadata. Same value. Same unit. Same chain.

For agentutility.ai, that means USDC on Base mainnet, with current endpoint prices from $0.001 to $0.30. A routing model can now apply policy: call anything under $0.005 automatically, ask before calls over $0.05, block calls over $0.30.

That’s where “agent-callable” becomes real. The agent sees the surface, prices the action, pays through x402, gets typed output, and keeps working.