I build Screenshot Happy, so take this with that in mind. This post is about a problem I kept running into on client sites: something looks fine in code review, ships on Friday, and nobody notices the broken hero section until Monday.
The gap between "tests pass" and "it looks right"
Unit and end-to-end tests tell you the logic works. They rarely tell you the page still looks right: a CSS change that pushes the pricing table off-screen, a third-party script that covers the checkout button, a banner that disappears. Catching that usually means keeping your own headless Chrome somewhere, which is its own maintenance job.
Option 1: capture after a deploy (works on any plan)
You can take a screenshot of the page from your CI job with one request and store it as a build artifact:
curl "https://screenshot-api-production-ffd7.up.railway.app/screenshot?url=https://example.com&full_page=true" \
-H "x-api-key: YOUR_API_KEY" \
--output after-deploy.png
full_page=true captures the whole scrollable page (capped at 30,000 px), and selector lets you capture just one element, for example the pricing table. Output can be PNG, JPEG or PDF. The request times out after 15 seconds, so it suits public pages, not slow authenticated flows.
Option 2: let a monitor watch the page for you
If you want to be told when a page changes visually between deploys, create a monitor and point it at any webhook you control:
curl -X POST "https://screenshot-api-production-ffd7.up.railway.app/monitors" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"webhook_url": "https://your-server.com/webhook",
"frecuencia_minutos": 360,
"umbral_diferencia": 5
}'
Here frecuencia_minutos is 360 (every 6 hours, the free plan's floor; paid plans go lower). Each check compares the new capture against the last one. If the percentage of changed pixels crosses umbral_diferencia, we POST this to your webhook:
{
"monitor_id": 4,
"url": "https://example.com",
"comprobado_en": "2026-09-18T17:00:00.000Z",
"cambio_detectado": true,
"diferencia_porcentaje": 12.4
}
From there it's yours: post to Slack, open a ticket, or trigger an n8n workflow from a webhook node. The delivery is retried up to 3 times if your endpoint doesn't return a 2xx.
What it doesn't do (yet)
I'd rather you know before you build on it:
- The threshold is a flat percentage of changed pixels across the whole page. A rotating ad or a live timestamp counts toward it, so noisy pages need a higher threshold.
- There is no selector-scoped comparison for monitors;
selectoronly scopes the capture itself. - Checks run on a schedule (every 6 hours on the free plan, hourly on Starter), not the instant you deploy. For a "right after deploy" check, use option 1.
- Monitor checks run one at a time across the service, so the frequency is a target, not a real-time guarantee.
Pricing, in one line
Free is €0 with 200 screenshots a month and 3 monitored pages. Starter is €9 and Growth is €29, each combining screenshots and monitoring in one payment. If you hit a limit you get a clear 429, not a surprise charge.
The full parameter list and examples are in the docs: https://screenshot-api-production-ffd7.up.railway.app/docs?utm_source=devto&utm_medium=article&utm_campaign=b7-visual-regression
If you try it on a page where the diff is noisy, tell me which page type and I'll look at whether the threshold logic should change.
Top comments (0)