Skip to main content
By the end of this guide, you have a URL monitor for every page a customer can land on, generated from one list, with thresholds that separate slow from down, and an SSL monitor that warns you two weeks before the certificate under all of them expires.
A Checkly group page named Shop uptime with seven passing monitors: five URL monitors for the shop's pages, one for a deliberately slow page, and one SSL monitor, with run results from N. Virginia and Ireland
To follow along without your own app, clone the sample project. It monitors the Danube demo shop and one deliberately slow page on httpbin.org.
To run this guide from your terminal or your coding agent, run npx checkly init in your project first. It installs the Checkly CLI and Checkly Skills for your agent. Then paste the prompt below into Claude Code, Cursor, Codex, or any agent that supports skills. It builds the same setup as this guide, proves it with npx checkly test --record, and stops for your confirmation before npx checkly deploy.
Prompt
The steps below are what the agent does, in the open.

Step 1: Decide what every monitor shares

A shop has a handful of pages a customer can land on, and they all deserve the same treatment: the same locations, the same alert rule, the same idea of what “slow” means. Put those decisions in one place before you write a single monitor, so adding the tenth page costs the same as adding the first.
__checks__/group.ts
The group carries locations and the alert policy, because those belong to the group. Response-time thresholds belong to each monitor, so they live in an exported object that every monitor spreads in. Retries are off in this guide so you can see a failure land on the first run. For real monitoring, Alerting that doesn’t wake you up for nothing shows how to turn them back on. The project config sets the frequency and tag for everything the group does not cover:
checkly.config.ts

Step 2: Turn the list of pages into monitors

Now write down the pages. Not the monitors, the pages. The home page, a product page, the cart, the checkout, and the API the storefront calls. A loop turns each line into a URL monitor that inherits everything from Step 1.
__checks__/pages.check.ts
When a new page ships, someone adds one line and deploys. When a page is retired, someone deletes one line and the monitor goes with it. The id matters more than it looks: Checkly matches a monitor to its history by logical ID, so shop-cart keeps its uptime record no matter where it sits in the array. Generate IDs from array positions and a reorder silently creates five new monitors and deletes five old ones.
A URL monitor answers one question: did this URL return the status code you expect, fast enough? It does not read the response body. The Danube shop is a single-page app that answers 200 for any path, so a monitor for /api/books proves the API is reachable, not that it returns books. When you need to check the body, a header, or an authenticated request, that page gets an API check instead.

Step 3: Tell slow from down

Every monitor above spreads responseTimes, so every one already knows the difference between slow and down. To see where the lines sit, add a page that is always slow. httpbin.org waits one second before answering, and the network adds a little on top.
__checks__/slow.check.ts
That page passes at just over a second. Past three seconds the result is degraded, which shows up in the app and reaches any alert channel that opts in to degraded results, but does not count as downtime. Past five seconds the run fails. The shop pages answer in under 300 milliseconds from both locations, so the same thresholds leave them room to slow down tenfold before anyone is bothered. Set thresholds from what you measure, then tighten them for the pages where speed is the product.

Step 4: Watch the certificate underneath

Every monitor so far speaks HTTPS, and every HTTPS request starts with the same TLS handshake against the same certificate. A URL monitor fails the moment that certificate expires. That is one layer too late: you want to hear about it while there is still time to renew.
__checks__/certificate.check.ts
The SSL monitor connects to the host, completes a handshake, and inspects what comes back: expiry, hostname match, chain trust, and the negotiated protocol. It fails when the certificate has fewer than 14 days left, and also when the chain is broken or the hostname does not match, which are the same failures a browser would show your users. Test everything, then deploy:
Terminal
Terminal
Terminal
After the first runs, the certificate monitor shows a handshake from each location:
A Checkly SSL monitor detail page for Shop certificate, passing, running every minute from N. Virginia and Ireland, with a 9 millisecond and a 141 millisecond handshake

Verify it works

Break both layers on purpose. In __checks__/slow.check.ts, change the URL to https://httpbin.org/status/503, a page that always answers with a server error. In __checks__/certificate.check.ts, change the hostname to expired.badssl.com, a host that serves an expired certificate on purpose. Deploy. Within a minute, the slow page monitor fails from both locations. Its error groups show both what happened and which assertion it broke: a 503 that was expected to equal 200.
A Checkly URL monitor detail page for Slow page, failing, with failed runs from Ireland and N. Virginia after four passing ones, and error groups reading Expected 503 to be equal to 200 and HTTP 503 Service Unavailable
The certificate monitor fails too. There is no status code at this layer, so the error names the handshake step that broke:
A Checkly SSL monitor detail page for Shop certificate, failing, with failed runs from N. Virginia and Ireland after four passing ones, and one error group reading chain verification failed
Change both values back and deploy again. The next run from each location recovers both monitors. Nothing else in the group changed, because everything else was generated from the same list and the same defaults.

Next

Monitor the content your customers need to see: a URL monitor proves a page answered, not what it shows. Assert that the text that sells is on the page, in the right place.

Reference