# Minifetch Skill: Competitive SEO Analysis Compare your page's SEO signals side-by-side with a competitor's. The `/extract/url-metadata` response is a structured SEO checklist -- diff two responses to surface gaps and opportunities. **Base URL:** https://minifetch.com --- ## What You'll Do 1. Setup -- choose payment method and access method 2. (Free) Preflight -- confirm both URLs are crawlable 3. (Paid) Fetch metadata for your URL 4. (Paid) Fetch metadata for the competitor URL 5. Diff the two responses -- surface gaps and opportunities --- ## Step 1 — Setup ### Choose a payment method There is no account setup fee or monthly fee. Minifetch does not charge for blocked pages or errors. **Option 1: Credit card (account setup required)** Sign up and get your first 250 fetches free, no credit card required to begin: https://minifetch.com/dashboard Click the "Sign up" button and verify your email address to create your account. Once you are signed in to your account, each successful "Go Fetch!" will be deducted from your credit balance. Top up for as little as $2 with your credit card. **Option 2: USDC via x402 on Base or Solana (no account setup needed)** Pay with your crypto wallet. See: https://www.x402.org/ ### Prices (pay-as-you-go) - URL Check (preflight): Free - URL Preview: $0.001 - URL Content: $0.002 - URL Links: $0.002 - URL Metadata: $0.002 ### Choose an access method **Option A: minifetch-api (recommended for agents)** Handles payment automatically — no manual auth header or x402 handshake needed. ``` npm install minifetch-api --save ``` Quickstart: https://www.npmjs.com/package/minifetch-api **Option B: curl + API key** ``` curl "https://minifetch.com/api/v1/extract/url-metadata?url=https://example.com" \ -H "Authorization: Bearer [your_api_key]" ``` **Option C: Coinbase Payments MCP (for AI assistants like Claude)** Gives AI assistants a built-in wallet — no private key needed. ``` npx @coinbase/payments-mcp ``` See: https://www.npmjs.com/package/@coinbase/payments-mcp --- ## Step 2 (Free) -- Preflight Check Confirm the URL is crawlable before spending credits: ``` curl "https://minifetch.com/api/v1/free/preflight/url-check?url=[target_url]" ``` Or with minifetch-api (the `checkAndExtract*` methods run this automatically). You can also call it as a standalone function: ```js await client.preflightCheck(url); ``` If `allowed: false` is returned, skip the paid request -- Minifetch will not charge for blocked pages, but the preflight saves a round trip. If you own the site and want to allow Minifetch access, see: https://minifetch.com/skills/unblock-minifetch/SKILL.md --- ## Step 3 -- Fetch Metadata for Both URLs Run this request twice: once for your URL, once for the competitor's. ``` curl "https://minifetch.com/api/v1/extract/url-metadata?url=https://example.com&verbosity=full" \ -H "Authorization: Bearer [your_api_key]" ``` Or with minifetch-api: ```js await client.checkAndExtractUrlMetadata(url, { verbosity: 'full' }); ``` **Price:** $0.002 per URL (two requests total) --- ## Step 4 -- Diff the Responses Compare these fields between your page and the competitor's. Flag where the competitor has a signal you are missing, or where you have an advantage. ### Core On-Page Signals | Field | Your page | Competitor | Gap? | |---|---|---|---| | `title` | length, keywords | length, keywords | Longer/shorter? Different keywords? | | `description` | length, keywords | length, keywords | -- | | `canonical` | self-referencing? | self-referencing? | -- | | `lang` / `hreflang` | regions covered | regions covered | Missing markets? | ### Structured Data | Field | What to compare | |---|---| | `jsonLd[].@type` | Does competitor use schema types you don't? (FAQ, HowTo, Product, Review, BreadcrumbList) | | `jsonLd` presence | Do they have structured data and you don't? | ### Social Signals | Field | What to compare | |---|---| | `og:image` | Do they have one? Do you? | | `twitter:card` | Type mismatch? (summary vs summary_large_image) | ### Content Structure | Field | What to compare | |---|---| | `headings.h1` | Different keyword targeting in H1? | | `headings.h2` | How many subheadings? Topic coverage breadth? | | `images[].alt` | Do they have better alt text coverage? Missing alt is both an SEO and accessibility flag. | | `images[].width` / `height` | Set on all images? Affects Core Web Vitals. | | `favicons` | Do they have more sizes or formats? (16x16, 32x32, 180x180 for Apple) | ### Link Profile (via `/extract/url-links`) For a deeper comparison, fetch links for both URLs: ``` curl "https://minifetch.com/api/v1/extract/url-links?url=https://example.com" \ -H "Authorization: Bearer [your_api_key]" ``` Or with minifetch-api: ```js await client.checkAndExtractUrlLinks(url); ``` **Price:** $0.002 per URL Compare: | Field | What to look for | |---|---| | `summary.internalCount` | Do they have stronger internal linking? | | `summary.uniqueExternalDomains` | More outbound authority signals? | | `summary.nofollowCount` | Nofollow patterns? | --- ## Step 5 -- Output Format Return findings as a structured comparison. For each signal: - Win -- your signal is stronger or equivalent - Tie -- similar signals, monitor over time - Gap -- competitor has a signal you are missing Example output: ``` Competitive SEO Analysis Your URL: https://yoursite.com/page Competitor URL: https://competitor.com/page --------------------------------------------- WIN Title: similar length, both target keyword GAP Description: competitor 148 chars, yours 62 (too short) GAP JSON-LD: competitor uses FAQ + BreadcrumbList schema, you have none WIN og:image: both present TIE H1: different keyword targeting -- review competitor H1 GAP Internal links: competitor has 84 vs your 21 GAP H2 headings: competitor has 9 subheadings covering more subtopics ``` --- ## Iterating on Results Every response includes a `minifetchCache` object: ```json "minifetchCache": { "hit": "false", "cachedAt": "2026-02-18T22:37:32.889Z", "expiresAt": "2026-02-18T22:39:32.889Z" } ``` - `hit: true` means the response was served from cache -- the page was not re-fetched. - `hit: false` means a live fetch was performed. - If you are iterating (e.g. re-checking both pages after competitor updates), check `expiresAt` and wait until after that timestamp before re-fetching. Fetching before expiry will return the same cached result and cost a credit unnecessarily. - The cache window is typically 2 minutes. Use `expiresAt` as your retry-after value, not a fixed delay. --- ## Error Codes - 200 Success - 400 Bad Request — missing or invalid `url` param - 402 Payment Required — no valid payment or credits exhausted - 403 Forbidden — target URL blocked (not charged) - 429 Too Many Requests — back off and retry, max 5–10 req/s - 502 Bad Gateway — target URL blocked or DNS error (not charged) - 503 Service Unavailable — timeout on target URL, retry later --- ## Contact Questions or need help? Join our [Discord server](https://discord.gg/EM6ET8Dshm). Feedback or bulk credits waitlist? Use our [feedback form](https://forms.gle/rkMi7T23bHJc8XFw9). Follow us on X: [@minifetch](https://x.com/minifetch) Full API docs: https://minifetch.com/llms.txt All skills: https://minifetch.com/SKILL.md