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.

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 only runs if Frankfurt failed that window. 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, ping, 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 ping is over your threshold (default 3 seconds, 0 is off) we mark Slow and can mail you. 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

305d

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 crawl, no port scan, no SMS, no PagerDuty. 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 paths on that hostname are allowed. A hostname that is not a site on the account is refused.

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 only runs if Frankfurt failed. Down means both failed. On Starter and Growth — it follows the invoice. Not a second product.
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 only confirms a fail. One city down and one up stays Up (recorded as degraded). Mail goes out when both fail twice.
Is slow the same as down?
No. If the hostname answered, it is not down. Over your ping threshold we mark Slow and can mail you. Default 3 seconds. 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 only to confirm 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 and Dublin colos). 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.

# Starter and Growth. Grace set on the dashboard. Empty grace = off.

curl -sS -X POST https://www.cookiefreeanalytics.com/api/watch/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.