The boring upside

JSON-LD on a page is a small payload. Maybe 1KB per endpoint. Search crawlers parse it. AI-search routers parse it. Some of them weight it heavily when deciding what to cite.

You can ship a beautifully-designed endpoint page and it'll still lose to a worse-looking competitor whose page emits structured data. That's the part most teams don't internalize until they've measured.

What we emit per endpoint

Every page at agentutility.ai/<cluster>/<endpoint> carries three JSON-LD blocks. Here's the shape:

{
  "@context": "https://schema.org",
  "@type": ["WebAPI", "Service"],
  "name": "secrets-exposure-check",
  "description": "Grep + entropy scanner for committed API keys...",
  "url": "https://agentutility.ai/prooflayer/secrets-exposure-check",
  "category": "security",
  "potentialAction": {
    "@type": "ConsumeAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://x402.org/v1/secrets-exposure-check",
      "httpMethod": "POST",
      "contentType": "application/json",
      "actionPlatform": ["x402", "MCP"]
    },
    "expectsAcceptanceOf": {
      "@type": "Offer",
      "price": "0.02",
      "priceCurrency": "USDC"
    }
  },
  "offers": {
    "@type": "Offer",
    "price": "0.02",
    "priceCurrency": "USDC",
    "priceSpecification": {
      "@type": "UnitPriceSpecification",
      "price": "0.02",
      "priceCurrency": "USDC",
      "unitText": "per call"
    }
  }
}

Two things this gives you that a plain HTML page can't:

  • An LLM can answer "what's the price" from the structured data without parsing the body. That's a 100x speedup on the routing decision.
  • A search engine can render a rich result with the price inline. We've seen Google AI Overviews quote our prices directly, sourced from the Offer block.

We also emit a BreadcrumbList and a TechArticle. The TechArticle helps with "explain how this works" queries. The BreadcrumbList helps with "show me the catalog" queries.

What we don't emit

No aggregateRating. We don't have ratings yet. Spoofing them would tank trust fast.

No Review. Same reason.

No fake Product block. A paid API isn't a Product in the e-commerce sense and trying to fake it will trip the spam filters at Google.

How to test yours

Two commands:

# inspect a page
curl -s https://your-site/endpoint-1 | grep -A 200 'application/ld+json'

# validate
npx schema-org-validator your-page.html

If you're using Next.js, the simplest pattern is a server component that injects a <script type="application/ld+json"> tag with dangerouslySetInnerHTML. We do this in components/JsonLd.tsx. Pure static, ships in the build, costs nothing to render.

The price field gotcha

Schema.org's price field expects a string. Some validators want a number. Most importantly, your priceCurrency field can be any ISO-4217 currency code OR a custom string. "USDC" is a custom string and Google handles it fine. If you're using a different stablecoin, write the symbol, not the contract address.

We also include actionPlatform: ["x402", "MCP"] even though that's not a Schema.org-blessed enum. The point is to give downstream parsers a signal they can grep on. Google ignores fields it doesn't recognize. Anthropic's models pay attention to them.

Why we don't bother with OpenAPI

OpenAPI is great for traditional API portals. It assumes a long-lived URL surface with versioned operations, request bodies, response codes, OAuth flows. None of that maps cleanly to x402, where there's no auth header to specify, no version path, no rate-limit headers. Schema.org's Service + ConsumeAction maps better. The trade-off is fewer downstream tools support it. The trade is worth it for our case.

What this adds up to

Every endpoint page gets indexed twice. Once by the renderer that scrapes HTML for content. Once by the parser that scrapes JSON-LD for structure. The second one is what makes the difference in AI-search citation. So we ship it.