Build an automated SEO audit with two APIs

Two calls give you every on-page signal that matters. The interesting work is deciding which of them should fail a build, and which are noise.

Most SEO regressions are not strategy failures. Someone ships a template change and every product page loses its meta description. A staging noindex survives the deploy. A redesign wraps the logo in an <h1> and the real heading becomes the second one. Nobody notices for three weeks, because nobody looks at the <head> of a page they can already see rendered.

Those are exactly the problems a machine is good at catching. You do not need a crawler or a headless browser for them; you need the page's metadata and a handful of structural counts, checked against rules you wrote down. Two catalog APIs return that data, and this lesson turns them into an audit that runs from a script, a CI job or a cron schedule.

What each API sees

SEO Data Scraper (seoscraper) reads a URL and returns what the page declares about itself: the <title>, the meta description, Open Graph and Twitter card tags, the robots meta tag, the viewport and the charset. It is a POST with a JSON body containing url, and it costs 10 credits.

Try it liveSEO Data Scraper10 credits
POSThttps://api.apiverve.com/v1/seoscraper
curl -X POST "https://api.apiverve.com/v1/seoscraper" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'
Sign in or create a free account to run this with your own key.

title is set, but description, robots and every og: field come back as empty strings.

Look at what came back for example.com. The title is Example Domain. Everything else that the page does not declare is an empty string, not null and not missing. That matters for your code: if (data.description) works, if (data.description !== null) silently passes a page with no description at all.

Also notice the key names. The scraper returns social tags under their literal attribute names, og:title, twitter:card and so on. In JavaScript that means data['og:title'], not data.og.title. In Python it is an ordinary dict key.

SEO Quick Validator (seovalidator) answers a different question: not "what does the page say" but "what is structurally wrong with it". It is also a POST with url, also 10 credits.

Try it liveSEO Quick Validator10 credits
POSThttps://api.apiverve.com/v1/seovalidator
curl -X POST "https://api.apiverve.com/v1/seovalidator" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'
Sign in or create a free account to run this with your own key.

checks.h1Count is 0 and hasCanonical is false. The issues array explains each failure in words.

The useful part of this response is the checks object. When we ran it against example.com it reported:

CheckValueReading
hasTitle / titleLengthtrue / 14Title exists but is short
hasMetaDescription / metaDescriptionLengthfalse / nullNo description; length is null when absent
h1Count0No H1 at all
hasCanonicalfalseNo canonical link tag
hasViewporttrueMobile viewport declared
imagesTotal / imagesMissingAlt0 / 0Nothing to check
externalLinksTotal / externalLinksMissingRel1 / 1One external link without rel

Alongside checks you get passed, issueCount and an issues array of plain-English strings. Paid plans also get seoScore (0-100) and a letter grade.

So between them: the scraper gives you the content of the tags, the validator gives you counts and presence flags, including the heading structure the scraper does not report. A useful audit needs both, because "has a title" and "the title is the same on all 400 product pages" are different failures.

Check yourself

Your audit code checks `if (seo.description === null) flag('missing description')`. A page with no meta description passes. Why?

Answer the check above to continue.

Run every example on your own key. Free plan, no card.

Scaling up?

Volume pricing, custom SLAs, and dedicated support for high-traffic teams.

Contact sales