The Minifetch /extract/url-metadata API endpoint returns every major on-page technical SEO signal
in a single structured JSON response. This tutorial walks you through reading that response
and turning it into a clear technical SEO checklist. Minifetch is free to use when you sign up and claim your
free starter credits, and pay-as-you-go after that. That's pay-per-audit SEO, without a monthly
subscription plan.
Check back later and we'll show you how to use the Minifetch API to turn this checklist into an analysis you can import to your AI Agents and automation workflows. To be notified, fill out our feedback form or join the Discord.
Before you start, pick how you'll authenticate with Minifetch:
API key — Sign up on the dashboard, grab free starter credits, and create a key. Recommended for most builders.
USDC via x402 — Pay directly from a crypto wallet, no account needed.
Free
Before spending a credit, run a quick preflight check to confirm the URL is fetchable.
This is free and tells you whether the site's robots.txt allows Minifetch to fetch it.
From the homepage, enter your URL in the search box and click "Check URL".
Or with the minifetch api client:
await client.preflightCheck("https://yoursite.com/your-page");
checkAndExtractUrlMetadata() method in the minifetch-api client
runs the preflight automatically before every paid fetch — so you only pay when a result is likely.
Or from your cli:
curl "https://minifetch.com/api/v1/free/preflight/url-check?url=https://yoursite.com/your-page"
Free to start, then $0.002 per URL
From the homepage, just click "Go Fetch!". Metadata extraction is the default option.
Or with the minifetch api client:
const result = await client.checkAndExtractUrlMetadata(
"https://yoursite.com/your-page",
{ verbosity: "full" }
);
Or from your cli:
curl "https://minifetch.com/api/v1/extract/url-metadata?url=https://yoursite.com/your-page&verbosity=full" \
-H "Authorization: Bearer YOUR_API_KEY"
Call the metadata endpoint with the verbosity=full option to get every signal, including
favicons, response headers, hreflang tags, the full heading hierarchy, and image metadata.
verbosity=full: If you only need the core SEO
fields (title, description, canonical, og tags), leave it off. The default response is
lighter and cheaper in an LLM context.
The response maps directly to the signals search engines and social platforms care about. Here's what to check in each section:
Core on-page signals
| Field | What to check |
|---|---|
| title | Present? Between 50–60 characters? Contains your primary keyword? |
| description | Present? Between 120–160 characters? Compelling and keyword-relevant? |
| canonical | Present? Points to itself? (A canonical pointing elsewhere signals a duplicate content issue.) |
| lang | Set correctly for the page's target market? |
| hreflang | If the site is multilingual: are all regions covered, with no missing reciprocal tags? |
| viewport | Present? Google uses this as a mobile-friendliness signal. |
| charset | Set? (Typically utf-8.) |
Structured data (rich results)
| Field | What to check |
|---|---|
| jsonld | Present? Structured data unlocks rich results in Google Search (stars, prices, FAQs, breadcrumbs). |
| jsonld[].@type | Matches the page's intent? Common types: Article, Product, BreadcrumbList, FAQPage. |
Social / Open Graph
| Field | What to check |
|---|---|
| og:title | Present? Can be the same as title or slightly different for social context. |
| og:description | Present? |
| og:image | Present? Recommended size is 1200×630px for best display across platforms. |
| og:type | Set? (e.g. website, article, product) |
| twitter:card | Present? summary_large_image gets the best display on X/Twitter. |
| twitter:title | Present? |
| twitter:image | Present? |
Content structure
| Field | What to check |
|---|---|
| headings.h1 | Exactly one H1? Contains the primary keyword? Multiple H1s are an SEO anti-pattern. |
| headings.h2 | Present and logically structured? |
| images[].alt | Non-empty on every image? Missing alt text is both an SEO flag and an accessibility issue. |
| images[].width / height | Set on every image? Missing dimensions cause layout shift, which hurts Core Web Vitals scores. |
Technical signals (from response headers)
| Field | What to check |
|---|---|
| responseStatusCode | Should be 200. Anything else is a problem to investigate. |
| responseHeaders['x-robots-tag'] | Not set to noindex? A noindex header silently removes a page from search results. |
| responseHeaders['cache-control'] | Set with a reasonable TTL? Helps crawl efficiency. |
Every response includes a minifetchCache object that tells you when the cached
result expires:
"minifetchCache": {
"hit": "false",
"cachedAt": "2026-04-22T10:00:00.000Z",
"expiresAt": "2026-04-22T10:02:00.000Z"
}
If hit is true, you received a cached result and the page
was not re-fetched. After deploying a fix, wait until after the expiresAt
timestamp before re-auditing — fetching earlier returns the same cached data
and charges a credit unnecessarily.
The cache window is typically 2 minutes.