The MetaSnap
Developer API

Free REST endpoints for meta tag scraping, deep SEO audits, and broken-link detection. No signup, no API key, no rate limits — just POST { "url": "..." }.

No auth required CORS enabled JSON in/out 4 endpoints
POST /api/scrape POST /api/audit POST /api/audit-links GET /api/download

Quick start

Send a single POST request and get structured JSON back. Works in any language with an HTTP client.

30-second example
curl -X POST https://metasnap.vercel.app/api/scrape \
  -H "Content-Type: application/json" \
  -d '{"url":"https://github.com"}'
POST /api/scrape

Quick meta-tag scrape

Fetches a URL, parses the HTML, and returns every relevant meta tag — title, description, Open Graph, Twitter Card, favicon — in a clean JSON shape. Use this for previews or to build your own meta tag inspector.

Request body

Field Type Required Description
url string Yes Any HTTP/HTTPS URL. Protocol is auto-prefixed if missing.

Response shape

application/json
{
  "title": "string",
  "description": "string",
  "ogTitle": "string",
  "ogDescription": "string",
  "ogImage": "string (absolute URL)",
  "ogUrl": "string",
  "ogType": "string",
  "ogSiteName": "string",
  "twitterCard": "string",
  "twitterTitle": "string",
  "twitterDescription": "string",
  "twitterImage": "string",
  "twitterSite": "string",
  "favicon": "string (absolute URL)",
  "url": "string (final URL after redirects)",
  "domain": "string"
}

Try it live

POST
Samples:

Code samples

bash
curl -X POST https://metasnap.vercel.app/api/scrape \
  -H "Content-Type: application/json" \
  -d '{"url":"https://github.com"}'
javascript (browser)
const res = await fetch("https://metasnap.vercel.app/api/scrape", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://github.com" }),
});
const meta = await res.json();
console.log(meta.ogImage);
python
import httpx

resp = httpx.post(
    "https://metasnap.vercel.app/api/scrape",
    json={"url": "https://github.com"},
)
meta = resp.json()
print(meta["ogImage"])
node.js (fetch)
const meta = await fetch("https://metasnap.vercel.app/api/scrape", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://github.com" }),
}).then(r => r.json());

console.log(`Title: ${meta.title}`);
console.log(`OG Image: ${meta.ogImage}`);
POST /api/audit

Deep SEO audit

Runs 15+ checks (title length, meta description, OG image, canonical, JSON-LD, viewport, robots, h1, and more), computes a 0–100 score with a letter grade, generates smart title/description suggestions, and returns a copy-paste optimised meta tag bundle.

Request body

Field Type Required Description
url string Yes The URL to audit.

Response shape

application/json
{
  "meta": { /* same shape as /api/scrape */ },
  "score": 87,
  "grade": "B",
  "summary": "Good — a few small tweaks will polish it.",
  "checks": [
    {
      "label": "Title length",
      "status": "pass | warn | fail",
      "detail": "57 chars",
      "tip": "Optional fix suggestion"
    }
    /* ...15+ entries */
  ],
  "suggestions": {
    "title": "Optimised <= 60 char suggestion",
    "description": "Optimised <= 160 char suggestion"
  },
  "bundle": "<!-- Primary Meta Tags -->..."
}

Try it live

POST
Samples:

Code samples

bash
curl -X POST https://metasnap.vercel.app/api/audit \
  -H "Content-Type: application/json" \
  -d '{"url":"https://stripe.com"}'
javascript
const audit = await fetch("https://metasnap.vercel.app/api/audit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://stripe.com" }),
}).then(r => r.json());

console.log(`Score: ${audit.score} (${audit.grade})`);
audit.checks
  .filter(c => c.status !== "pass")
  .forEach(c => console.log(`- ${c.label}: ${c.tip}`));
python
import httpx

audit = httpx.post(
    "https://metasnap.vercel.app/api/audit",
    json={"url": "https://stripe.com"},
    timeout=20,
).json()

print(f"Score: {audit['score']} ({audit['grade']})")
for check in audit["checks"]:
    if check["status"] != "pass":
        print(f"- {check['label']}: {check['tip']}")
GET /api/download?url=<image-url>

Image proxy / CORS bypass

Proxies image downloads (OG images, favicons) so you can save them client-side without CORS issues. Returns the raw image bytes with the original Content-Type and a Content-Disposition: attachment header.

Query parameters

Field Type Required Description
url string Yes The image URL to fetch.

Code samples

html
<a href="/api/download?url=https://github.com/og-image.png" download>
  Download OG image
</a>
javascript
const target = "https://github.com/og-image.png";
const res = await fetch(`/api/download?url=${encodeURIComponent(target)}`);
const blob = await res.blob();
const url = URL.createObjectURL(blob);

const a = document.createElement("a");
a.href = url;
a.download = "og-image.png";
a.click();
URL.revokeObjectURL(url);
bash
curl -L -o og.png \
  "https://metasnap.vercel.app/api/download?url=https://github.com/og-image.png"

Errors

All endpoints return JSON with a detail field on failure.

Status Meaning Example
400 Bad request {"detail": "URL is required"}
500 Fetch failed (network, DNS, TLS, target 4xx/5xx, etc.) {"detail": "Fetch failed: ..."}

Built it? We'd love to hear about it.

The MetaSnap API powers everything you see on this site. Use it freely in your own dashboards, CLIs, browser extensions, or CI checks.