Dev.to WebDev 🛠 Dev 👁 0 📖 3 min read

How to audit a website's SEO and JSON-LD with a single API call

Checking a page's SEO usually means opening five different tools: one for the title and meta description, another for Open Graph tags, another for canonicals and indexability, another for the sitemap, and yet another to

How to audit a website's SEO and JSON-LD with a single API call

 Checking a page's SEO usually means opening five different tools: one for the title and meta description, another for Open Graph tags, another for canonicals and indexability, another for the sitemap, and yet another to validate JSON-LD.

I got tired of that, so I built PageSignal: an API that audits any public URL in a single request and returns an explainable report, so you know not just what failed but why.

What it checks

  • Title and meta description: length, and duplicate tags on the same page
  • Open Graph and Twitter Card tags: and which recommended ones are missing
  • Indexability: meta robots, googlebot and the X-Robots-Tag header combined into one verdict
  • Canonical URL: missing, empty, duplicated, self-referencing or pointing elsewhere
  • robots.txt and XML sitemap discovery
  • JSON-LD: every block parsed and validated, with its schema types
  • Headings, image ALT coverage, internal and external links
  • A 0–100 score where every rule shows its points, severity and the reason

Try it without signing up

There's a live demo where you paste a URL and get the score and the top issues to fix:

👉 https://pagesignal.alorenzom.com/demo

Or straight from your terminal, no key needed (3 checks per day):

curl -s https://pagesignal.alorenzom.com/demo/api/audit \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com/"}'

The demo returns a summary. The full API returns the complete report — here's a real, unedited one for python.org.

Call the full API

With a free RapidAPI key:

curl --get 'https://pagesignal-seo-audit-metadata-json-ld-validator.p.rapidapi.com/v1/audit' \
  --data-urlencode 'url=https://www.python.org/' \
  -H 'X-RapidAPI-Host: pagesignal-seo-audit-metadata-json-ld-validator.p.rapidapi.com' \
  -H "X-RapidAPI-Key: $RAPIDAPI_KEY"

Example output

This is a trimmed, real response for https://www.python.org/:

{
  "success": true,
  "network": {
    "final_url": "https://www.python.org/",
    "status_code": 200,
    "response_time_ms": 113,
    "redirect_count": 0
  },
  "quality_score": {
    "score": 68,
    "grade": "C",
    "errors_count": 1,
    "warnings_count": 4,
    "breakdown": [
      {
        "rule_id": "title_check",
        "severity": "warning",
        "max_points": 15,
        "points_impact": -6,
        "message": "Your title is shorter than recommended (30–60 characters). Consider adding primary keywords or brand context."
      },
      {
        "rule_id": "xml_sitemap_check",
        "severity": "error",
        "max_points": 10,
        "points_impact": -10,
        "message": "No XML sitemap was detected at common locations."
      }
    ]
  },
  "diagnostics": { "http_ok": true, "likely_client_rendered": false, "notes": [] },
  "title": { "status": "warning", "value": "Welcome to Python.org", "length": 21 },
  "indexability": { "status": "healthy", "is_indexable": true, "raw_directives": "index, follow" },
  "canonical": { "status": "warning", "is_present": false, "badge": "Missing" },
  "structured_data": {
    "status": "healthy",
    "blocks_detected": 1,
    "valid_blocks": 1,
    "invalid_blocks": 0,
    "blocks": [{ "schema_types": ["WebSite"], "errors": [] }]
  }
}

Every point lost comes with a message, so you can show your users exactly what to fix instead of a bare number.

Fail your CI build when SEO breaks

Here's a small script that audits a list of URLs and exits with code 1 if any page breaks a rule you care about. Save it as seo-check.mjs (Node 18+, no dependencies):


js
// seo-check.mjs: audits a list of URLs and exits with code 1 if any of them
// breaks a rule you care about, so it can stop a CI pipeline.
const HOST = 'pagesignal-seo-audit-metadata-json-ld-validator.p.rapidapi.com';
const KEY = process.env.RAPIDAPI_KEY;
const MIN_SCORE = 60;

const urls = process.argv.slice(2);
if (!KEY || urls.length === 0) {
  console.error('Usage: RAPIDAPI_KEY=your_key node seo-check.mjs <url> [more urls...]');
  process.exit(2);
}

let failed = false;

for (const url of urls) {
  const res = await fetch(`https://${HOST}/v1/audit?url=${encodeURIComponent(url)}`, {
    headers: { 'X-RapidAPI-Host': HOST, 'X-RapidAPI-Key': KEY },
  });
  const report = await res.json();

  if (!res.ok) {
    console.log(`✖ ${url}: ${report.error?.code ?? `HTTP ${res.status}`}`);
    failed = true;
    continue;
  }

  const { quality_score, indexability, canonical, structured_data } = report;
  const problems = [];
  if (quality_score.score < MIN_SCORE) problems.push(`score ${quality_score.score} is below ${MIN_SCORE}`);
  if (!indexability.is_indexable) problems.push('page is not indexable');
  if (!canonical.is_present) problems.push('canonical tag is missing');
  if
📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.