Checking response content: JSON, XML, HTML and headers
A server that answers 200 OK with an error page, an empty list or yesterday's data is up by every status-code measure and broken for everyone using it. Pingsured can check what a response contains, not only that it arrived.
Apart from the status code, every check below is optional, and you can combine them freely. A check passes only when the status code matches and every content check you have configured passes.
Status code
The expected status is a single code, a list or a range: 200, 200,204 or 200-299. Anything else is a failure. The default is 200.
Text in the body
The simplest content check: the response body must contain a piece of text, such as a product name or a "healthy" marker your health endpoint prints. It is a plain substring match of up to 1,024 characters.
JSON fields (JSONPath)
For APIs, select a value with a JSONPath expression and compare it. For example, a health endpoint that answers {"status": "ok", "queue": {"depth": 12}} can be checked with:
| Path | Operator | Value |
|---|---|---|
$.status | equals | ok |
$.queue.depth | less than | 1000 |
Available operators:
- exists / does not exist — the path selects something, or nothing.
- equals / not equals — typed: the number
12does not equal the string"12". - contains and matches (a regular expression) for text.
- greater than / less than (or equal to) for numbers.
- count comparisons for the number of matches, such as "at least one item in
$.items[*]". - age comparisons for timestamps, described under freshness below.
When a path selects several values, the first one is compared. You can add up to 16 JSON checks per ping.
XML elements (XPath)
The same idea for XML responses — feeds, SOAP services, sitemaps — with XPath expressions such as /rss/channel/item (count at least 1) or //status/text() (equals ok). Operators are exists, does not exist, equals, contains, matches, the count comparisons and the age comparisons. A response that is not well-formed XML fails every XML check.
HTML elements (CSS selectors)
For web pages, pick an element with a CSS selector — or an XPath expression, if you prefer — and check its text or one of its attributes. Text is compared with its whitespace normalised, so line breaks in the markup do not matter. Typical uses:
- the price element on a product page exists and is not empty;
h1.titlecontains your headline, so a blank template or a maintenance page is caught;- a
metatag'scontentattribute has the value it should.
Response headers
Headers can be checked in two ways: an exact match per header, or the same operators as above — exists, does not exist, equals, contains, matches, numeric comparisons and age. Header checks do not read the body.
Freshness: is the data current?
The age operators read a value as a timestamp and compare how old it is, in seconds. "$.updated_at age less than 3600" fails as soon as the newest data is more than an hour old — the classic case of an export, a cache or a feed that quietly stopped updating while the server keeps answering.
Recognised formats:
- ISO 8601 / RFC 3339, such as
2026-10-09T14:30:00Z(a time without a zone is read as UTC); - HTTP dates, so a
Last-Modifiedheader works as is; - Unix time in seconds or in milliseconds.
Limits worth knowing
- Only the first 1 MB of the body is read.
- Checks send
GETorHEADrequests. Other methods and request bodies are not available yet: they can change data on the server being checked, so they will need proof that you own the domain first. - You can add up to 20 request headers and HTTP basic authentication, for endpoints that need a token or a login.
- The User-Agent is always
Pingsured/1.0, with a link to the page that explains our requests to server operators.