Monitor visual changes
Catch the checkout page that turned into unstyled text or the hero image that broke, even when the page's text is identical. Each check renders the page like a visitor, compares it with the last capture and alerts you when it looks different. You pay per check, with no subscription.
Text can stay identical while a page falls apart visually — a broken hero image, a collapsed layout, a banner that silently vanished.
When the text stays the same but the page breaks
A page can keep exactly the same text while it falls apart visually. A hero image breaks, a layout collapses, a banner silently disappears, or a style file fails to load and the entire checkout page turns into unstyled text on a white background. A comparison of the raw page code will happily report that nothing changed. Design teams, quality assurance engineers and anyone running marketing or landing pages that must look a certain way need a check that renders the page the way a real visitor sees it and compares that rendering over time.
How the visual comparison works
On the first run the page is rendered and captured, and a visual fingerprint of it is stored. Every later run captures the page again and compares it with that fingerprint. When the rendering has changed, you get a signal that the appearance has moved since the last check; it is not a map of which pixels differ. Teams use it to catch a broken campaign page after a release before customers do, to spot a competitor's redesign of a pricing or feature page early, and to let an unexpected visual shift right after a deployment inform the decision to roll back.
Why pixels lie less than text
A diff of raw HTML will happily tell you nothing changed when, in reality, a CSS file failed to load and your entire checkout page is now unstyled text on a white background. Design teams, QA engineers, and anyone running marketing or landing pages that must look a certain way need a check that renders the page like a real visitor would see it, then compares that rendering over time.
What you can do with it
Marketing page integrity
Get alerted when a campaign landing page's appearance changes after a deploy, catching a broken hero or a collapsed layout before customers do.
Competitor layout tracking
Watch a competitor's pricing or feature page for a visual redesign before the change shows up anywhere else.
Post-deploy visual QA
Get a visual change alert right after a release pipeline finishes, so an unexpected rendering shift can gate a rollback decision.
FAQ
How does visual monitoring differ from checking if the HTML changed?
HTML can stay technically valid while the page renders broken — a missing stylesheet, a hidden section, an image that fails silently.
What happens if a check fails, like a timeout?
The task retries automatically up to three times; if it still fails, you get a clear error and are not charged for that failed attempt.
Can I run this in bulk across many URLs?
Yes, each URL is its own monitor, so you can register monitor-visual checks across as many pages as you need from your own scheduler.
Does the alert show exactly which part of the page changed?
No. It tells you that the page's appearance has moved since the last check, as a change signal rather than a map of which pixels differ. Open the page to see what happened.
What kind of problems does visual monitoring catch?
A broken hero image, a collapsed layout, a banner that silently vanished, or a style file that failed to load and left a checkout page as plain text on a white background. None of these has to change the page's text.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
One authenticated POST creates the task; the result comes back by webhook or a signed link. This capability is currently available through the API, not as an interactive Web tool.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/monitor-visual \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'const res = await fetch("https://api.kit.forhosting.com/web/monitor-visual", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://example.com"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/monitor-visual",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://example.com"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/monitor-visual", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://example.com"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://example.com"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/monitor-visual", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://example.com"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.monitor_visual",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |
Technical notes
This visual regression monitoring API renders the page, compares it against the last capture, and alerts you when the rendered appearance has changed.
Why pixels lie less than text
That is the gap this endpoint fills.
What actually happens on each check
On every subsequent run, the new capture is compared against that fingerprint. You call POST /web/monitor-visual with a URL and a check frequency; the task renders the page, captures it, and stores a visual fingerprint. If the rendering has changed, a webhook fires to tell you the page's appearance has moved since the last check — a change signal, not a localized diff of which pixels differ.
From single screenshots to a discipline
Visual regression testing grew out of frontend QA, where teams got tired of shipping a broken button color or a layout shift nobody caught in a manual review.
Built to sit inside your own automation
The monitor is asynchronous: you register it and it runs on your chosen frequency, delivering a change notification via a signed webhook (recommended for pipelines) or a signed link valid for 24 hours. That means checks run on your own cadence, feeding results straight into an incident channel or a step after a deploy — without holding a connection open or polling in a loop.
Pricing that matches what you use
A failed task is retried up to three times automatically and is never charged if it ultimately fails. The endpoint costs $0.040 per request plus $0.001 per check, published and predictable. There is no free tier and no trial period — access requires prepaid balance, which keeps the checking capacity fast and free of abuse.
Integration use cases
Third-party widget failure
Catch the moment a chat widget, cookie banner, or embedded video silently stops loading and leaves a visible gap that shifts the page.
Technical questions
Is there a free trial for the visual monitor endpoint?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How do I get notified of a change?
When a check finds the rendered page differs from the last one, a webhook — or a signed link valid for 24 hours, whichever you configure — delivers the change notification with a timestamp.
What counts as a check?
Each individual visual check performed against the target URL — the baseline capture plus every subsequent comparison — is billed at $0.001, on top of the $0.040 base request cost.
Can I monitor pages that require login or specific viewport sizes?
Yes, the target URL and rendering parameters are set per request, so authenticated or device-specific pages can be checked as long as the page itself is reachable.
Do you keep my screenshots forever?
No. Captured data is deleted after the retention period and is never used for training — it exists only to serve your comparison and webhook delivery.