SEO Audit — On-Page Score, Meta Tags, Schema & Fix Guidance avatar

SEO Audit — On-Page Score, Meta Tags, Schema & Fix Guidance

Pricing

from $3.20 / 1,000 page auditeds

Go to Apify Store
SEO Audit — On-Page Score, Meta Tags, Schema & Fix Guidance

SEO Audit — On-Page Score, Meta Tags, Schema & Fix Guidance

SEO audit: On-page scores, metadata, schema and original fix guidance. $0.004 per page audited; start extra; usage included; failed results uncharged.

Pricing

from $3.20 / 1,000 page auditeds

Rating

0.0

(0)

Developer

Logan Parker

Logan Parker

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Features

Limited permissions

Share

SEO audit of supplied public page URLs returns a reproducible on-page score and fix guidance for metadata, headings, canonical tags, hreflang, schema and links; optional batch summaries group duplicate metadata without crawling. AI agents can call and pay through Apify MCP. List event rates are $0.004 per page audited; start is extra, usage is included and failed results are uncharged.

Example result

This is the unchanged record returned for the minimal input by the built production image on 2026-10-28, using the real Apify SDK against the public source in local storage mode. Local event logs are not Apify settlement. The image identity, source commit, command and raw records are retained with the release.

{
"url": "https://docs.apify.com/platform/actors/publishing/monetize",
"finalUrl": "https://docs.apify.com/actors/monetize",
"ok": true,
"status": 200,
"findings": [
{
"id": "twitter_missing",
"severity": "notice",
"message": "Recommended Twitter card metadata is absent.",
"evidence": "twitter:title"
},
{
"id": "twitter_missing",
"severity": "notice",
"message": "Recommended Twitter card metadata is absent.",
"evidence": "twitter:description"
},
{
"id": "redirected",
"severity": "notice",
"message": "The requested URL redirects.",
"evidence": [
"https://docs.apify.com/actors/monetize"
]
}
],
"summary": {
"errors": 0,
"warnings": 0,
"notices": 3
},
"meta": {
"title": "Monetize Actors | Platform | Apify Documentation",
"description": "Monetize your Actors on Apify Store and earn regular passive income.",
"canonical": "https://docs.apify.com/actors/monetize",
"robots": [],
"xRobotsTag": null,
"lang": "en",
"viewport": "width=device-width, initial-scale=1.0",
"hreflang": [
{
"lang": "en",
"url": "https://docs.apify.com/actors/monetize"
},
{
"lang": "x-default",
"url": "https://docs.apify.com/actors/monetize"
}
],
"openGraph": {
"og:url": "https://docs.apify.com/actors/monetize",
"og:locale": "en",
"og:title": "Monetize Actors | Platform | Apify Documentation",
"og:description": "Monetize your Actors on Apify Store and earn regular passive income.",
"og:image": "https://apify.com/og-image/docs-article?title=Monetize+Actors"
},
"twitter": {
"twitter:card": "summary_large_image",
"twitter:image": "https://apify.com/og-image/docs-article?title=Monetize+Actors"
}
},
"headings": [
{
"level": 1,
"text": "Monetize Actors"
},
{
"level": 2,
"text": "Pricing models"
},
{
"level": 2,
"text": "Fees and costs"
},
{
"level": 3,
"text": "Platform usage"
},
{
"level": 3,
"text": "Testing costs"
},
{
"level": 3,
"text": "Apify's commission"
},
{
"level": 2,
"text": "Make your Actor eligible for agentic payments"
},
{
"level": 2,
"text": "Handle free users"
},
{
"level": 2,
"text": "Actor analytics"
},
{
"level": 2,
"text": "Promote your Actor"
}
],
"structuredData": [],
"links": {
"internal": 77,
"external": 23,
"nofollow": 0
},
"wordCount": 913,
"imagesMissingAlt": 0,
"onPageScore": 100,
"scoreVersion": "hermes-on-page-v1",
"scoreBreakdown": [
{
"group": "title",
"cap": 20,
"deduction": 0,
"findingIds": []
},
{
"group": "description",
"cap": 10,
"deduction": 0,
"findingIds": []
},
{
"group": "canonical",
"cap": 15,
"deduction": 0,
"findingIds": []
},
{
"group": "headings",
"cap": 10,
"deduction": 0,
"findingIds": []
},
{
"group": "language",
"cap": 5,
"deduction": 0,
"findingIds": []
},
{
"group": "viewport",
"cap": 10,
"deduction": 0,
"findingIds": []
},
{
"group": "hreflang",
"cap": 5,
"deduction": 0,
"findingIds": []
},
{
"group": "schema",
"cap": 10,
"deduction": 0,
"findingIds": []
},
{
"group": "alt",
"cap": 5,
"deduction": 0,
"findingIds": []
},
{
"group": "mixed_content",
"cap": 10,
"deduction": 0,
"findingIds": []
},
{
"group": "observations",
"cap": 0,
"deduction": 0,
"findingIds": [
"redirected",
"twitter_missing"
]
}
],
"actions": [
{
"id": "redirected",
"priority": 3,
"fixHint": "Check that the redirect destination is intended, and update links to the final address where appropriate.",
"findingIndices": [
2
],
"occurrences": 1
},
{
"id": "twitter_missing",
"priority": 3,
"fixHint": "If card previews matter, review the named Twitter card fields and the preview you intend to publish.",
"findingIndices": [
0,
1
],
"occurrences": 2
}
]
}

How to use it

Start a run in Apify Console, by API or from an agent with an input like this one — it is the input Apify runs every day to test this Actor:

{"urls": ["https://docs.apify.com/platform/actors/publishing/monetize"]}

Start with the minimal JSON example above, then adjust the fields in the table below. Read the Example result and Output fields sections for the returned record, Errors for failure codes, and Events and prices for result events and the separate platform start.

FieldTypeMeaning
urlsarrayPublic HTTP(S) URLs to process; errors are uncharged.
renderstringauto renders sparse HTML; never audits static HTML; always audits the rendered DOM.
includeBatchSummarybooleanOptional supplied-URL report and duplicate metadata groups, false by default; no crawl or extra event.

Events and prices

EventTitleCharged whenFREE / BRONZESILVERGOLD / PLATINUM / DIAMOND
page-auditedPage auditedOne successfully fetched and audited HTML page.$0.004$0.0036$0.0032

Platform usage is not passed through. Apify's automatic actor-start event remains $0.00005 per started GB (one GB or less counts once). The synthetic dataset-item event is absent. Charge limits stop further paying work; unprocessed inputs receive uncharged errors. Settlement of completed readable work is attempted on abort; interruption can leave a charge unconfirmed.

Worked cost example: ten successful primary events cost $0.04 at list, plus actor start. Failures are not included in that count.

Call it from an agent

Through Apify's MCP server (https://mcp.apify.com) use call-actor:

{
"actor": "hermeskd/seo-page-audit",
"input": {
"urls": [
"https://docs.apify.com/platform/actors/publishing/monetize"
]
},
"callOptions": {
"maxTotalChargeUsd": 0.05,
"timeout": 600
},
"waitSecs": 30
}

Then call get-dataset-items with the returned defaultDatasetId. Dedicated tool URL: https://mcp.apify.com?tools=hermeskd/seo-page-audit

Output fields

FieldMeaning
urlInput URL.
finalUrlURL after redirects.
okTrue for a readable audit, including pages with SEO findings.
statusFinal HTTP status.
findingsActionable observations; length checks are editorial heuristics.
summaryFinding counts by severity.
onPageScoreOriginal 0–100 findings-only score, null on failure; formula above.
scoreVersionOriginal weight policy version, hermes-on-page-v1.
scoreBreakdownGroup caps, deductions and matching finding IDs.
actionsFresh fixed fix hints, priority, occurrence count and bounded finding references.
metaTitle, description, canonical, robots, language, viewport, hreflang and social metadata.
headingsDocument heading outline.
structuredDataTypes and profile validation only; unknown types valid=null; no contact values returned.
linksHTTP(S) link counts.
wordCountWords in visible static/rendered text, excluding scripts and styles.
imagesMissingAltImages without an alt attribute; decorative empty alt is accepted.
errorFailure, always uncharged.

Limits and run time

1–100 URLs; 10 MiB per HTML response. auto renders HTML with fewer than 200 static words, never parses static HTML only, always audits the rendered DOM. Actual HTML is requested; Markdown and files are rejected, uncharged. Title length 30–60 and description length 50–160 are editorial heuristics, not ranking guarantees. Structured-data profiles cover Article, NewsArticle, BlogPosting, Organization, BreadcrumbList and ListItem. Article/Organization currently have no required properties. Unknown types have valid=null; no complete schema.org or rich-result eligibility claim. Up to 1,000 structured nodes and depth 50.

The default run timeout is 600 seconds. Typical run time on Apify, measured by its deploy of 2026-10-21: the minimal input under How to use it took 3–13 seconds a run at the default 2,048 MB (three runs, peak memory 74 MiB). The same input also ran and passed the pricing floor at 1,024 MB and 4,096 MB (the deploy's memory probes).

On-page score and fix guidance

onPageScore is our hermes-on-page-v1 editorial audit rubric, not a Google score, a ranking prediction, a rich-result eligibility verdict or a complete accessibility assessment. Given the same findings, it always gives the same score. It uses only distinct finding IDs: no timing, run ID, metadata value, finding order or occurrence count changes the number.

Start at 100. For each group, add the deductions for distinct matching IDs, cap that sum at the group's cap, then subtract all capped sums. Clamp the result to 0–100. In formula form: max(0, 100 - sum(min(groupCap, sum(distinctIdDeductions)))). A http_status finding produces null, since no successful page audit is available. Failed input records likewise have no numeric score. Unknown finding IDs require an explicit policy update rather than silently earning a perfect score.

GroupCapFinding IDs and deductions
title20title_missing 20, title_length 5
description10description_missing 10, description_length 3
canonical15canonical_missing 5, canonical_invalid 15, canonical_multiple 15
headings10h1_count 5, heading_level_skipped 5
language5lang_missing 5
viewport10viewport_missing 10
hreflang5hreflang_invalid 5, hreflang_duplicate 5
schema10structured_data_malformed 10, structured_data_missing 5
alt5image_alt_missing 5
mixed_content10mixed_content 10
observations0not_indexable 0, open_graph_missing 0, twitter_missing 0, resource_url_invalid 0, redirected 0, http_status 0

For example, title_length, description_length and canonical_missing deduct 5 + 3 + 5 = 13, for a score of 87. Repeating any one of those findings does not subtract again. Conflicting canonical findings together subtract at most 15. Noindex can be intentional; redirects and optional social tags cost no points. Title/description length and heading conventions are editorial guidance, not search-engine ranking requirements. No schema markup is required simply to earn a score, and unsupported schema types remain unassessed in structuredData. A score of 100 means none of this rubric's weighted findings occurred, not that all possible SEO checks passed.

scoreBreakdown lists every group, cap, deduction and matching IDs. actions contains one original fix hint per finding ID, ordered by priority (1 error, 2 warning, 3 notice) then ID. findingIndices points into the original, unchanged findings array; at most three examples are referenced, with the full occurrence count recorded separately. The hints are fixed guidance written for this Actor; no model or third-party recommendation text is used.

Optional supplied-URL batch report

Set includeBatchSummary to true to write BATCH_SUMMARY.json in the run's key-value store. The output link Optional supplied-URL batch summary opens that JSON. It does not exist when the option is off. No page is discovered or crawled: only caller-supplied inputs and their policy-checked redirects contribute. Links found inside HTML are counted as before, never followed for this report. There is no extra paid event or page charge for the summary.

The report groups outcomes by final origin (scheme, host and non-default port). Failed or unfinished inputs use their supplied origin; malformed origins are null. Indices are zero-based positions in the caller's input list. Counts separate successful and failed completed attempts, pending attempts and unprocessed inputs. reportedInputs also includes uncharged limit/deadline error records. An origin with no successful scored pages has a null average, never a score of 100 or zero. Score distributions cover submitted successful inputs; issue frequencies count distinct audited final URLs, not repeated input aliases.

Duplicate title/description groups cover only distinct final URLs within one origin, without an explicit not_indexable finding. Blank values are ignored. A repeated URL or two supplied URLs redirecting to the same final URL is one observed page. Fragments, host letter case and default ports do not invent new pages; path and query order are retained. Values are normalized with Unicode NFKC, whitespace collapse and case folding; the report includes their SHA-256 digest and input indices rather than copying metadata text. Existing page records retain their original values. No claim is made about pages the caller did not supply or actual search indexing.

complete is false after an abort, timeout, charge limit or unfinished attempt; stoppedBy, pending indices and unprocessed indices show the boundary. Readable page outcomes can appear in a partial report even if settlement is still pending; the report is about audit outcomes, not proof of billed events. An abort may write an initial partial snapshot and a newer one as the current page finishes. An identical snapshot is not rewritten. Storage failures remain visible failures; they are not reported as successful summaries. Invalid run input is rejected before a summary is created.

Once a page write is acknowledged, a deadline or cancellation during settlement keeps that one readable page outcome and its successful summary facts. It does not add a timeout failure for the same input. Interrupted completion marks the summary partial; charge reservations remain with the existing charger. The log separates confirmed charge totals from requests whose settlement is unconfirmed. Abort stops new pages even when summaries are disabled, and allows up to 25 seconds for settlement before publishing the partial report. A remote request interrupted before confirmation may still have reached the platform. Its final billed status requires the platform's settlement evidence.

Errors

CodeMeaning
download_failedThe request or connection failed within its bounded deadline.
http_errorThe source answered an unsuccessful HTTP status.
unsupported_content_typeAn HTML audit/crawl received a non-HTML representation.
too_largeA documented response, expansion or traversal cap was exceeded.
robots_disallowedrobots.txt forbids fetching the URL; no request was made to it.
blocked_hostThe host is on the deny-list or resolves to a private or local address; no request was made.
login_requiredThe page is a sign-in wall; no authentication is attempted.
timeoutThe input did not finish within the run's time budget.
internal_errorUnexpected failure; the message carries the error class.
charge_limit_reachedThe run reached its maximum total charge; this input was not processed.
invalid_inputThe run input passed the input schema but cannot be used; the message names the field.

No failure record is charged. A run fails only when all input outcomes are Actor-side failures; caller errors and a mixture of caller/Actor failures do not fail the run.

Sources and terms

Only process content you have the right to process. URL fetches obey HermesBot robots-group selection, the shared deny-list, public-address checks on connections and redirects, honest identity, deadlines and rate limits. No caller credentials, cookies, CAPTCHA solving, residential proxies or evasion. Public caller-named HTML is parsed directly or after guarded Chromium rendering. Structured-data required-property checks cover the documented Article, Organization and Breadcrumb profiles; unsupported types remain unassessed. No contact values from structured data are returned. The committed enumeration records the Google Search guidance used for those profiles.

Not affiliated

This Actor is not affiliated with Google, Apify, IANA, Verisign or other named protocol/source providers. Third-party names describe compatibility and source material.

Changelog

  • 1.1 (2026-10-28) — original findings-only score and fix hints; optional supplied-URL batch summaries with duplicate metadata groups. No crawl; title, prices, events and fetch safeguards unchanged.

  • 1.0 (2026-10-26) — store listing rewritten for the people and agents searching for this job: title, description, search-engine title and description, categories, and the README in the order a searcher reads it (what it does, a real result, how to use it, prices, the agent call).

  • 1.0 (2026-10-21) — first public release on Apify Store, after the deploy's typical calls, memory probes, benchmarks and pricing floor passed on the platform.

  • 1.0 (2026-10-19) — repairs from an independent review: DNS privacy, malformed publisher URLs, empty sitemap failures, responsive assets and schema prefill, as applicable to this Actor.

  • 1.0 (2026-10-18) — the production image, smoke input, three example tasks and benchmarks passed on GitHub-hosted Linux.

  • 1.0 (2026-10-17) — first implementation.