URL Metadata and Link Preview API: OpenGraph, Twitter Tags, JSON-LD for $0.001
/v1/metadata fetches a public HTML page and returns what a link preview needs: title, meta description, canonical URL, language, OpenGraph and Twitter tags and parsed JSON-LD blocks. $0.001 USDC on Base per call, paid over x402, charged only on success.
- Everything for a preview card
title, description, canonical, lang, og (OpenGraph tags, e.g. og.title), twitter (Twitter card tags) and json_ld (parsed blocks; json_ld_invalid counts the ones that failed to parse).
- Final URL after redirects
final_url shows where the page landed, after at most 5 redirects.
- Limits
Public http(s) HTML pages on default ports only, 8 s per fetch, 20 s per call, 2 MB per page.
- Not charged on failure
A blocked URL (400), a non-HTML page (422) or a fetch failure (502) is not charged.
Cost: $0.001 per call. Previewing 2,000 links a month costs $2.00.
Code examples
curl: unpaid call shows the price (HTTP 402, $0.001)
curl -i -G https://api.switch402.com/v1/metadata \
-H 'User-Agent: my-agent/1.0' \
--data-urlencode 'url=https://example.com'
# 200 after payment: {"url", "final_url", "title", "description", "canonical", "lang",
# "og": {...}, "twitter": {...}, "json_ld": [...], "json_ld_invalid", "truncated", "ms"}Python: build a link preview card
# pip install "x402[requests,evm]"
import os
from eth_account import Account
from x402 import x402ClientSync
from x402.http.clients import x402_requests
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact import ExactEvmScheme
client = x402ClientSync()
client.register("eip155:8453", ExactEvmScheme(signer=EthAccountSigner(Account.from_key(os.environ["AGENT_KEY"]))))
session = x402_requests(client)
session.headers["User-Agent"] = "my-agent/1.0"
def link_preview(url: str) -> dict:
"""Title, description and image for a preview card ($0.001 per successful call)."""
r = session.post("https://api.switch402.com/v1/metadata", json={"url": url})
r.raise_for_status()
m = r.json()
og = m.get("og") or {}
return {
"url": m.get("canonical") or m["final_url"],
"title": og.get("title") or m.get("title"),
"description": og.get("description") or m.get("description"),
"image": og.get("image"),
}MCP: the metadata tool
curl -s -X POST https://api.switch402.com/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -H 'User-Agent: my-agent/1.0' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"metadata","arguments":{"url":"https://example.com"}}}'FAQ
- What does a call cost if the page fails?
- Nothing. A blocked URL, a page that is not HTML or a fetch failure is not charged.
- Does it return the preview image file?
- It returns the image URL from the OpenGraph tags as published on the page, not the image itself.
- Is this the same as a link preview API?
- Yes for the data: the fields a preview card needs come back in one call. Rendering the card is up to your app.