Skip to content

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

Issued to
example.com
Issued by
Let's Encrypt
Valid until
28 Nov 2026
  1. Valid

    Leaf is good

  2. Mail

    14 days

  3. Incident

    3 days

The certificate visitors see. Mail at 14 days, incident at 3.

DNS

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

What you see on a URL in Watch. Sample dates — not a live check.

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.