Watch
Hear about downtime first.
They clicked Reject. The site still has to answer. Watch is HTTP, TLS, and DNS on a hostname you already added — so you know before the client does. Not a second product. Not a crawl.
What Watch checks
Watch is more than a ping. Each check is an HTTP GET from Europe — not a real browser. It is included on Starter and Growth, on a hostname you already added.
Three European cities
Frankfurt checks every window. Dublin runs when Frankfurt failed, or when Frankfurt answered but first byte was slow. London is a third sample only after a fail — not for slowness.
DNS
Each check resolves the hostname (IPv4, then IPv6 when needed) before it requests the URL. If the address set moves, we mail you.
HTTP status
The response must match the status you expect. The default is 200–399. You can require a single code.
Redirects
A redirect that leaves your hostname fails the check.
Page content
You can require a short phrase in the body, or forbid one. A keyword check is its own row — the page can be up while the phrase is missing.
Speed
We record first byte (TTFB) and total load time. Slow is based on first byte. The default threshold is 3 seconds; 0 turns Slow off.
Daily sitemap
Once a day we fetch /sitemap.xml (or the path you set) and visit the first 40 URLs on the same hostname. Off-host URLs are skipped. A bad result is checked again after 30 minutes before we alert. Not an HTML crawl.
Certificate
On a successful HTTPS check we read the leaf certificate visitors see. Mail at 14 days left, an incident at 3. We do not walk the full chain or grade ciphers.
Domain expiry
Once a day we look up the registry (RDAP). Mail at 30 days left, an incident at 7.
Visitor 404s and 500s
Watch counts cfa('404') and cfa('500') events from real visitors in the last hour. Over the threshold (default 10; 0 is off) we mail you. The hostname can still be Up.
Heartbeat
On Starter and Growth you can POST a heartbeat for a cron or a job. If no beat arrives within the grace you set (minimum 60 seconds, maximum 24 hours), Watch opens a heartbeat incident. Empty grace is off.
TCP port
You can add a TCP check for one port on a hostname you already added. That is a connect, not a port scan.
What Watch is not
Watch is not a real browser and not a transaction test. It does not run JavaScript or click through a checkout.
A single slow sample never sends mail. Slow mail goes out only after Dublin confirms slowness in two consecutive windows. A real outage — two windows where Frankfurt and Dublin both failed — alerts promptly. One city down and one up stays Up.
Starter checks every 3 minutes (10 pages). Growth checks every minute (25 pages). Hobby shows the Watch tab; checks start on Starter.
Ping vs Watch
What it sends
- A simple ping
- Often ICMP echo, or one HTTP request
- Watch
- An HTTP GET — not a rendered page
Where from
- A simple ping
- Usually one location
- Watch
- Frankfurt every window; Dublin confirms a fail or a slow first byte; London only after a fail
What counts as up
- A simple ping
- Any answer may count as up
- Watch
- DNS, the status you expect (default 200–399), and no redirect off your hostname. Optional must-contain or must-not-contain phrases.
Speed
- A simple ping
- Sometimes round-trip time
- Watch
- First byte and total load time. Slow is first byte over your threshold (default 3 seconds).
Certificate and domain
- A simple ping
- No
- Watch
- Leaf certificate: mail at 14 days, incident at 3. Registry expiry (RDAP, once a day): mail at 30 days, incident at 7.
Sitemap and visitor errors
- A simple ping
- No
- Watch
- Daily sitemap, first 40 same-host URLs. Hourly visitor 404 and 500 rates from cfa('404') and cfa('500').
Cron jobs
- A simple ping
- No
- Watch
- Optional heartbeat on Starter and Growth. Empty grace is off.
When it alerts
- A simple ping
- Often on the first failed ping
- Watch
- Down after two windows where Frankfurt and Dublin both fail. Slow after two windows where both are slow. One slow sample never mails.
Browser checkout test
- A simple ping
- No
- Watch
- No — Watch does not run JavaScript or click through a checkout.
Stop hearing it from the client
Most teams find out a site is down from an email, a Slack ping from the client, or a one-star review. By then checkout already failed. Watch requests the URL you already track for pageviews. If it does not answer, you get the mail. The public status page is what you send instead of “we’re looking into it.”
One dashboard: analytics and Watch. You do not log into a second uptime tool to answer “is it up?”
Down is two cities, not one blip
Frankfurt fetches every window. Dublin runs when Frankfurt failed that window, and also when Frankfurt answered slowly. Down still means both failed. One fail and one ok stays Up. That is how we avoid waking you because one network path hiccuped.
The down mail names the domain, both cities, HTTP status, first byte, or the error class. Two fails to open, two oks to close — not a flap on the first timeout.
A 200 is not always fine
Default expected status is 200-399. You can require a single code. Optionally the body must contain a short phrase, or must not contain one. A 200 that still says Error is then Down, same dual-region rule.
Slow is separate. If first byte is over your threshold (default 3 seconds, 0 is off) in Frankfurt, Dublin measures that same window. We mark Slow and mail only when both cities are slow on two checks in a row. One slow sample does not. A Dublin timeout, failure, or missing time is not confirmation. The hostname still answered. That is the early warning Oh Dear talks about — without calling it an outage.
Certificate and domain, before the browser warning
An expired certificate is a full stop for visitors: “your connection is not private.” Watch reads days left and the issuer from the leaf certificate on an ok check. Mail at 14 days, an incident at 3. Domain expiry from the registry (RDAP, at most once a day): mail at 30 days, an incident at 7. If the DNS set moves, we mail that too.
What you see on a URL in Watch. Sample dates — not a live check.
We do not walk intermediates to the root, flag SHA-1, or grade ciphers. That is Oh Dear’s certificate product. Watch is the date on the certificate the browser shows — enough to renew before the lock turns red.
CertificateValid
18
days
- Issued to
- example.com
- Issued by
- Let's Encrypt
- Valid until
- 28 Nov 2026
Valid
Leaf is good
Mail
14 days
Incident
3 days
The certificate visitors see. Mail at 14 days, incident at 3.
2
Addresses this hostname points to.
- 23.21.150.4
- 2600:1f18:1234:5678::1
DomainOk
241d
RDAP once a day. Mail at 30 days, incident at 7.
9 Jul 2027
SitemapOk
24
Listed URLs on this hostname answered.
/sitemap.xml · 24 checked · 31 Aug 2026
The sitemap you hand to Google
Once a day Watch fetches /sitemap.xml (or a path you set), including one level of a sitemap index. Gzipped files are fine. It visits the first 40 URLs on this hostname. Off-host URLs are skipped, not failed. A missing default file is not an incident — invalid XML, an unreachable file, or listed URLs that miss 200–399 are. Empty the path to turn it off. That is not Oh Dear’s 5,000-URL crawl, and it is not an HTML link check.
A status page they can open without a login
During an incident the same questions arrive a dozen times. A public page answers them: “No problems detected.” — or that it is down — every watched URL with a 60-day bar, and a 7-day calendar that also says when nothing happened.
URL https://www.cookiefreeanalytics.com/status/{token}. Cached 15 seconds. Hosted here, so it can still load when their origin does not. Starter and Growth can subscribe for down/back mail. The owner can type one sentence on an open incident. Growth may CNAME status.yourhost to cname.vercel-dns.com (DNS only, grey cloud). Apex forbidden. We do not hijack your homepage. Maintenance silences downtime mail inside a window you set.
A monthly page for the retainer
Starter and Growth get a monthly Watch report for the site: uptime they can open without a login. Growth can put the agency name and logo on it. You are not grading your own homework — the numbers come from checks we ran. That is the paper trail Oh Dear sells as client reporting; here it sits next to the analytics you already send on Monday.
Who it is for
Agencies that should know before the client. Shops where checkout must answer. Anyone already counting pageviews here who does not want a second uptime login. Marketing that launched a campaign and needs the landing to stay up.
Viewers on the plan see the board. They do not get a seat SKU. Extra Watch mail: Starter 2, Growth 10, after they confirm a link.
What Watch is not
Cookie Free Analytics counts the pageview after Reject. Watch asks whether that same hostname answered. Not a second product, not a crawl, no extra SKU. Not Oh Dear and not UptimeRobot. No HTML crawl, no port scan of the internet, no SMS, no PagerDuty. One TCP port on a hostname you already added is allowed. Visitor 404s come from cfa('404'), 500s from cfa('500'). Alerts are email, confirmed extra inboxes, a Growth Slack webhook, and a Starter+ generic webhook.
What it is, exactly
One click on a site: Watch this site. Default URL is https://{hostname}/. Extra HTTPS paths, a keyword check (its own row — the page can be up while the phrase is missing), or one TCP port on that hostname. A hostname that is not a site on the account is refused. TCP is not a port scan.
Watch is on Starter (10 slots / 3 min) and Growth (25 / 1 min). Hobby sees the tab; checks start after Starter. Cancel Stripe and Watch pauses. No extra SKU — it follows the invoice.
Questions before the first check
- What is Watch?
- Uptime, TLS, DNS, and a public status page on a hostname you already added to Cookie Free Analytics. Frankfurt checks every window. Dublin confirms a fail or a slow response. Down means both failed. On Starter and Growth — it follows the invoice. Not a second product.
- Is Watch just a ping?
- No. A simple ping asks whether a host answers. Watch sends an HTTP GET from Frankfurt every window, confirms a fail or a slow first byte from Dublin, and uses London only after a fail. It checks DNS, the status you expect, redirects that leave your hostname, optional page phrases, first byte and total load time, the leaf certificate, domain expiry, a daily sitemap of the first 40 same-host URLs, visitor 404 and 500 rates, an optional TCP port, and heartbeats for cron jobs. Slow mail waits for two confirmed windows. Down mail waits for two windows where Frankfurt and Dublin both failed. It does not run JavaScript or click through a checkout.
- Do I need to install an agent?
- No. Watch requests your URL from Europe, the way a visitor would. Nothing runs on your server. For a cron or a job that is not a public page, you can POST a heartbeat.
- How often do you check?
- Starter every 3 minutes (10 URLs). Growth every 1 minute (25 URLs). Hobby sees the Watch tab; checks start after Starter.
- Will I get false alarms from one flaky city?
- No. Frankfurt up is enough to stay Up. Dublin confirms a fail, and also a slow Frankfurt response. One city down and one up stays Up (recorded as degraded). Down mail goes out when both fail twice. Slow mail goes out only when both cities are slow on two checks in a row.
- Is slow the same as down?
- No. If the hostname answered, it is not down. We mark Slow only when Frankfurt and Dublin are both over your first-byte threshold on two checks in a row. Default 3 seconds. One city, or one slow check, does not mail you. 0 turns Slow off.
- Do you monitor SSL certificates?
- The leaf — days left and issuer, on every ok check. Mail at 14 days, an incident at 3. We do not walk the chain, flag SHA-1, or grade ciphers.
- Can I watch /checkout, not just the homepage?
- Yes, extra paths on the same hostname: /login, /checkout, /api/health. A hostname that is not a site on the account is refused.
- Do you crawl for broken links?
- No HTML crawl. Visitor 404s come from cfa('404') on your not-found page, 500s from cfa('500') on the error page — the same event as a signup, not billed. Watch mails if those hits spike. The hostname can still be Up.
- Do you monitor sitemaps?
- Once a day we fetch /sitemap.xml (or the path you set), including one level of index. We visit the first 40 URLs on this hostname. Off-host URLs are skipped. A missing default sitemap is not an incident. Invalid XML, an unreachable file, or listed URLs that fail 200–399 are. Not Oh Dear’s 5,000-URL crawl.
- Is there a public status page?
- Yes. No login. Headline, every watched URL with a 60-day bar, and a 7-day incident calendar. Starter and Growth can subscribe for down/back mail. The owner can type one sentence on an open incident. Growth may CNAME status.yourhost to cname.vercel-dns.com (DNS only, grey cloud). Apex forbidden. We do not rewire your homepage.
- Can agencies put their name on reports?
- Growth: agency name and logo on the monthly report and on the status page. Starter still gets the report. Viewers are on the plan — not a seat SKU.
- Is Watch a separate bill?
- No Watch SKU. Starter from €4 includes Watch. Growth from €8. Cancel Stripe and checks pause. Oh Dear’s public list on 31 August 2026 starts at $17 / month for 2 sites as a dedicated monitor (USD, ex VAT). We are cookieless analytics that also watches the hostname you already added.
- Where do checks run?
- Cloudflare EU: Frankfurt every window. Dublin confirms a fail or a slow response. London is a third sample only after a fail. Allow User-Agent Cookie-Free-Analytics-Watch/1.0. We do not publish a static unicast IP list.
Checker identity
User-Agent: Cookie-Free-Analytics-Watch/1.0 (+https://www.cookiefreeanalytics.com/docs/watch) X-CFA-Watch: <per-monitor public token> Accept: text/html,application/json;q=0.9,*/*;q=0.8
Egress is Cloudflare’s EU anycast (Frankfurt, Dublin, and London colos). Frankfurt checks every window. Dublin confirms a fail or a slow response. London is a third sample only after a fail. Allow that User-Agent and header. Cloudflare publishes IP ranges at cloudflare.com/ips. We do not publish a static unicast list.
Heartbeat
Starter and Growth, off until you set a grace on the dashboard. Empty grace is off. Minimum 60 seconds, max 24 hours. Cron or a deploy hook. If no beat arrives within the grace, Watch opens a heartbeat incident. The beat token is on the dashboard. It is not the status-page token. Sharing the status page does not refresh the heartbeat.
# Starter and Growth. Grace set on the dashboard. Empty grace = off. curl -sS -X POST https://www.cookiefreeanalytics.com/api/watch/beat/BEAT_TOKEN # 204
Not-found spike
Visitor 404s are not a crawl. Fire cfa('404') on the not-found page — same event as a signup, not billed. Watch counts those hits in the last hour. Over the threshold (default 10, 0 is off) mails the owner with the top paths. The hostname can still be Up.
Server-error spike
Same shape as not-found. Fire cfa('500') on the error page. Watch counts those hits in the last hour. Over the threshold (default 10, 0 is off) mails the owner with the top paths. The hostname can still be Up.
TLS, DNS, domain, sitemap
The dashboard shows the leaf as a certificate: days left, issuer, and when mail and an incident fire (from the TLS handshake on an ok Frankfurt check). The A set Watch last saw sits next to it, and domain expiry from the registry. RDAP runs at most once a day per hostname — not on every ping. TLS: mail at 14 days, an incident at 3. Domain: mail at 30 days, an incident at 7. DNS change mail is the set moved. Sitemap is the same daily cadence: the file, then the first 40 same-host URLs.
Alerts
Owner email is always on. Extra inboxes: Hobby 0, Starter 2, Growth 10 (they confirm a link first). Slack webhook on Growth. Generic HTTPS webhook on Starter and Growth. No SMS.
curl -sS -X POST https://example.com/hooks/cfa-watch \
-H 'content-type: application/json' \
-d '{
"event": "watch.down",
"hostname": "example.com",
"url": "https://example.com/",
"detail": "Both Frankfurt and Dublin failed.",
"status_url": "https://www.cookiefreeanalytics.com/status/TOKEN",
"dashboard_url": "https://www.cookiefreeanalytics.com/app?site=SITE_ID",
"occurred_at": "2026-08-31T09:00:00.000Z"
}'Events: watch.down, watch.back, watch.slow, watch.tls, watch.domain, watch.dns, watch.heartbeat, watch.not_found, watch.server_error, watch.sitemap. POST JSON, 5 second timeout. Non-2xx is ignored. No visitor hashes, bodies, or IPs.
Status page
The status page is for the client. Subscribe, read the sentence the owner typed, print last month. Not a status-page company.
Starter and Growth: an email box on /status/{token}. Confirm the address. Unsubscribe is one click, no account. We mail only watch.down and watch.back — not TLS, sitemap, 404, or heartbeat. Hobby has no form.
Open incidents: the owner can save one sentence (160 characters). It stays on the 7-day history after the incident closes. Empty is fine — then only the automatic line shows.
Growth: CNAME status.yourhost to cname.vercel-dns.com (DNS only, grey cloud). Apex forbidden. No orange cloud. If HTTPS does not appear, ask hello@cookiefreeanalytics.com to attach the host. The homepage on www is unchanged.
Monthly report: /app/sites/{id}/watch/report?month=YYYY-MM. Starter and Growth. Print / PDF is the browser. Growth may put an agency name and https logo on it. We do not email the report. Still not Oh Dear: no SMS, no crawl, no extra SKU.
JSON
Starter and Growth, same bearer as the rest of the read API. Hobby stays the dashboard.
GET /api/v1/sites/:id/watch GET /api/v1/sites/:id/watch/incidents?range=30d
MCP tools get_watch and get_watch_incidents. Read-only. No visitor hashes, no writes, no mail.
What it stores
URL, status code, timings, TLS expiry, DNS ok, incident timestamps. Not the response body, not target server logs, not visitors. You instruct us to request that URL. Raw checks 7 days; hour rollups then day rollups. Paid history follows the same rule as analytics history.