SEO Audit Tool: Title, Meta, Schema, Robots, Sitemap avatar

SEO Audit Tool: Title, Meta, Schema, Robots, Sitemap

Pricing

from $80.00 / 1,000 audited pages

Go to Apify Store
SEO Audit Tool: Title, Meta, Schema, Robots, Sitemap

SEO Audit Tool: Title, Meta, Schema, Robots, Sitemap

SEO audit for any URL or whole site: crawl mode finds redirect chains, broken links, duplicate titles; page mode checks title/meta, headings, schema, robots.txt, sitemap, canonical. Machine-readable JSON with a pre-sorted fix list. $0.10 per page audited, failures free.

Pricing

from $80.00 / 1,000 audited pages

Rating

0.0

(0)

Developer

Broke to Built

Broke to Built

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Share

Website SEO Audit — crawl a whole site, get a prioritized fix list

Point it at your homepage. It crawls the site, finds what's costing you rankings, and hands back a fix list ordered by impact — not a wall of data you have to interpret.

Two modes, one actor:

  • Site audit — crawls up to 500 pages, follows internal links, finds problems that only exist between pages: redirect chains, broken links, duplicate titles and descriptions, missing sitemap or robots.txt.
  • Single page — audit one URL, or a list of URLs, for a fast on-page check.

No API key. No signup. Pay per page audited — nothing charged for pages that fail to load.


What it finds

Site-wide (site mode only — a single-page tool structurally cannot see these)

  • Redirect chains that leak link equity, with every hop listed
  • Broken internal links and broken outbound links, with the page each one sits on
  • Duplicate titles and duplicate meta descriptions across pages, with the exact URLs
  • Missing or unreachable robots.txt and sitemap.xml
  • Pages returning 4xx/5xx or unreachable entirely

Per page

  • Title and meta description — presence, length, truncation risk
  • Heading structure — <h1> count, <h2> count
  • Canonical link, noindex traps, HTTPS
  • Images missing alt text, with counts
  • Structured data (JSON-LD) blocks that fail to parse
  • Word count and thin-content flag
  • Response time, HTTP status
  • Tech detected — WordPress, Next.js, Shopify, Wix, Astro, Squarespace, generator meta
  • SEO score 0–100 with the issues that produced it

Input

Site audit:

{ "mode": "site", "startUrl": "https://example.com", "maxPages": 100 }

Single page, or a list:

{ "url": "https://example.com" }
{ "urls": ["https://a.com", "https://b.com"], "maxPages": 25 }
FieldTypeDefaultNotes
mode"site" | "page""page""site" crawls; "page" audits given URLs only
startUrlstringWhere the crawl begins (site mode)
url / urlsstring / arraySingle or multiple URLs (page mode)
maxPagesinteger25Hard cap, max 500
checkOutboundLinksbooleantrueHEAD-checks external links for 404s

Output

Page mode pushes one record per page. Site mode pushes one record per page plus a final SITE_SUMMARY record.

Example 1 — one page, real output

Input:

{ "mode": "page", "url": "https://broke2builtai.com" }

Result, copied from an actual run:

{
"url": "https://broke2builtai.com",
"status": 200,
"responseMs": 424,
"seoScore": 89,
"title": "Broke to Built — a company of machines that gives away what it builds",
"titleLength": 69,
"metaDescription": "One operator and a fleet of AI agents that publish, moderate, audit and repair on their own [...]",
"descriptionLength": 259,
"h1Count": 1,
"h2Count": 11,
"canonical": "https://broke2builtai.com/",
"wordCount": 1356,
"images": 0,
"imagesMissingAlt": 0,
"structuredDataBlocks": 2,
"structuredDataErrors": 0,
"techDetected": ["Astro"],
"issues": [
{ "sev": "warn", "msg": "Title is 69 chars — Google truncates near 60" },
{ "sev": "note", "msg": "Description is 259 chars — will be truncated" }
],
"summary": "89/100 — 2 issue(s)",
"redirectHops": []
}

That is a $0.10 run. Two real, fixable findings and a score you can track over time. The score starts at 100 and subtracts 25 per critical, 8 per warning and 3 per note — so it is a transparent arithmetic of the issues list, not an opinion.

Example 2 — a whole site

Input:

{ "mode": "site", "startUrl": "https://example.com", "maxPages": 100 }

100 per-page records like example 1, then one summary record:

{
"type": "SITE_SUMMARY",
"site": "https://example.com",
"pagesAudited": 100,
"averageSeoScore": 78,
"issueCounts": { "critical": 2, "warn": 14, "note": 31 },
"siteWideIssues": [
{ "sev": "warn", "msg": "Duplicate title on 6 pages: \"Home | Example\"", "url": "..." }
],
"worstPages": [ { "url": "...", "seoScore": 41, "topIssue": "No <title> element" } ],
"fixOrder": [ "…up to 25 issues, criticals first" ],
"summary": "100 pages · avg 78/100 · 2 critical, 14 warnings, 31 notes"
}

worstPages holds the ten lowest scores, and fixOrder is the work queue: up to 25 issues already sorted criticals-first, so nobody has to triage a spreadsheet.

Example 3 — a page that will not load

{ "url": "https://example.com/gone", "error": "HTTP 404", "redirectHops": [] }

The run continues and that page is not charged.

Every issue carries sev (critical / warn / note), a plain-English msg, and the exact url it was found on — so results are directly actionable without a second pass.


Call it from code

curl — synchronous run, findings straight back:

curl -X POST "https://api.apify.com/v2/acts/eliai~website-seo-tech-auditor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode":"site","startUrl":"https://example.com","maxPages":50}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("eliai/website-seo-tech-auditor").call(
run_input={"mode": "site", "startUrl": "https://example.com", "maxPages": 50}
)
for rec in client.dataset(run["defaultDatasetId"]).iterate_items():
if rec.get("type") == "SITE_SUMMARY":
for step in rec["fixOrder"]:
print(step)

Node.js (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('eliai/website-seo-tech-auditor').call({ url: 'https://example.com' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].seoScore, items[0].issues);

For agents and automation

Deterministic and side-effect free: given the same site it returns the same findings, writes nothing anywhere, and requires no credentials. Callable as a tool over Apify MCP.

  • Capability: technical SEO audit of a website or of specific URLs
  • Required input: one URL (startUrl for a crawl, url/urls for specific pages)
  • Returns: structured JSON per page; in site mode also one SITE_SUMMARY with fixOrder already sorted by severity
  • Bounded: maxPages caps the run; the crawl stays on the starting origin
  • Failure mode: unreachable pages are reported as records with an error field and are not charged — the run does not abort

Pricing

Pay per event, one event: page-audited.

EventWhat one event coversPrice
page-auditedOne page fetched and fully audited: on-page SEO, redirect chain, link checks, structured data, plus its contribution to site-wide duplicate and broken-link detection$0.10

A single-page check costs $0.10. A 50-page crawl costs $5.00. A full 500-page crawl costs $50.00 — set maxPages deliberately, because it is both your crawl cap and your spend cap. Pages that fail to load are never charged, the SITE_SUMMARY record is free, and there is no start fee or monthly fee.

Honest framing: this is not the cheapest thing on the store, and it should not be your choice for a one-off look at one page — a browser extension or Google's own free tools will do that. What $0.10 a page buys is the between-pages layer (duplicate titles across the whole site, redirect chains with every hop, broken internal and outbound links attributed to the page they sit on) delivered as machine-readable JSON with a pre-sorted fixOrder. Start with maxPages: 25 on your most important section before you crawl 500.

When NOT to use this

  • You want one free check of one page. Use Lighthouse, Google Search Console, or a browser extension. Paying $0.10 for a single URL only makes sense inside an automated pipeline.
  • You want Core Web Vitals, performance scores, or rendering metrics. responseMs is the only speed number here. This is a technical-SEO linter, not a performance profiler.
  • Your site is client-rendered. Pages are read as the server sends them; no JavaScript is executed. A React or Vue app that ships an empty shell will audit as thin content.
  • You need backlinks, keyword volumes, rank tracking, or competitor data. None of that is here — this looks only at the pages you point it at.
  • You need to crawl across subdomains or several sites in one run. A site crawl stays on the starting origin. Use page mode with an explicit list instead.
  • The site is behind a login or bot protection. No credentials and no proxy: those pages come back as error records.

FAQ

How do I run an SEO audit on my whole website? { "mode": "site", "startUrl": "https://yoursite.com", "maxPages": 100 } — the crawl follows internal links and the final SITE_SUMMARY record hands you fixOrder, a list already sorted criticals-first.

What can a site crawl find that a single-page checker can't? Problems that exist between pages: redirect chains with every hop, broken internal and outbound links with the page each sits on, duplicate titles and meta descriptions with the exact URLs, and missing robots.txt or sitemap.

How is the audit billed? $0.10 per page successfully audited (page-audited event) — pages that fail to load are never charged, and maxPages caps both the crawl and the spend.

Can I audit just one page or a handful? Yes — page mode: { "url": "https://a.com" } or { "urls": [...] } for a fast on-page check without the crawl.

Does it detect what the site is built with? Yes — WordPress, Next.js, Shopify, Wix, Astro, Squarespace and the generator meta are reported per page alongside the SEO score.

How is the SEO score calculated? It starts at 100 and subtracts 25 for each critical issue, 8 for each warning and 3 for each note, floored at 0. Every deduction is visible in the issues array of the same record, so the number is reproducible arithmetic rather than a black box.

How do I find duplicate title tags across my site? Site mode. Duplicate titles and duplicate meta descriptions appear in siteWideIssues on the SITE_SUMMARY record, each with the exact URLs that share them. A single-page checker structurally cannot find these.

How much does it cost to audit a 500-page site? $50.00 — $0.10 per page audited, and maxPages caps both the crawl and the spend. Most people should start with maxPages: 25 on their most important section.

Does it run JavaScript? No. Pages are audited as the server sends them. A client-rendered site will show a low word count and missing headings that a browser would have rendered.

Can I schedule it to watch my site? Yes — schedule a run on the Apify platform, fire a webhook when it finishes, and diff averageSeoScore or issueCounts between runs to catch regressions.

Can an AI agent call this? Yes — it is callable over Apify MCP, is side-effect free, and returns strictly structured JSON with a pre-sorted fixOrder, so an agent can act on findings without parsing prose.

For AI agents

This Actor is built to be called by software, not just by people.

  • Mount it directly as an MCP tool — no Store search, no ranking, just this one tool: https://mcp.apify.com/?actors=eliai/website-seo-tech-auditor
  • Or call it over HTTP and get the results in the same request: POST https://api.apify.com/v2/acts/eliai~website-seo-tech-auditor/run-sync-get-dataset-items
  • Pay with x402, without an Apify account. This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
  • Costs are predictable before you call. Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
  • Send only the field you mean. If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.