JSON API Monitoring: Catch Silent Data Breakage
Catch schema drift, empty feeds, and record-count drops that HTTP 200 checks miss. Monitor JSON APIs in CI with a Python standard-library-only GitHub Action.

Your API Says "200 OK." Is Your Data Still Working?
A JSON endpoint can return HTTP 200 while quietly breaking the system that depends on it. A field disappears, a value changes type, or a feed that usually contains hundreds of records suddenly returns a dozen. Your HTTP client still sees success. Your downstream code may get missing salaries, incomplete reports, or an empty job board.
That gap is easy to miss because a basic health check answers only one question: did the server respond? It doesn't tell you whether the response still has the structure and volume your application expects. A loud 500 error is annoying, but a "successful" response with unusable data can sit unnoticed for days.
This article lays out a practical way to think about silent JSON API failures - and a small monitoring step that helps catch them early. We'll cover schema drift, sudden record-count drops, and full outages, then show how to use jobfeed-watchdog, a Python standard-library-only CLI and GitHub Action, to compare responses against a baseline.
Why an HTTP 200 check is not enough
A status-code check is a liveness signal. It tells you a request reached a server and the server returned a response classified as successful. That's useful, but it's not a data-quality check.
Take a job feed used by an internal listing page. The endpoint stays up, but the provider renames salary to compensation. The response is still valid JSON, and it still returns 200. If your client expects the old key, you can end up with blank salary information. If missing values get handled quietly, you may see no exception - and no alert.
The same problem shows up in other integrations too:
- A market-data API returns an empty array after a provider-side issue.
- A vendor changes an identifier from a number to a string.
- A feed's record count drops sharply after a filter or pagination change.
- An API keeps its old fields but removes one that a downstream process relies on.
- The response is syntactically valid JSON, but it no longer matches what the consumer assumes.
In all of these cases, the transport layer is fine. The contract between the producer and consumer isn't.
Liveness and data health are different checks
It helps to separate three questions:
- Is the endpoint reachable? The request succeeds and produces a response.
- Is the response parseable? The body is valid JSON and can be decoded.
- Is the returned data still usable? The response has the expected structure and plausible volume.
An uptime monitor is usually built for the first question. Your application may cover parts of the second and third through validation or tests, but those checks often run only after data reaches a pipeline - or only when code gets deployed.
A lightweight external check can fill that gap by polling the endpoint and comparing the response to a known baseline. It doesn't replace application validation; it gives you an earlier signal that something changed before the damage spreads.
Why silent failures can be worse than loud ones
A 500 response is visible. It usually triggers existing error handling, monitoring, or retries. A 200 response with the wrong body can pass all the usual "did we get something?" checks unless you validate the data.
That creates a misleading operational picture: dashboards look green, scheduled jobs complete, and users still get incomplete results. The longer it goes unnoticed, the harder it gets to figure out when the data first became unreliable.
This gets extra painful when you don't control the API. A public provider might change its output, apply a new filter, or have a partial outage without coordinating with every consumer. So you want a check at the boundary where you consume the dependency.
What a JSON API watchdog should detect
A useful watchdog doesn't try to flag every tiny difference. It focuses on a few signals that usually mean a real regression. Jobfeed-watchdog (JFW) is built around three: structural changes, sudden record-count collapse, and full outage. It snapshots response structure and record counts, then compares later responses against a baseline.
Schema drift: fields and types change
Schema drift is when the "shape" of the data changes. A field can be added, removed, or returned with a different type. For instance, a field that used to be consistently a string might start coming back as null, or a numeric identifier might show up as text.
Not every schema change is a problem. An added optional field might be harmless. Removing a field can break consumers that rely on it. A type change might be fine for a tolerant client and breaking for a strict one. The point of a drift alert is simple: it tells you to inspect the change rather than assume everything still matches what you wrote.
Count collapse: the endpoint returns much less data
A count-collapse check looks for a sharp reduction in the number of records returned. If a feed normally has hundreds of jobs and suddenly shows twelve, the endpoint can still be "healthy" from an HTTP perspective while the data is clearly not.
This isn't about expecting one fixed count. Feeds grow and shrink. A good check should look for meaningful regressions, not normal movement. JFW is designed to alert on real regression rather than ordinary feed growth, and its count comparison is meant to catch the silent-outage pattern.
The threshold depends on the source. A daily job feed might be volatile; an inventory list might only change when products update and could be steadier. Before you trust an alert, compare it to the feed's normal variation and decide what reduction would actually affect users or downstream processing.
Full outage: no usable response
The watchdog should also separate "unavailable" from "available but useless." An endpoint can respond successfully and still return a broken or unexpectedly empty result. Those cases often need different investigation paths.
A network failure or an unsuccessful HTTP response points toward availability, connectivity, or provider service health. A successful response with a changed schema points toward a contract change. An unusually small result set can suggest a partial failure, a filter change, or a data issue.
The goal isn't to build a full monitoring platform for every API. It's to catch a small set of high-impact failure modes cheaply - and give the person investigating enough context to start in the right place.
How to add jobfeed-watchdog to your workflow
JFW is a free, open-source CLI and GitHub Action built with Python's standard library. One major design choice is that it avoids third-party Python dependencies. That keeps the installation surface smaller and makes it easier to run in CI without babysitting an extra dependency stack.
The basic CLI invocation is:
pip install jobfeed-watchdog
jobfeed-watchdog https://api.example.com/v1/jobs --baseline baseline.json
The first command installs the package. The second tells the tool which API endpoint to check and which baseline file to compare against. Start with the project's current docs for the baseline setup process and any configuration options; the snippet above shows the core idea, not every production detail.
Start with one important endpoint
Don't begin by monitoring every URL your system calls. Pick a feed where a failure would be noticeable: a job listing source, a supplier catalog, a public market-price feed, or a data endpoint used in a scheduled report.
Then write down what a "meaningful failure" looks like. For example:
- A required field disappears or changes type.
- A feed that usually returns a substantial number of records collapses unexpectedly.
- The endpoint stops returning a usable response.
This step avoids a common monitoring trap: collecting alerts without agreeing on what action they should trigger. If a warning doesn't change what you investigate or do, it probably shouldn't be in version one.
Establish and maintain the baseline deliberately
A baseline is the reference response the tool uses. It's only useful if it represents a known-good state. If you capture a broken or unusually low-volume response as the baseline, future checks can look "normal" even when they shouldn't.
Before creating or updating a baseline, inspect the current response and confirm it's representative. Store the baseline somewhere the team can review, and treat baseline updates as a decision - not routine housekeeping. If a provider intentionally changes its API, update the reference only after you check the impact on your consumer.
There's a trade-off here. A baseline that never changes will eventually create alerts when a legitimate API evolution happens. A baseline that gets refreshed automatically without review can quietly absorb real regressions.
Usually, the middle ground is lightweight review: investigate the difference, confirm whether it was expected, and update the baseline only after the change is accepted.
Run the check in CI and define the response
JFW is meant to run in CI, including via GitHub Actions. A scheduled workflow can check an API even when nothing in your application was deployed - which matters because providers can change responses independently of your code.
Keep the operational flow straightforward:
- Poll the endpoint on a schedule that fits its importance and update frequency.
- Compare response structure and record count with the baseline.
- Surface a regression through your existing CI or notification process.
- When something changes, figure out whether it's an outage, expected evolution, or a break that affects consumers.
- Update the baseline only after you understand the change.
JFW is described as both a CLI and a GitHub Action, but exact workflow syntax and inputs can change. Use the current project documentation rather than copying an unverified YAML example. The key design choice is repeatability and visibility - so the check doesn't become "another script nobody owns."
Baseline design, alert quality, and limitations
A watchdog is only useful if its alerts lead to action. Too few checks and silent failures slip through. Too many checks - or checks that treat normal day-to-day variation as incidents - creates noise people learn to ignore.
Tune checks to the API's behavior
A stable reference works well when the API has a predictable response shape and volume. A rapidly changing feed needs more care. A job listing source might vary by weekday or season; a product catalog might change only when inventory updates. Those patterns should shape how you interpret count changes and how often you run the monitor.
Ask two questions: what's the cost of missing a real failure, and what's the cost of a false alarm? If a missing field could break a financial report, schema drift deserves quick attention. If record counts swing normally by a small amount, a monitor that treats every dip like an incident will become counterproductive. Start conservatively, watch what happens, and adjust based on actual feed behavior.
Use a watchdog alongside consumer validation
A structural snapshot can't replace tests for business meaning. A response can match the baseline and still contain stale, duplicated, or incorrect values. And a field can exist but still contain content your product can't use.
Use layers that match the risk:
- Availability monitoring checks whether the endpoint can be reached.
- Shape and count monitoring catches changes like drift or collapse.
- Consumer validation checks required fields, domain rules, and downstream behavior.
- Operational review confirms whether a detected change is expected and assigns ownership.
You don't need all four layers for every low-risk integration. But if a feed drives user-facing or business-critical behavior, relying on only an HTTP status check is a fragile assumption.
Be clear about what standard-library-only buys you
Using only Python's standard library keeps the dependency footprint small. That can make installation and maintenance easier, especially in controlled CI environments. But it doesn't mean there's no operational work. You still need to handle credentials for authenticated APIs, deal with network behavior, store and review baselines, and decide who responds to alerts.
The project's description focuses on public JSON endpoints and the failure modes discussed above. Don't assume a generic structure-and-count comparison understands pagination, rate limits, authentication flows, business-specific semantics, or every detail of an API contract. Double-check the tool's current capabilities for your endpoint before you rely on it in production.
For a public endpoint that returns a useful JSON body without complicated setup, this approach can be a good fit: a small check can catch regressions that a ping won't. For a heavily authenticated API with complex pagination and strict domain rules, JFW is more likely to be one piece of a broader validation system.
Conclusion
An HTTP 200 response tells you an endpoint answered. It doesn't tell you that the data your system consumes is still complete, compatible, and usable. Schema drift, count collapse, and empty responses can all pass a simple liveness check while quietly degrading a product or pipeline.
Jobfeed-watchdog helps close part of that gap by snapshotting a JSON response, comparing structure and record count to a baseline, and running the check from a CLI or GitHub Actions workflow. Its standard-library-only approach keeps dependencies light - but the value still depends on having a representative baseline and on alerts that reflect real operational risk.
Start with one public API that matters, inspect its normal behavior, and make the check part of a workflow someone owns. For the project details and latest usage, read the original jobfeed-watchdog announcement. Then ask the practical question: which silent failure in your feeds would be the most expensive to discover late?