Web Metadata Contract Validator — OG, Twitter & Canonical avatar

Web Metadata Contract Validator — OG, Twitter & Canonical

Pricing

$3.00 / 1,000 results

Go to Apify Store
Web Metadata Contract Validator — OG, Twitter & Canonical

Web Metadata Contract Validator — OG, Twitter & Canonical

Extract deterministic web metadata and machine-actionable validation findings from one static HTML page.

Pricing

$3.00 / 1,000 results

Rating

0.0

(0)

Developer

Masatoshi Shimada

Masatoshi Shimada

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Turn one public static HTML page into a deterministic JSON contract for metadata QA and automation. The Actor extracts document, canonical, robots, Open Graph, and Twitter Card metadata, then returns stable finding codes for missing, duplicate, invalid, or conflicting values.

Human Owner approved Public publication, Pay-per-event Monetization, and the production price on August 15, 2026. Live platform status is verified in the repository release report.

What it returns

Each successful run writes exactly one item to the default dataset:

  • requested and final URL, HTTP status, and fetch timestamp
  • title, meta description, resolved canonical URL, and robots directives
  • Open Graph title, description, image, and type
  • Twitter Card type, title, description, and image
  • machine-actionable findings with stable code, severity, and field
  • all observed values under evidence.metadataOccurrences
  • content type and parser version provenance

Absent values are null; the Actor does not copy a value from another field. When a scalar field has multiple definitions, its normalized value is also null, every occurrence remains in evidence, and an *_MULTIPLE finding is returned.

Input

{
"url": "https://example.com/",
"timeoutSeconds": 15,
"maxResponseBytes": 5242880,
"maxRedirects": 3
}
FieldRequiredContract
urlyesOne public http or https page
timeoutSecondsnoInteger from 1 to 20; default 15
maxResponseBytesnoInteger from 1 to 5,242,880; default 5 MiB
maxRedirectsnoInteger from 0 to 3; default 3. Use 0 to reject the first redirect without following it

Output example

{
"requestedUrl": "https://example.com/",
"finalUrl": "https://example.com/",
"httpStatus": 200,
"fetchedAt": "2026-08-07T00:00:00Z",
"metadata": {
"title": "Example Domain",
"description": null,
"canonicalUrl": null,
"robots": [],
"openGraph": {"title": null, "description": null, "image": null, "type": null},
"twitterCard": {"card": null, "title": null, "description": null, "image": null}
},
"findings": [
{
"code": "META_DESCRIPTION_MISSING",
"severity": "WARNING",
"field": "metadata.description",
"message": "Meta description is absent"
}
],
"evidence": {
"metadataOccurrences": {
"title": ["Example Domain"],
"description": []
}
},
"provenance": {"contentType": "text/html", "parserVersion": "0.1.0"}
}

The full occurrence map always contains every field defined in the dataset schema.

Finding families

  • missing fields: TITLE_MISSING, META_DESCRIPTION_MISSING, CANONICAL_MISSING, OG_*_MISSING, TWITTER_*_MISSING
  • duplicate fields: corresponding *_MULTIPLE codes
  • canonical checks: CANONICAL_URL_INVALID, CANONICAL_ORIGIN_MISMATCH
  • consistency checks: TITLE_OG_MISMATCH, TITLE_TWITTER_MISMATCH, DESCRIPTION_OG_MISMATCH, DESCRIPTION_TWITTER_MISMATCH
  • robots/canonical check: NOINDEX_CANONICAL_CONFLICT

Findings describe the metadata contract. They do not guarantee search rankings or social-platform behavior.

Limits and safety

  • Static HTML only; no browser and no JavaScript rendering.
  • One URL and one connection at a time. maxRedirects bounds redirect following from 0 to 3; the default 3 preserves the existing behavior.
  • DNS is validated on the initial URL and every redirect. Connections are pinned to the validated public IP, and local, private, link-local, reserved, multicast, and metadata-service destinations are rejected.
  • User information in URLs, non-HTML responses, unsupported content encodings, HTTP errors, timeouts, and oversized responses fail explicitly.
  • Both compressed and expanded response bodies are capped. HTML bodies are neither logged nor stored.
  • No proxy, paid API, LLM, API key, or Secret is required.

Only fetch pages you are authorized to access and comply with applicable terms, robots guidance, privacy, copyright, and rate limits.

Pricing

The approved production price is $0.003 per successful default dataset item using Apify's built-in apify-default-dataset-item event. There is no Actor-start or custom paid event.

An approved private Free-plan cloud test observed usageTotalUsd of $0.00010828961847888099 and $0.0001060056708090835 for two successful 128 MiB runs. Both finished in under seven seconds with exactly one contract-valid dataset item. A third run rejected 127.0.0.1 before producing data, as required by the SSRF policy.

The normal-run average, $0.000107147644643982245, supports a positive conditional pro forma at this item price. It is not actual paid-user cost: the measurements came from private Free-plan runs and usageTotalUsd is an informational current-price estimate. Paid-user unit economics and paid demand remain unproven. See the repository cloud Cost Test report for the full assumptions and reconciliation.

Local development

Python 3.11 or newer is required; the candidate image uses Python 3.14 and Apify SDK 4.0.0.

py -3.14 -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
$env:PYTHONPATH = "."
.venv\Scripts\python.exe -m unittest discover -s tests -v
.venv\Scripts\ruff.exe check web_metadata_actor tests tools

Run with the Apify CLI and mock PPE logging:

$env:VIRTUAL_ENV = (Resolve-Path .venv).Path
$env:Path = "$env:VIRTUAL_ENV\Scripts;$env:Path"
$env:APIFY_CLI_DISABLE_TELEMETRY = "1"
$env:ACTOR_TEST_PAY_PER_EVENT = "true"
npx --yes apify-cli@1.7.1 validate-schema
npx --yes apify-cli@1.7.1 run --purge --input '{"url":"https://example.com/"}'

Mock PPE logs use a local placeholder price and do not bill any account.