# SEO Site Audit

> SEO site audit: crawl a site and find broken links, redirect chains, bad titles and meta tags. Get issues by priority. No login or API key.

URL: https://cliqtomedia.com/actors/seo-site-audit/

Category: Search, SEO & ads · Status: coming soon · Apify profile: https://apify.com/cliqtomedia?fpr=cliqto

Crawl one website from a start URL. Get one row per page with issues sorted by priority. You also get one readable report for the site.

## How to use it: 3 steps

1. **Follow us on Apify.** The tool is built and waits in the queue for the Apify Store. Apify is the cloud platform where our tools run.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `https://apify.com` in Website URL. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

SEO Site Audit crawls one website from a start URL and checks every page it finds: HTTP status, redirect chain, broken links, title, meta description, canonical, hreflang, headings, noindex and page size. You get one row per page with a list of issues sorted by priority, plus one readable report for the whole site.

- Status and redirects: the HTTP status code, every redirect hop (`redirectChain`) and the final URL.
- Links: broken internal links (4xx, 5xx or no answer) and broken external links (4xx, 5xx or a domain that does not exist), with the page where each one was found.
- Meta tags: title and its length, meta description and its length, canonical, meta robots and `X-Robots-Tag`, noindex, nofollow, `lang`, hreflang.
- Content: the first H1, H1 and H2 counts, word count, images without an `alt` attribute.
- Speed signals: response time, time to first byte and HTML size. Optional Google PageSpeed (Lighthouse) score and Core Web Vitals with your own free Google API key.
- Issues: a list of found problems (`issues[]`) with a code, severity (`critical`, `high`, `medium`, `low`) and a short message, plus a page score from 0 to 100.

### Good for

- Find broken links and the pages that contain them before users or search engines do.
- Check titles, meta descriptions, canonical tags and noindex on every page after a redesign or migration.
- Find redirect chains and internal links that point to redirects.
- Get a quick technical SEO health check of a client or competitor site.

### Not a good fit

- Sites that build their content with JavaScript only. The Actor reads the server HTML, so text and links added later by scripts are not seen.
- Pages behind a login, a paywall or bot protection that blocks normal crawlers.
- Keyword research, rankings, backlinks or traffic data. This Actor checks your pages, not search results.
- Many websites in one run. Use one run per website.

## Price

Prices will be shown after release.

## Questions

### Do I need an account or an API key?

No. It checks public pages without login. A Google key is needed only for PageSpeed tests.

### Does it run JavaScript like a browser?

No. It reads the HTML that the server returns. Text added by scripts is not seen.

### Can I audit several websites in one run?

No. Use one start URL per run. Start one run for each site.

### Will it find pages with no links to them?

No. It finds pages that links from the start URL can reach.

### Am I charged for 404 pages and redirects?

Yes, when they are on your site: a page that answers 404 or 301 is a checked page and an important finding. Pages that give no answer at all are free. When the start URL itself fails, only the start fee is charged.

### Is the result complete?

It is complete for the pages the crawler can reach by links from the start URL, within your limits and `robots.txt`. Pages that no link points to (orphan pages) are not found.

## Data fields

- `url` (string)
- `finalUrl` (string)
- `status` (string)
- `statusCode` (integer)
- `redirectChain` (array)
- `depth` (integer)
- `linkedFrom` (string)
- `contentType` (string)
- `isHtml` (boolean)
- `responseTimeMs` (integer)
- `ttfbMs` (integer)
- `pageSizeBytes` (integer)
- `title` (string)
- `titleLength` (integer)
- `metaDescription` (string)
- `metaDescriptionLength` (integer)
- `h1` (string)
- `h1Count` (integer)
- `h2Count` (integer)
- `canonical` (string)
- `isCanonicalSelf` (boolean)
- `noindex` (boolean)
- `nofollow` (boolean)
- `robotsMeta` (string)
- `xRobotsTag` (string)
- `lang` (string)
- `hreflang` (array)
- `wordCount` (integer)
- `imagesMissingAlt` (integer)
- `internalLinksCount` (integer)
- `externalLinksCount` (integer)
- `inlinksCount` (integer)
- `brokenLinks` (array)
- `brokenLinksCount` (integer)
- `pagespeed` (object)
- `issues` (array)
- `issuesCount` (integer)
- `topSeverity` (string)
- `score` (integer)
- `error` (string)

## Input settings

- `startUrl` (string, required): Page where the crawl starts, usually the homepage. Only pages on the same host (www and non-www count as the same) are crawled.
- `maxPages` (integer): Maximum number of URLs to audit. You pay per audited page that returned an HTTP response.
- `maxDepth` (integer): How many clicks away from the start URL to go. Leave empty for no limit.
- `checkExternalLinks` (boolean): Send a HEAD request (GET if HEAD is refused) to links pointing to other sites and report broken ones.
- `maxExternalLinks` (integer): Unique external URLs to check per run, at most 20 per audited page. External checks are not charged.
- `includeSubdomains` (boolean): Also crawl subdomains such as blog.example.com when they are linked.
- `excludeUrlPatterns` (array): Skip URLs containing any of these strings. Use * as a wildcard, e.g. */tag/* or ?page=.
- `maxConcurrency` (integer): Requests to the site at the same time (1–5). If robots.txt sets Crawl-delay, the Actor uses 1 and waits between pages (up to 10 s).
- `userAgent` (string): Leave empty to use the Actor's own honest crawler name, which robots.txt rules can target. Names of search-engine bots are not allowed.
- `pagespeedApiKey` (string): Your own Google API key with PageSpeed Insights API enabled. Adds Lighthouse performance score, LCP, CLS and TBT for the first pages. Never logged or stored.
- `pagespeedMaxPages` (integer): How many audited pages (in crawl order, start URL first) get a PageSpeed test. A test usually takes 10–30 s and is stopped after 60 s. Only successful tests are charged; tests stop after 2 failures in a row or after a slow failed test.
- `pagespeedStrategy` (string): Lighthouse device profile.

## Step by step on Apify

1. Open the Input tab.
2. Add your website to Website URL (`startUrl`), for example `https://example.com`.
3. Keep Max pages (`maxPages`) at the suggested 20 for a first test.
4. Click Start.
5. Open the Output tab. The Pages by priority view shows the pages with the lowest score first (rows are saved in that order). Open the Audit report (HTML) for a readable summary.

## Use cases

| Task | Input | Key fields |
|---|---|---|
| Fix broken links | `startUrl`, `checkExternalLinks` | `brokenLinks`, `brokenLinksCount`, `url` |
| Check meta tags after a redesign | `startUrl`, `maxPages` | `title`, `titleLength`, `metaDescription`, `canonical`, `noindex` |
| Clean up redirects after a migration | `startUrl` (old domain or new) | `redirectChain`, `finalUrl`, `statusCode` |
| Check hreflang on a multi-language site | `startUrl`, `includeSubdomains` | `hreflang`, `lang`, `issues` |
| Weekly site health check | `startUrl` on a schedule | `RUN_SUMMARY.siteHealthScore`, `issuesBySeverity` |
| Speed check of key templates | `pagespeedApiKey`, `pagespeedMaxPages` | `pagespeed.performanceScore`, `pagespeed.largestContentfulPaintMs` |

## Tips

- Run it after each site move to catch broken links early.
- Add your free Google API key if you want PageSpeed scores.
- Start one run for each site, because one run takes one start URL.

## Limits



- HTML only, no JavaScript. Titles, headings, links and text are read from the HTML the server sends. On sites that render content in the browser, H1, word count and links can be missing.
- One site per run, up to 2000 pages. Subdomains only with `includeSubdomains`.
- robots.txt is always respected. If `robots.txt` answers with a server error, the Actor checks only the start URL and reports `robots_txt_unavailable`.
- Internal links are checked when the linked page is crawled in the same run. Links to files (PDF, images and similar) are checked separately, up to 500 per run. Pages beyond `maxPages` are not checked.
- External links: up to `maxExternalLinks` and up to 20 per checked page. Answers 401, 403, 429 and 999, timeouts and loops are reported as `restricted_external_links` (could not verify), not as broken, because many sites block automated checks. Link checks stop after 10 timeouts in a row and take at most about 60 s plus 1 s per checked page; links left unchecked are counted in `RUN_SUMMARY.externalLinksSkipped`.
- A redirect to another website (for example to a login service) is a normal row with status 301 or 302 and is charged as one page.
- HTML larger than 5 MB is checked by its first 5 MB.
- PageSpeed depends on your Google key and quota. A failed test is saved as `pagespeed.status = "error"` with a reason such as `invalid_api_key` or `quota_exceeded`, and is not charged. Tests stop after 2 failures in a row, after a wrong key or quota error, or after a failed test that took over 30 s (a test is stopped at 60 s). PageSpeed is skipped when the site stopped answering (`SOURCE_ERROR`).

## Sample result

```json
{
  "url": "https://apify.com/integrations",
  "finalUrl": "https://apify.com/integrations",
  "status": "ok",
  "statusCode": 200,
  "redirectChain": [],
  "depth": 1,
  "title": "Connect Apify with your apps · Apify",
  "titleLength": 36,
  "metaDescription": "Integrate the Apify platform and Actors with your favorite tools, APIs, and cloud services. Trigger workflows, send data in real time, and power your AI and apps with live web automation.",
  "metaDescriptionLength": 187,
  "h1Count": 1,
  "canonical": "https://apify.com/integrations",
  "isCanonicalSelf": true,
  "noindex": false,
  "hreflang": [],
  "wordCount": 1674,
  "responseTimeMs": 162,
  "pageSizeBytes": 949320,
  "brokenLinks": [
    { "url": "https://www.relay.app/apps/apify/integrations", "type": "external", "statusCode": 404, "error": null },
    { "url": "https://block.github.io/goose/docs/mcp/apify-mcp/", "type": "external", "statusCode": 404, "error": null }
  ],
  "brokenLinksCount": 2,
  "pagespeed": null,
  "issues": [
    { "code": "broken_external_links", "severity": "medium", "message": "2 broken external links" },
    { "code": "meta_description_too_long", "severity": "low", "message": "Meta description has 187 characters" },
    { "code": "restricted_external_links", "severity": "low", "message": "6 external links could not be verified (401/403/429, timeout or redirect loop)" }
  ],
  "issuesCount": 3,
  "topSeverity": "medium",
  "score": 88,
  "error": null,
  "fetchedAt": "2026-10-17T08:21:08.535Z"
}
```

## Similar tools

- [Link Route Audit — Bulk HTTP Status & Redirects](https://cliqtomedia.com/actors/bulk-url-status-redirect-checker/)
- [XML Sitemap URLs Extractor](https://cliqtomedia.com/actors/xml-sitemap-urls-extractor/)
- [Website Metadata & Open Graph Scraper](https://cliqtomedia.com/actors/website-metadata-open-graph-scraper/)
- [Website Tech Stack Detector: CMS, Versions & CDN, No Login](https://cliqtomedia.com/actors/tech-stack-detector/)
- [Google Autocomplete Scraper](https://cliqtomedia.com/actors/google-autocomplete-scraper/)
- [Website JSON-LD Structured Data Scraper](https://cliqtomedia.com/actors/website-jsonld-structured-data-scraper/)
