rapidapi-metadata-extractor
Detects if a website uses Angular and enhances extraction for Angular-based SPAs.
Detects if a website uses Astro and enhances extraction for Astro-based SPAs.
Detects links to Behance profiles on a website.
Detects links to Bluesky profiles on a website.
Detects links to Discord servers or profiles on a website.
Detects links to Dribbble profiles on a website.
Detects links to Facebook pages or profiles on a website.
Detects if a website uses Gatsby and enhances extraction for Gatsby-based SPAs.
Detects links to GitHub repositories or profiles on a website.
Detects links to GitLab repositories or profiles on a website.
Detects links to Instagram profiles on a website.
Detects links to Mastodon profiles on a website.
Detects links to Medium profiles or publications on a website.
Detects if a website uses Next.js and enhances extraction for Next.js-based SPAs.
Detects if a website uses Nuxt and enhances extraction for Nuxt-based SPAs.
Detects links to Pinterest profiles on a website.
Detects if a website uses React and enhances extraction for React-based SPAs.
Detects links to Reddit profiles or subreddits on a website.
Detects if a website uses Remix and enhances extraction for Remix-based SPAs.
Detects if a website is built on Shopify and extracts ecommerce metadata such as products and prices.
Detects links to Snapchat profiles on a website.
Detects if a website uses Stripe for payment processing and extracts relevant metadata.
Detects if a website uses Svelte and enhances extraction for Svelte-based SPAs.
Detects links to Telegram channels or profiles on a website.
Detects links to Threads profiles on a website.
Detects links to TikTok profiles on a website.
Detects links to Vimeo profiles or videos on a website.
Detects if a website is built with Webflow and extracts relevant metadata.
Detects if a website uses WooCommerce for ecommerce and extracts product-related data.
Detects if a website is powered by WordPress and extracts relevant metadata.
Detects links to YouTube channels or videos on a website.
Turn any URL into structured intelligence.
Extract SEO, technologies, contacts, products, social profiles, security signals, and AI-ready content from any public website — with one API call.
Free to try. No signup required for the demo.
🎮 Try the Live Demo • 🔑 Get Free API Key on RapidAPI • 📖 API Documentation • ⚡ Code Examples
Paste a URL, get real results in seconds — rapidapi-metadata-extractor.onrender.com runs the actual pipeline live, no API key needed. Try your own site, or one of these:
/demo/extractis the same no-key route the live demo page above uses (see "Honest Limitations" — it's rate-limited per IP, not a documented/stable API endpoint). For integrating in code, use/api/v1/extractwith a RapidAPI key as shown below.
Or call it directly (swap in your key from RapidAPI for production use):
curl "https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/extract?url=github.com" \
-H "X-RapidAPI-Key: YOUR_KEY" -H "X-RapidAPI-Host: web-metadata-and-contact-extractor.p.rapidapi.com"🎯 Use Cases
Use case | What you get | |
🧲 | Lead generation | Find companies on a given tech stack (e.g. Shopify) with a weak SEO score, then prioritize outreach. |
🤖 | AI agents | Feed |
🔎 | SEO audits | Run the 14-point on-page score plus graded security headers across a URL list, on a schedule. |
🛒 | Ecommerce | Pull product name/price/currency/availability/brand from Schema.org, OpenGraph, and Microdata — cross-checked for conflicts. |
🕵️ | Competitive intelligence | Track a competitor's tech stack, metadata, and product data over time by re-checking the same URL list. |
import requests
RAPIDAPI_KEY = "YOUR_RAPIDAPI_KEY"
HEADERS = {
"X-RapidAPI-Key": RAPIDAPI_KEY,
"X-RapidAPI-Host": "web-metadata-and-contact-extractor.p.rapidapi.com",
}
BASE = "https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/extract"
for url in ["shop-a.com", "shop-b.com", "shop-c.com"]:
data = requests.get(BASE, headers=HEADERS, params={"url": url}).json()
if "Shopify" in data["detected_technologies"] and data["seo_score_percentage"] < 60:
print(f"{url}: Shopify + {data['seo_score_percentage']}% SEO -> outreach candidate")import requests
def read_url_as_markdown(url: str) -> str:
"""Tool function an LLM agent can call to read any public webpage."""
resp = requests.get(
"https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/markdown",
headers={"X-RapidAPI-Key": "YOUR_KEY", "X-RapidAPI-Host": "web-metadata-and-contact-extractor.p.rapidapi.com"},
params={"url": url},
).json()
return resp["markdown_content"]Related MCP server: intercept-mcp
🌟 Key Features
Feature | Detail |
⚡ Ultra-Fast Performance | ~150–300ms live fetch. Powered by |
🧠 Adaptive SPA Byte Limit | Auto-detects React, Next.js, Vue, Angular, Nuxt, Svelte, Gatsby, Remix, Astro and expands download to 256 KB for richer data extraction. Static sites stay at 64 KB. |
🛡️ IP-Pinned Anti-SSRF Shield | DNS resolved once, IP validated against private/loopback/cloud-metadata ranges, connection pinned to IP with TLS SNI. Eliminates DNS Rebinding & Redirect SSRF. |
🎯 Rich SEO & OpenGraph Metadata | Title, Description, OG Image, OG Type, OG URL, OG Video, Favicon, Canonical URL, Language, Author, Theme Color, Robots directive, hreflang tags, H1 headings, image count. |
📧 Contact Extractor | Public emails and phone numbers with smart DOM cleaning to eliminate false positives. Phones are additionally normalized ( |
📲 Social Profile Finder | Auto-detects 20 platforms: Twitter/X, LinkedIn, Facebook, Instagram, GitHub, YouTube, Telegram, TikTok, Threads, Bluesky, Mastodon, Discord, Reddit, Pinterest, Medium, GitLab, Vimeo, Dribbble, Behance, Snapchat. |
🛠️ 40+ Tech Stack Detector | WordPress, Shopify, WooCommerce, Webflow, React, Next.js, Vue, Angular, Svelte, TailwindCSS, Stripe, GA4, and more across CMS/ecommerce, frameworks, and analytics/payment/hosting categories. |
📦 Schema.org JSON-LD + Product Parser | Parses all structured data schemas AND auto-extracts Product price, currency, availability, brand, rating and review count. |
🎯 Multi-Source Data Quality & Conflict Detection | Product price/currency/availability/brand are cross-checked across three distinct structured encodings — JSON-LD, OpenGraph's product extension, and schema.org Microdata. |
📊 On-Page SEO Health Audit Score | 14-point automated on-page technical SEO diagnostic (0–100%) with actionable warnings list, plus a structured |
🔗 Internal vs External Link Classifier | Categorizes up to 100 hyperlinks per page. |
🤖 AI & LLM Clean Markdown Reader | Converts article text to clean Markdown for ChatGPT, Claude, RAG, and AI agents. Includes word count and reading time. |
📡 RSS / Atom Feed Discovery | Auto-discovers RSS and Atom feed URLs. |
🔒 Graded Security Headers Audit | HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer Policy, Permissions Policy — each graded |
🚀 15-Min In-Memory Cache | Cached responses served in < 0.01 ms server-side processing time. |
⚡ Multi-Worker + Auto-Reconnect Redis |
|
🔒 Split | Minimal public liveness probe ( |
🧯 Per-Host Circuit Breaker | Trips after repeated timeouts/connection failures/5xx to one host, fails fast during the cooldown window instead of burning the full connect+read timeout budget on every request, and probes recovery automatically (never trips on ordinary 4xx). |
🧩 Request Single-Flight + DNS Coalescing | Concurrent requests for the same URL (or the same hostname's DNS lookup) share one in-flight fetch instead of hammering the origin N times. |
🩹 Negative-Result Cache | Short-TTL caching of recent upstream failures (DNS/timeout/5xx) so a broken target fails fast instead of repeating the same slow failure for every request during an outage. |
🧱 Adaptive Byte-Limit Hardening | Streaming byte cap is enforced on the decoded chunk, closing a decompression-bomb gap where a small gzip/br payload could otherwise expand to megabytes in a single read. Response headers are also count- and size-bounded. |
🏷️ Structured Error Codes | Every error response carries a machine-readable |
📈 Prometheus Metrics + Structured JSON Logs |
|
🧠 Confidence-Scored Tech Detection |
|
📦 Deeper Product & JSON-LD Parsing | Traverses |
🔎 Unicode-Aware SEO & Keywords | Keyword extraction now matches non-ASCII scripts correctly (accented/Cyrillic/etc. content), and the SEO audit adds |
⚡ Lazy Extraction Per Endpoint | Specialized endpoints only run the extractors they actually need instead of the full pipeline — |
🐘 Mastodon Social Detection | Best-effort detection of the largest public Mastodon instances (mastodon.social, fosstodon.org, hachyderm.io, ...) alongside the existing 20 platforms — decentralization means a hostname map can't cover every self-hosted instance, so this is intentionally partial rather than a false-positive risk. |
🚦 Rate-Limit Response Headers | Every response (success or |
🛡️ Bot-Protection Detection | Cheap heuristic signature check (no extra requests, no JS execution) flags when the fetched page is a Cloudflare/Akamai/PerimeterX/CAPTCHA challenge page rather than real content — either as |
🎯 Performance SLA & Technical Architecture Notes
Latency & Performance SLA: Server-side processing overhead (DOM cleaning, C-Lexbor parsing, Rust serialization) averages < 5ms. Live execution times depend on the target website's network latency and origin server response time. Repeating requests for the same URL hit the in-memory cache and return in < 0.01ms.
IPv6 & IPv4-Mapped SSRF Shield: The Anti-SSRF validation engine enforces strict resolution checks across both IPv4 and IPv6, blocking loopback (
127.0.0.1,::1), link-local (169.254.169.254,fe80::/10), and IPv4-mapped IPv6 (::ffff:127.0.0.1) addresses.Redis Rate Limiter (Fixed-Window, Auto-Reconnect): When
REDIS_URLis configured, rate limiting is distributed across all workers via a single atomic Redis Lua script (INCR+ first-hitEXPIREin one round-trip — no window where a dropped connection could leave a counter with no TTL). Redis is pinged at startup and re-validated every 30 seconds. On failure, the service falls back to per-process TTLCache immediately and marksredis_status: degraded_fallbackin/health/details.Split Health Endpoints:
/healthreturns a minimal public liveness payload./health/detailsreturns full operational status (Redis mode, trust_proxy, engine) and requires theX-Health-Secretheader whenHEALTH_DETAILS_SECRETenv var is set.Horizontal Scaling: Single-instance → in-memory TTLCache (60 req/min/IP). Multi-worker → distributed Redis. Enterprise scale → RapidAPI Gateway or Nginx.
Zero-Trust Self-Hosting: Full Dockerfile (uvicorn multi-worker) and test suite included for self-hosted production deployments.
Modular Codebase: The service is organized as an
app/package (security/,fetcher/,cache/,ratelimit/,extraction/,observability/,api/) rather than a single file —main.pyis a thin backward-compatibility shim souvicorn main:app/gunicorn main:appkeep working unchanged.Validated Configuration:
app/config.pyis backed bypydantic-settings— every tunable (rate limits, cache sizes/TTLs, byte-fetch limits, header limits, ...) is validated at startup with the exact same defaults as before, and now opportunistically overridable via env vars. An invalid value (negative sizes,STREAM_SOFT_LIMITaboveSTREAM_HARD_LIMIT, ...) fails immediately with a clear error instead of surfacing as a runtime bug later.Lazy Extraction:
/api/v1/extractwith nofields=runs the full pipeline. Specialized endpoints — and/api/v1/extract?fields=...— instead run only their required extractor groups — e.g./api/v1/securityskips HTML parsing entirely (headers-only),/api/v1/tech-stackskips metadata/links/markdown/SEO. Calling two different specialized endpoints (or field selections) for the same URL shares one upstream fetch and merges into one cache entry.Tech Signature Prefiltering: Each of the 40+ technology signatures is gated by a cheap substring check against a once-lowercased copy of the page before its regex ever runs, instead of running every regex unconditionally — same detection output, substantially less CPU on pages with many
<script>tags.Observability:
GET /metricsexposes Prometheus counters and latency histograms (requests, cache hit/miss, SSRF blocks, circuit-breaker trips, rate limiting, bytes downloaded, etc.) — open by default (standard Prometheus practice) but gate-able behindMETRICS_SECRET/X-Metrics-Secretif you're self-hosting with the port exposed to the internet and no reverse-proxy rule in front of it. All application logs are single-line JSON with arequest_idshared with theX-Request-IDresponse header, for correlating a request across logs and metrics.Property-Based Fuzz Testing: Hypothesis-driven tests generate hundreds of adversarial inputs per run against URL normalization, the SSRF IP-safety classification (every IPv4/IPv6 address, not just a fixed list), and every extractor that runs on attacker-controlled page content — asserting they never crash and the SSRF logic never lets a dangerous address through. This found and fixed two real bugs: a crafted
url=[query string could trigger an unhandled 500, and the embedded-credentials check (user:pass@host) could be bypassed by omitting the URL scheme.Real-World Accuracy Benchmark:
benchmarks/bench_accuracy.pyruns the real pipeline against a hand-curated, independently-verified sample of 29 live URLs across ecommerce/news/blogs/SaaS/SPA/WordPress/multilingual/small/bot-protected sites — seebenchmarks/README_ACCURACY.mdfor methodology and honest limitations. The first real run scored 61%: Brotli-compressed responses (common on modern CDN-fronted sites) were silently passed through undecoded and force-decoded as UTF-8, with no error raised anywhere —app/fetcher/client.pyadvertisedAccept-Encoding: brbut the decoder package wasn't installed. Addingbrotlitorequirements.txtfixed it with no other code change; the same 29-URL run now scores 100%, 0 unexpected errors.
🎯 What This API Is — And Isn't — For
This API turns a URL into structured knowledge about that page: SEO/OpenGraph metadata, public contact signals, social profiles, tech stack, Schema.org/product data, graded security headers, link classification, and clean Markdown — consolidated into one fast HTTP request. It's a metadata/intelligence layer over ordinary server-rendered HTML, not a general-purpose scraping tool or a browser-automation replacement. Keep that framing in mind when deciding whether it fits your use case.
✅ Good fit:
Company/website analysis — pull tech stack, CMS, socials, contact signals, and SEO health for a given site in one call.
Input for a sales/outreach workflow —
/api/v1/contactsfinds public emails/phones/social links present on a page; it's a raw signal you feed into a lead-gen process you build (company identification, role verification, CRM enrichment), not a lead-enrichment product by itself — see "Honest Limitations" below.Automated SEO audits — the 14-point on-page score, structured
seo_checksbreakdown, and graded security-header audit are built for exactly this.Competitive/tech-stack monitoring — compare tech stack, metadata, or product data across a known set of URLs over time. You supply and re-check the URL list; there's no built-in crawler (see below).
AI agents / RAG pipelines —
markdown_contentand the structured JSON fields are designed as clean LLM input, not raw HTML soup.E-commerce data extraction — product name/price/currency/availability/brand/SKU/reviews where a site exposes Schema.org JSON-LD, OpenGraph product tags, or Microdata, cross-checked with a per-field confidence score. Product responses use a short 3-minute cache specifically because price data goes stale faster than everything else.
Link previews — title, description, image, favicon for chat apps, social cards, and bookmarking tools.
❌ Not a good fit:
Complex/interactive scraping — logins, multi-step forms, button clicks, infinite scroll, CAPTCHA-gated content. This API issues one HTTP GET and parses the HTML it gets back; it does not drive a browser or simulate user interaction.
Heavily JS-rendered sites — if the meaningful content only exists after client-side hydration, this API sees close to the same empty shell a plain HTTP client would. The adaptive byte limit improves coverage of what the server already sent; it doesn't execute JavaScript.
Mass or distributed crawling — there's no queue, frontier, or "give me a domain and I'll find its pages" mode. It's one URL in, one page's data out, by design — kept stateless and fast rather than growing into a crawler.
Penetration testing or vulnerability scanning — the security-header audit grades the presence and quality of headers like HSTS, CSP, and X-Frame-Options. It does not probe for vulnerabilities, scan for misconfigurations beyond those headers, or constitute a security assessment. A high
security_scoremeans "this page sends good security headers," not "this site is secure.""Extract anything from any site" scraping — this is a fixed set of well-defined extractors (SEO, contacts, socials, tech, product, links, Markdown), not a programmable scraper for arbitrary custom fields or page structures.
For the technical reasoning behind these boundaries — why JS execution, crawling, and bot-protection bypass are out of scope, and what the confidence/quality scores do and don't mean — see "Honest Limitations" below.
⚠️ Honest Limitations
This API fetches raw HTTP responses and parses HTML — it is not a browser. That's a deliberate trade-off for speed (no browser startup, no JS execution wait, minimal memory per request), and it comes with real ceilings that no amount of additional regex or extractors can fully remove:
No JavaScript execution. Content that only exists after client-side rendering (many SPAs, some login-gated pages, content behind "load more" interactions) will be missing or incomplete. A static/SSR page (most blogs, e-commerce product pages, marketing sites, GitHub, Wikipedia) works great; a client-rendered single-page app whose initial HTML is just
<div id="root"></div>will return mostly empty results — the API cannot execute the JS that would fill it in.Detecting a JS framework doesn't mean the JS problem is solved. The adaptive byte limit (see below) expanding to 256 KB when React/Next.js/Vue/etc. signatures are spotted improves coverage of the initial HTML — it does not run a browser, execute hydration, or wait for client-side API calls.
Next.js -> more bytes -> a bigger parseis notNext.js -> Chromium -> JS execution -> hydration -> final DOM. Treat it as "we tried harder to read what the server already sent," not "we solved SPAs."Bot-protection / CAPTCHAs are detected, not bypassed.
bot_protection_detected(see above) tells you that Cloudflare/Akamai/PerimeterX/a CAPTCHA blocked the request — it does not solve the challenge. There is no workaround for this short of running a real browser.Extraction is heuristic evidence, not ground truth — including when it looks confident. Technology detection, contact info, social links, and product data are pattern/signature-based. A tech signature match (e.g. one CDN hostname in an image URL) proves the string was present somewhere the fetcher looked, not that the technology is meaningfully in use — it could be dead code, a shared/third-party asset, a transitive dependency, or an accidental substring.
technology_details.confidencereflects how many independent signals agreed, not a probability that the detection is correct. See the live GitHub example above, where"Contentful"is detected at0.75confidence from a single CDN hostname in anog:imageURL — plausible evidence, not proof GitHub runs on Contentful.A
quality.scorenear 1.0 means the evidence available to this API was internally consistent — not that the data is verified accurate. When JSON-LD, OpenGraph, and Microdata all report the same price, that's three encodings, not necessarily three independent sources — a site frequently generates all three from the same underlying product record, so agreement can mean "one data source, expressed three ways" rather than three independently-verified facts. Readconfidence: 0.98as "nothing on the page contradicts this," not "there's a 98% chance this is correct."The adaptive 64/256 KB byte limit is a real trade-off, not just a performance knob. It's what keeps typical requests fast, but it means content positioned late in a large page — JSON-LD placed near the closing
</body>, a product block far down a long CMS-generated page — can be missed purely because of where it sits in the HTML, independent of how "complex" the page seems. Larger/more script-heavy pages are paradoxically more likely to have relevant data pushed past the cutoff. Always checkquality.warningsfor aCONTENT_TRUNCATEDentry before treating a missing field as "this page doesn't have it" rather than "this API didn't read that far" — there's no separate top-levelcontent_truncatedboolean, that signal lives insidequality.Markdown conversion is not semantic understanding.
markdown_contentis a reasonably clean HTML→Markdown conversion, not a "read and understand what's actually the article" model — it doesn't reliably distinguish primary content from navigation, related-content widgets, paywalled teasers, or boilerplate on every layout.The cache trades freshness for speed, and that trade-off matters more for some fields than others. A 15-minute-stale
<title>is harmless; a 15-minute-stale price is not — which is why product-bearing responses get a separate, much shorter TTL (PRODUCT_CACHE_TTL_SECONDS, 3 minutes by default) rather than sharing the general 15-minute cache. Everything else still follows the general TTL: don't build a real-time price-monitoring product directly on the general cache path without accounting for that window.Arbitrary URL fetching is inherently unreliable, independent of this API: pages can be slow, redirect repeatedly, be enormous, block automated clients, have TLS quirks, serve different content by geography/User-Agent, be temporarily down, or return unexpected status codes. SSRF protections, timeouts, redirect limits, byte caps, and the circuit breaker (see above) bound the damage but can't make an unreliable target reliable.
"~150–300ms" describes the live-fetch network leg, not a ceiling on total response time. Server-side processing genuinely is single-digit milliseconds (see the benchmark methodology in
benchmarks/), but the live end-to-end time is dominated by however long the target site takes to respond — if the target takes 2.5s, so does your request. Don't read the headline numbers as "this API responds in 200ms regardless of target."There is no crawler. The unit of work is one URL in, one page's data out — not "give me a domain and I'll discover/prioritize/crawl its pages for you."
/api/v1/linksclassifies up to 100 hyperlinks on the page you gave it; it doesn't follow them. Analyzing a whole site (homepage +/about+/pricing+/blog, deduplicated, prioritized, crawled) is something you'd orchestrate externally, one/extractcall per URL — this project deliberately doesn't grow a queue/worker/crawl-frontier system into what's meant to stay a fast, stateless per-request API./api/v1/contactsfinds public contact signals, not company or people intelligence. It returns emails/phones/social links it found in the page's HTML — it does not identify who those belong to, their role, or verify anything. Turningwebsite -> public contact signalsinto real lead enrichment (domain -> company identification -> people -> roles -> verification -> confidence) is out of scope here; the endpoint is intentionally named/tagged "Contact Discovery," not "Lead Enrichment," to avoid implying more than it does.Prefer the specific endpoint over
/api/v1/extract— or usefields=./extractwithoutfieldsruns the complete pipeline./extract?fields=detected_technologiesnow runs exactly the same narrow extraction asGET /api/v1/tech-stack(and shares its cache entry) —fieldsgenuinely skips unneeded work rather than computing everything and filtering afterward.This project's API surface is still evolving. New fields ship frequently (
quality,product_field_confidence,bot_protection_detected, and others were all added recently) — additive changes only, existing fields never change type (see the versioning notes below), but if you're integrating deeply, treat the live/openapi.jsonschema as the source of truth over any single README snippet, which can lag by a commit or two.
None of this means the underlying approach is flawed for its intended job (fast metadata/SEO/contact/tech extraction from ordinary web pages) — it means "extract everything from any URL via one HTTP request" has a ceiling that only browser automation (Playwright/Puppeteer) can raise, at the cost of the speed and low resource footprint that make this API fast in the first place.
⚡ Quick Start
Python
import requests
url = "https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/extract"
headers = {
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY_HERE",
"X-RapidAPI-Host": "web-metadata-and-contact-extractor.p.rapidapi.com"
}
params = {"url": "https://github.com"}
data = requests.get(url, headers=headers, params=params).json()
print(f"Title: {data['metadata']['title']}")
print(f"OG Type: {data['metadata']['og_type']}")
print(f"Robots: {data['metadata']['robots']}")
print(f"hreflang: {data['metadata']['hreflang_tags']}")
print(f"Product: {data['product_data']}")
print(f"Emails: {data['contacts']['emails']}")
print(f"Tech Stack: {data['detected_technologies']}")
print(f"Time: {data['execution_time_ms']} ms")JavaScript / Node.js
const url = 'https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/extract?url=https%3A%2F%2Fgithub.com';
const response = await fetch(url, {
headers: {
'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY_HERE',
'X-RapidAPI-Host': 'web-metadata-and-contact-extractor.p.rapidapi.com'
}
});
const data = await response.json();
console.log('Title:', data.metadata.title);
console.log('OG Type:', data.metadata.og_type);
console.log('Product:', data.product_data);
console.log('Time:', data.execution_time_ms, 'ms');cURL
curl --request GET \
--url 'https://web-metadata-and-contact-extractor.p.rapidapi.com/api/v1/extract?url=https%3A%2F%2Fgithub.com' \
--header 'X-RapidAPI-Host: web-metadata-and-contact-extractor.p.rapidapi.com' \
--header 'X-RapidAPI-Key: YOUR_RAPIDAPI_KEY_HERE'🤖 MCP / AI Agent Support
This API is available as an MCP server out of the box, via RapidAPI's hosted gateway — no extra setup or self-hosting needed. Add it to Claude Desktop, Claude Code, Cursor, or any MCP-compatible client:
{
"mcpServers": {
"RapidAPI Hub - Web Metadata and Contact Extractor": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.rapidapi.com",
"--header",
"x-api-host: web-metadata-and-contact-extractor.p.rapidapi.com",
"--header",
"x-api-key: YOUR_RAPIDAPI_KEY_HERE"
]
}
}
}Once connected, an agent can call the extractor directly as a tool — e.g. pulling markdown_content into a RAG pipeline, or checking detected_technologies and seo_score_percentage as part of an autonomous research/outreach workflow. Get a free key from the RapidAPI listing first.
📊 Sample API Response (JSON)
This isreal, live output from GET /api/v1/extract?url=https://github.com, captured 2026-08-11 — not a hand-edited illustration. It's deliberately left un-prettified, including the parts that aren't flattering: detected_technologies includes "Contentful" on a page that almost certainly isn't Contentful-powered (see technology_details below — the evidence is one CDN hostname in an og:image URL, hence only 0.75 confidence, not 0.98), and markdown_content/word_count come back empty because GitHub's homepage is a JS-heavy shell whose initial HTML has no <article>-like content for this API to find. Both are the "Honest Limitations" section below in action, not this example glossing over them. social_links has 20 keys total (see the Key Features table above); only non-null ones are worth reading, so it's trimmed here for length — the real response includes all 20.
{
"url": "https://github.com",
"final_url": "https://github.com",
"status_code": 200,
"execution_time_ms": 130.43,
"bot_protection_detected": false,
"metadata": {
"title": "GitHub · Change is constant. GitHub keeps you ahead. · GitHub",
"description": "Join the world's most widely adopted, AI-powered developer platform where millions of developers, businesses, and the largest open source community build software that advances humanity.",
"og_image": "https://images.ctfassets.net/8aevphvgewt8/4pe4eOtUJ0ARpZRE4fNekf/f52b1f9c52f059a33170229883731ed0/GH-Homepage-Universe-img.png",
"og_type": "object",
"canonical_url": "https://github.com",
"language": "en",
"favicon": "https://github.githubassets.com/favicons/favicon.svg",
"theme_color": "#1e2327",
"hreflang_tags": [
{"lang": "en-us", "url": "https://github.com"},
{"lang": "pt-br", "url": "https://github.com?locale=pt-br"}
],
"h1_tags": [],
"links_count": 51,
"content_length_bytes": 109075
},
"social_links": { "github": "https://github.com/features/copilot", "twitter": null, "linkedin": null, "...": "17 more platforms, all null here" },
"contacts": { "emails": [], "phones": [] },
"detected_technologies": ["Contentful"],
"technology_details": [
{ "name": "Contentful", "confidence": 0.75, "evidence": ["ctfassets.net"], "category": "cms" }
],
"product_data": null,
"quality": {
"score": 0.85,
"rendered": false,
"sources_used": ["meta"],
"warnings": [{ "field": null, "type": "CONTENT_TRUNCATED" }]
},
"rss_feeds": ["https://github.com/opensearch.xml", "https://github.githubassets.com/favicons/favicon.svg"],
"json_ld_schemas": [],
"security_score_percentage": 64.2,
"seo_score_percentage": 75.0,
"seo_passed_checks": ["Title tag present with optimal length (10-70 chars)", "Canonical link tag present", "OpenGraph image present for social sharing", "Favicon icon present"],
"seo_warnings": ["Meta description present but sub-optimal length (186 chars)", "Missing <h1> primary heading", "No structured data (JSON-LD) found"],
"internal_links": ["https://github.com/", "https://github.com/login", "https://github.com/features/copilot"],
"total_internal_count": 44,
"total_external_count": 5,
"word_count": 0,
"reading_time_minutes": 0.0,
"markdown_content": ""
}This response is exactly
MetadataResponse(app/models/responses.py) serialized, trimmed for length — every field shown above is real. Four model fields aren't shown:phone_detailsandproduct_field_confidence(both empty here — no phone numbers orproduct_dataon this page),seo_checks(the structured, per-check version of theseo_passed_checks/seo_warningsalready shown above), andexternal_links(5 URLs, pertotal_external_count, omitted the same wayinternal_linksis truncated). There's no separatecontent_truncated/bytes_downloadedat the top level; that signal lives insidequality.warnings.
Since v4.0.0,
metadataalso includesviewport,twitter_card, andh1_count;/api/v1/tech-stackadditionally returnstechnology_details(confidence score, matched evidence, category per technology); andproduct_data(when present) includessku,mpn,gtin/isbn,seller,condition, and price-range fields. All additions are purely additive — no existing field was removed or changed type. Fields that were previously untypedDict/List[Dict]blobs (metadata,technology_details,seo_checks,phone_details) now have documented Pydantic models in the OpenAPI schema — withproduct_data, previously missing from/api/v1/extractdespite being shown here, now actually returned. Also new:product_field_confidenceand a top-levelqualityobject — e.g. for a page where JSON-LD says €39.99 and OpenGraph says €29.99:"product_field_confidence": {"price": {"value": "39.99", "confidence": 0.5, "source": "json_ld", "agreement": ["json_ld", "microdata", "opengraph"]}}and"quality": {"score": 0.9, "rendered": false, "sources_used": ["json_ld", "microdata", "opengraph", "meta"], "warnings": [{"field": "product.price", "type": "SOURCE_CONFLICT", "values": {"json_ld": "39.99", "microdata": "39.99", "opengraph": "29.99"}, "chosen_source": "json_ld", "chosen_value": "39.99"}]}.
📖 API Endpoint Documentation
Endpoint | Method | Description |
|
| Full payload — SEO, contacts, social, tech stack, schema, security, AI markdown, SEO audit, links, product data. Supports |
|
| Social link preview card — title, description, OG image, favicon, site name, language. |
|
| Contact discovery — public emails, phone numbers, social profiles found on the page (a raw signal for lead-gen workflows, not lead enrichment itself — see "Honest Limitations"). |
|
| Framework & CMS detector — 40+ technology signatures. |
|
| Schema.org JSON-LD parser — product prices, articles, events, organizations. |
|
| Security headers audit — HSTS, CSP, X-Frame-Options, Referrer Policy with percentage score. |
|
| AI & LLM Markdown reader — clean article text, word count, reading time. |
|
| Automated SEO diagnostic — 14-point audit score with warnings list plus structured |
|
| Link classifier — internal vs external hyperlinks (up to 100 per page). |
|
| Health check — status, version, protection mode. |
|
| Operational health — Redis mode/status, trust-proxy config. Requires |
|
| Readiness probe — 200 once the HTTP client is initialized, 503 during startup. |
|
| Prometheus scrape target — request/cache/SSRF/circuit-breaker/rate-limit counters and latency histograms. Open by default (protect at the network/proxy level, standard Prometheus practice) — set |
Query Parameters
Parameter | Type | Required | Description |
|
| Yes | Target URL (e.g. |
|
| No | Comma-separated response filter (e.g. |
|
| No | Custom User-Agent header string. |
🔧 Self-Hosting & Local Development
# 1. Clone
git clone https://github.com/JosejuX/rapidapi-metadata-extractor.git
cd rapidapi-metadata-extractor/rapidapi_service
# 2. Install
pip install -r requirements.txt
# 3. Fixture-based test suite (SSRF matrix, circuit breaker, single-flight, rate-limit atomicity, ...)
pip install pytest
pytest tests/ -q
# 3b. Live-network smoke suite (14 SSRF vectors + 12 global domains)
python test_api.py
# 4. Load test (concurrent requests benchmark)
python load_test.py
# 5. Dev server
uvicorn main:app --reload --port 8000Open http://localhost:8000/docs for the interactive Swagger UI.
Docker
# Pull the published image (built + pushed by .github/workflows/docker-publish.yml on every version tag)
docker pull ghcr.io/josejux/rapidapi-metadata-extractor:latest
docker run -p 8000:8000 ghcr.io/josejux/rapidapi-metadata-extractor:latest
# Or build it yourself
cd rapidapi_service
docker build -t rapidapi-metadata-extractor .
docker run -p 8000:8000 rapidapi-metadata-extractor🏷️ Keywords
metadata-extractor • opengraph-parser • email-scraper • contact-extractor • social-links-finder • tech-stack-detector • seo-parser • fastapi • rapidapi • python-web-scraper • link-preview-generator • lead-generation-api • hreflang • schema-org • product-data-extractor • ssrf-protection
🤝 Built With
This API was built and iterated on in collaboration with AI coding assistants — Google's Gemini 3.6 Flash and Anthropic's Claude Sonnet 5 — alongside human design, review, and testing decisions throughout.
📄 License
Distributed under the MIT License. See LICENSE for more information.
This server cannot be installed
Maintenance
Related MCP Servers
- Alicense-qualityFmaintenanceEnables fetching and processing web content with advanced features including batch processing of up to 20 URLs, streaming support, metadata extraction, and multiple output formats (HTML, Markdown, plain text) with enterprise-grade security and global edge performance.MIT
- AlicenseAqualityBmaintenanceGive your AI the ability to read the web. Fetches URLs as clean markdown with 9 fallback strategies.2739MIT
- AlicenseAqualityDmaintenanceConverts URLs and raw HTML to clean Markdown, enabling AI assistants to read web pages for summarization, analysis, or ingestion.2171MIT
- Alicense-qualityCmaintenanceConverts any URL into clean, LLM-ready Markdown, text, or HTML with production-grade features like SSRF protection, rate limiting, retries, caching, and structured error handling.MIT
Related MCP Connectors
Read any web page as clean Markdown for AI agents: fetch, search, metadata, links. SSRF-safe.
Web scraping for AI agents. Converts URLs to clean, LLM-ready Markdown with anti-bot bypass.
Fetch any URL and get clean Markdown. Web scraping for AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/JosejuX/rapidapi-metadata-extractor'
If you have feedback or need assistance with the MCP directory API, please join our Discord server