Website Release QA: SEO, Links & Screenshots
Pricing
from $50.00 / 1,000 page auditeds
Website Release QA: SEO, Links & Screenshots
Check 1–10 public pages before launch. Render in Chromium, capture screenshots, test redirects and internal links, and verify SEO, indexability, image-alt, landmark, and form-label rules with deterministic pass, fail, or unknown evidence.
Pricing
from $50.00 / 1,000 page auditeds
Rating
0.0
(0)
Developer
Sassy Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Website Release QA
Website Release QA is a deterministic, browser-rendered website audit tool
for pre-launch checks, releases, campaigns, migrations, and client handoffs.
Add 1–10 public URLs and get screenshots plus explicit pass, fail, or
unknown evidence for delivery, redirects, internal links, SEO metadata,
indexability, image alt coverage, page landmarks, and form labels.
Use it before a production release, landing-page campaign, domain migration, or client handoff when you need a repeatable release receipt rather than a generic score. The Actor never logs in or submits forms, does not intentionally perform write actions, and does not ask a language model to interpret the result. Browser routing blocks non-read-only HTTP methods; the Actor issues GET navigations and bounded HEAD/GET link probes, so target sites must treat those methods as read-only.
Current package release: 0.2.0. The Apify Actor definition uses the corresponding major/minor version 0.2.
Live Store listing: https://apify.com/sassy_labs/website-release-qa
Checks
For each page, release 0.2.0 checks:
- final HTTP status and redirect count;
- document title and meta-description length;
- canonical URL presence, validity, and optional same-origin enforcement;
- H1 count;
- meta robots and
X-Robots-Tagnoindexdirectives; - bounded unique same-origin links;
- image
altattribute coverage, including explicit empty decorative alts; - a
mainorrole=mainlandmark; - accessible names for non-hidden controls inside forms; and
- a Chromium viewport screenshot saved to the run's key-value store.
The first dataset record is the run-level overview. Every subsequent item is a
detailed finding. The overview dataset view is optimized for scanning status,
severity, category, observed evidence, and screenshot links.
Example input
{"urls": ["https://example.com/","https://example.com/about"],"maxRedirects": 5,"maxInternalLinksPerPage": 20,"minTitleChars": 10,"maxTitleChars": 60,"minMetaDescriptionChars": 50,"maxMetaDescriptionChars": 160,"minImageAltCoveragePercent": 95,"requireCanonical": true,"requireSameOriginCanonical": true,"requireSingleH1": true,"requireMainLandmark": true,"requireFormLabels": true,"captureScreenshots": true,"viewportWidth": 1440,"viewportHeight": 900}
One to ten URLs are accepted. Internal links are deduplicated, fragment-free,
same-origin only, and capped at 50 per page. Link probes use HEAD, falling
back to a one-byte ranged GET when a server rejects HEAD.
Output contract
The overview record contains:
- overall
status; - pass, fail, unknown, page, finding, and screenshot totals;
- one status per requested page; and
- the exact thresholds used.
Finding records contain a stable checkId, category, severity, expected rule,
observed result, short evidence array, final URL, and screenshot key/link when
applicable.
unknown is used when the Actor cannot safely or conclusively run a check. It
does not silently convert network, DNS, rendering, or screenshot failures into
a pass.
When a maximum run charge cannot cover another page, that URL is not opened.
Its only finding is budget_limit with status: unknown and audited: false.
The overview separately reports requested, processed, and budget-limited URL
counts, so an unpaid page is never presented as audited.
Concrete example output
This abridged output came from the verified 17 July 2026
check-landing-page-before-launch example against https://example.com/.
The page rendered and produced a screenshot; the failing checks remained
visible instead of being forced green.
{"recordType": "overview","status": "fail","summary": "Release QA found 3 failing check(s) across 1 page(s)","totals": {"requestedUrls": 1,"processedUrls": 1,"budgetLimitedUrls": 0,"findings": 12,"screenshots": 1,"pass": 9,"fail": 3,"unknown": 0}}
One detailed record was:
{"recordType": "finding","status": "fail","checkId": "main_landmark","category": "accessibility","severity": "medium","summary": "No main content landmark was found","expected": "At least one main or role=main landmark","observed": "0 main, 0 navigation, 0 banner, 0 contentinfo landmarks","audited": true}
The screenshot is stored as SCREENSHOT_001 in the run's default key-value
store. Volatile timestamps and storage URLs are omitted from this example.
Current Apify pricing
The live Store listing uses pure pay-per-event pricing with exactly two events:
apify-actor-start: the official platform-managed synthetic event at its default USD 0.00005 price. Apify charges it automatically and covers the first five seconds of compute; the Actor must never charge it manually;page-audited: USD 0.05 once per URL, charged before browser or link work begins.
That makes event charges USD 0.05005 for one page, USD 0.25005 for five pages, and USD 0.50005 for the ten-page maximum.
page-audited is the primary event. apify-default-dataset-item and the
obsolete custom audit-start event are not configured, so detailed findings
cannot create a second charge. Platform usage is included in the event price.
The runtime validates the production PPE event configuration, but it does not
manually charge the synthetic start. It inspects every custom-page
ChargeResult: a failed page charge stops the run before that URL is processed.
A successful charge remains valid even when it exhausts the remaining event
budget; that already-paid page is still audited, while later pages are marked
budget-limited.
The public configuration was verified on 17 July 2026 with limited permissions, hidden source files, Standby disabled, 1024 MB minimum/default memory, and a 2048 MB maximum. Owner cloud preflights for 1, 5, and 10 pages reported total platform usage of approximately USD 0.00063, USD 0.00109, and USD 0.00332. Those runs are cost and reliability evidence, not customer demand or revenue.
This charging design follows Apify's current
pay-per-event guidance,
including the synthetic start event, ChargeResult budget checks, and the
optional platform-usage pass-through setting.
Safety boundary
- Only public HTTP(S) URLs on ports 80 and 443 are accepted.
- URL credentials, localhost, internal hostnames, and private, reserved, link-local, multicast, and otherwise non-public IP addresses are rejected.
- Browser traffic is forced through a loopback-only guard proxy. The proxy resolves every destination itself and connects to the validated public IP, preventing Chromium from bypassing the DNS decision.
- Redirect destinations and sampled links are revalidated.
- Service workers and downloads are disabled.
- Runs are bounded to ten pages, fifty sampled links per page, eight link requests at once, and sixty seconds per navigation or probe.
- No account, cookie, customer credential, API key, proxy subscription, or model call is required.
What it does not claim
This is a focused release checklist, not a complete WCAG audit, legal compliance opinion, Core Web Vitals test, visual-regression system, malware scanner, or proof that search engines will index a page. It does not log in, submit forms, click consent dialogs, or intentionally perform a write action. Browser routing blocks methods other than GET, HEAD, and OPTIONS. The Actor still issues GET navigations and bounded HEAD/GET link probes, and it does not crawl beyond the configured link sample.
Dynamic pages are rendered with JavaScript, but results can still differ when a
site personalizes content, geo-blocks cloud browsers, requires authentication,
or delays important UI beyond DOMContentLoaded and a short bounded
network-idle wait. Those cases remain visible as failures or unknowns.
Local verification
Prerequisites: Node.js 22.19+.
npm cinpm run verifynpx --yes apify-cli@1.7.1 validate-schema
For a live local screenshot, install the matching Chromium once:
npx playwright install chromiumnpm run demo
On Windows, an existing stable Chrome install can be used without downloading Chromium:
$env:WEBSITE_QA_BROWSER_CHANNEL = "chrome"npm run demoRemove-Item Env:WEBSITE_QA_BROWSER_CHANNEL
The demo makes read-only requests to https://example.com/, writes its PNG
under output/playwright/, and prints the run overview. Unit tests inject
network and browser fixtures and do not depend on public websites.
Local pay-per-event boundary check
Local PPE test events explicitly charged by Actor code cost USD 1 each. The
following USD 1 cap permits exactly one custom page-audited event. The
platform-managed synthetic start is deliberately not emitted by Actor code or
the local charging log. The second URL must remain unaudited and appear as an
explicit budget-limited result:
$env:ACTOR_TEST_PAY_PER_EVENT = "true"$env:ACTOR_USE_CHARGING_LOG_DATASET = "true"$env:ACTOR_MAX_TOTAL_CHARGE_USD = "1"$env:WEBSITE_QA_BROWSER_CHANNEL = "chrome"npx --yes apify-cli@1.7.1 run --purge --input-file demo/ppe-input.jsonnpm run verify-ppe-logRemove-Item Env:ACTOR_TEST_PAY_PER_EVENTRemove-Item Env:ACTOR_USE_CHARGING_LOG_DATASETRemove-Item Env:ACTOR_MAX_TOTAL_CHARGE_USDRemove-Item Env:WEBSITE_QA_BROWSER_CHANNEL
The charging log is written to storage/datasets/charging_log/. It must contain
exactly one page-audited event. The default dataset overview must report one
processed URL, one budget-limited URL, and one page event charged. Neither a
manual start event nor a synthetic dataset event is permitted. Named local
charging logs can survive Apify's --purge; verify-ppe-log therefore scopes
its assertion to the current default-dataset overview timestamp.
The Actor requires at least 1024 MB of memory, matching Apify's browser-Actor guidance. The cloud Docker image pins Node.js 22 and Playwright 1.61.1 to the matching Apify Chromium image for reproducible builds.