Keyword & Content

A 200 OK doesn't prove the page is right. Hoppla reads what it actually says.

A page can return HTTP 200, render "Application Error," and still sail through a plain uptime check. The server answered, even though your users hit a wall. Hoppla layers content assertions onto that same uptime check: require the keyword that proves the page rendered, forbid the strings that mean it didn't. A rule fails, the check fails. Availability-grade, not a polite advisory.

TEXT / SAMPLE OUTPUT

GET / → 200 · body contains "Add to cart"? MISS · recheck hel → MISS · DOWN

Fictional values. Not a live measurement.

01 / What it does

Assert what the page says, not just that it answered

You attach response-body rules to the uptime check: a substring that must be present (contains), one that must never appear (not_contains), an exact match (equals), or a regex pattern (matches). On every run Hoppla reads the response body (the HTML your server sends, before any JavaScript runs) and tests each rule. If the expected keyword is missing, or a forbidden string like "Error" or "Maintenance" shows up, the check fails, even on a clean HTTP 200. This is an availability assertion: a broken-but-answering page counts as down.

What’s included

  • Four conditions: contains, not_contains, equals, matches (regex)
  • Availability-grade: a failing rule fails the uptime check, not just a warning
  • Catches HTTP 200 responses that render an error or maintenance page
  • Stacks with expected_status_code, response_header_rules, and expected_final_url on one check
  • ReDoS-guarded regex: 500-char pattern cap, nested quantifiers blocked
  • pcre.backtrack_limit capped at 10,000 so a bad pattern can't hang the worker
  • Rides the existing uptime check: one monitor, one timeline, one bill
02 / How it works

Under the hood.

01

Read the response body

The same uptime worker that hits your endpoint reads up to the first 1 MB of the response body, following redirects up to your max-redirect limit. No separate crawler, no second monitor. Content rules ride on the check you already run.

02

Test every body rule

Each response_body_rule tests one condition against the body: contains (the keyword must be there), not_contains (the string must be absent), equals (exact match), or matches (regex). Stack several at once, alongside status-code, response-header, and final-URL assertions on the same check.

03

Run regex behind a ReDoS guard

Patterns are capped at 500 characters, nested quantifiers are blocked, and pcre.backtrack_limit is held at 10,000. A pathological pattern can't hang the worker. A pattern the guard refuses counts as no match, so the rule fails: give a new pattern a test run before you rely on it.

04

Fail, recheck, then alert

If any rule fails, the uptime check fails, and goes through the same second-region recheck as any outage before it alerts. The page that returns 200 but renders "Application Error" lands on the monitor's timeline as a confirmed incident, not a quiet pass.

03 / Why it matters

The part that actually moves the needle.

01200 ≠ rendered

A status code lies

An app can crash, render a stack trace or a maintenance splash, and still return HTTP 200 because the web server itself is fine. Status-only monitoring calls that healthy. A rule that requires your real page text calls it what it is: down.

02contains · not_contains · equals · matches

Four ways to pin the truth

Require the keyword that only shows up when the page rendered right. Forbid the ones that mean it didn't: "Error," "Maintenance." Or match an exact value, or a regex. Most broken-render failures have an assertion shaped like them.

03500-char + 10k backtrack cap

Regex that can't stall the worker

Body matching uses real regex, but the guard caps pattern length, blocks nested quantifiers, and limits backtracking to 10,000 steps. You get pattern power without a catastrophic-backtrack pattern stalling your own monitoring.

04 / For every team

Whoever you are, this lands differently.

Solo SaaS founder

Your framework caught an unhandled exception, rendered its friendly error page, and returned 200 with it. Uptime Robot sees green. Your signups are silently dead. Add not_contains "Application Error" plus a contains rule for the heading that only appears when the dashboard truly loads, and the check fails on the next run after the page starts lying, re-tested from a second region first, so the buzz next to your bed means something.

Small agency

A theme update quietly drops the checkout button from a client's product pages. The page is up, the server's happy, and the first you hear of it is the client asking why nobody can buy. Assert that the exact CTA text, "Add to cart," is present in the HTML. The day it vanishes, the uptime check fails, and you can often patch it before the ticket arrives.

Large agency

Nobody hand-writes a rule per site at your volume. Define one ruleset (require the brand string, forbid the maintenance banner, match the footer copyright regex) and apply it across every site on the same stack. Account managers can report content integrity, not just reachability, and one broken-render failure mode is caught everywhere it can happen.

Reseller / hosting provider

You resell content-integrity monitoring under your own brand and domain. Your customers never see the word response_body_rule. They see your service catch their broken homepage, often before most visitors notice. The failing check raises an incident wearing your alert prefix on your status pages, so "we caught it and fixed it" is your message, not theirs.

Switching tools

Monitoring somewhere else? Bring your setup with you.

Import the monitors you already run in another tool. What comes across depends on the provider. Run both side by side for 24 hours or 7 days before you switch.

  • Guided import
  • Shadow run before you switch
  • Coverage varies by provider
Import from
  • Oh Dear
  • Uptime Robot
  • Better Stack
  • Pingdom
  • StatusCakeBeta
  • CronitorBeta
  • Healthchecks.ioBeta
  • Statuspage

The importer opens in your workspace once you have access.

Get early access
FOR HOSTERS & RESELLERS

Content-integrity assertions on every customer site, under your brand.

See the reseller program
05 / FAQ

Straight answers.

How is this different from a dedicated keyword uptime monitor?

A keyword monitor is a separate product checking one thing: is the word there. In Hoppla the keyword rule lives on the same uptime check as your status-code, header, and final-URL assertions: one monitor, one timeline, one bill. And it isn't only "contains": you also get not_contains, exact equals, and ReDoS-guarded regex.

Does a failed content rule just warn me, or does it count as downtime?

It counts as down. Response-body rules are availability-grade: if a rule fails, the uptime check fails and runs through the same second-region recheck before it alerts. A page that returns 200 but renders "Application Error" becomes a confirmed incident, not an advisory note.

Can I match the body with a regex?

Yes, the matches condition takes a regex, written with delimiters like /pattern/. It runs behind a ReDoS guard: patterns capped at 500 characters, nested quantifiers blocked, and PCRE backtracking limited to 10,000 steps. A pattern the guard refuses counts as no match, so the rule fails rather than stalling the check.

What exactly can I assert on?

That a substring is present (contains), that a forbidden string is absent (not_contains), that the body exactly equals a value (equals), or that it matches a regex (matches). Combine any of those with the expected status code, response-header rules, and the expected final URL after redirects, all on the same check.

Your next step

Stop trusting the status code. Monitor what the page actually says.

Checks, alerts and status pages in one workspace. Now in early access: join the list for an invite.