Visual Diff API: Pixel-Perfect Change Detection for Any Two Pages
Compare any two URLs or HTML strings pixel-by-pixel and get a highlighted diff image, changed pixel count, and percentage. One API call, no browser in your stack.
You shipped a CSS change. The login page looks fine. But the pricing page? The cards overlapped and nobody noticed for three days. Unit tests do not catch layout drift, missing assets, or subtle color shifts — visual diffs do.
Visual regression compares what users actually see. When something changes between two renders, you get proof: a diff image, counts, and a percentage. That is what the Visual Diff API is for.
What Visual Diff does
Send two sources — either url_a / url_b or html_a / html_b — and PageBolt returns a single response with:
- Diff image — a PNG where changed pixels are highlighted (red) against the baseline
changed_pct— percentage of pixels that differchanged_pixelsandtotal_pixels— raw counts for thresholds and reportingduration_ms— how long the comparison took
One HTTP request. No Playwright, no Docker, no headless browser running in your infrastructure.
How it works
Both pages are rendered in parallel in Chromium at the same viewport size. Screenshots are then compared with pixelmatch for a deterministic pixel-level diff. If the two captures have different dimensions, the smaller canvas is padded so the comparison stays well-defined.
API example
curl -X POST https://pagebolt.dev/api/v1/diff \
-H "x-api-key: $PAGEBOLT_KEY" \
-H "Content-Type: application/json" \
-d '{
"url_a": "https://staging.myapp.com",
"url_b": "https://production.myapp.com",
"threshold": 0.1,
"width": 1280,
"blockBanners": true
}'
Example response:
{
"changed_pct": 2.34,
"changed_pixels": 21542,
"total_pixels": 921600,
"diff_image": "data:image/png;base64,...",
"duration_ms": 1842
}
Use cases
- CI/CD visual regression — screenshot staging vs production (or vs a baseline) before you merge or deploy
- Website monitoring — run periodic diffs to catch unauthorized or accidental changes
- A/B testing verification — confirm the correct variant is live on a URL
- Design QA — compare a Figma export or mock rendered as HTML against the real implementation
CI/CD integration
Here is a GitHub Actions step that calls the diff API and fails the job if the change percentage exceeds 5%:
- name: Visual diff check
run: |
RESULT=$(curl -s -X POST https://pagebolt.dev/api/v1/diff \
-H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
-H "Content-Type: application/json" \
-d "{\"url_a\": \"$STAGING_URL\", \"url_b\": \"$PRODUCTION_URL\", \"threshold\": 0.1}")
PCT=$(echo $RESULT | jq -r '.changed_pct')
echo "Visual change: ${PCT}%"
if (( $(echo "$PCT > 5" | bc -l) )); then
echo "::error::Visual diff exceeds 5% threshold"
exit 1
fi
Install jq and bc on the runner if they are not already available, and set STAGING_URL / PRODUCTION_URL via repository or environment variables.
Node.js SDK
const res = await fetch('https://pagebolt.dev/api/v1/diff', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url_a: 'https://staging.myapp.com',
url_b: 'https://production.myapp.com',
threshold: 0.1,
}),
});
const data = await res.json();
// data.diff_image is a base64 PNG; data.changed_pct is the % difference
Python SDK
import requests
resp = requests.post(
"https://pagebolt.dev/api/v1/diff",
headers={"x-api-key": PAGEBOLT_KEY},
json={
"url_a": "https://staging.myapp.com",
"url_b": "https://production.myapp.com",
"threshold": 0.1,
},
)
data = resp.json()
# data["diff_image"] is a base64 PNG; data["changed_pct"] is the % difference
All parameters
Quick reference for the request body (pair url_a/url_b or html_a/html_b):
| Parameter | Description |
|---|---|
| url_a | First page URL |
| url_b | Second page URL |
| html_a | First page as HTML string (alternative to URLs) |
| html_b | Second page as HTML string |
| threshold | Sensitivity 0–1; default 0.1 |
| width | Viewport width in pixels |
| height | Viewport height in pixels |
| darkMode | Emulate prefers-color-scheme: dark |
| blockBanners | Hide cookie / consent banners |
| blockAds | Block ad requests |
| cookies | Cookies to send with navigations |
| headers | Extra HTTP headers |
| authorization | Authorization for protected pages |
| viewportDevice | Named device preset (e.g. phone / tablet profiles) |
The free tier includes 100 requests per month. Each visual diff costs 1 request. Grab an API key on signup and see full request/response details in the documentation.
Get Started Free
100 requests/month, no credit card
Visual diff costs one request per comparison — pixel-perfect change detection without running a browser in your stack. Create a free account or read the API docs.
Get Your Free API Key →