A 200 response can still break your API integration
An API can be up, fast, and still break every client that depends on it. A field changes from an object to an array. An optional property disappears. A path is renamed in the OpenAPI document. The uptime check stays green because the server did exactly what it was asked to do: it returned 200 OK . That gap is what I wanted to monitor. Uptime answers only one question A basic status probe can tell…
Even when an API looks fast and responsive, it can still cause breakdowns in the software that relies on it. Changes can happen in ways that are hard to detect. A field that was once an object might suddenly become an array. Important optional properties could vanish. Paths in the OpenAPI document could be renamed without warning.
Yet the uptime monitors might still show green because the server is simply doing what it's programmed to do: sending a 200 OK response. This is the gap I wanted to fill. Uptime checks only tell us if DNS resolved, TLS completed, the server responded within a time limit, and if the response arrived at all. But they don't tell us if the response data still aligns with what our code expects. Consider this example: yesterday's payload was a simple object:
{
customer: {
id: "cus_42",
status: "active"
}
}
Today, the same endpoint returns an array:
{
customer: [
{
id: "cus_42",
status: "active"
}
]
}
Both responses are valid JSON and can arrive in 120 milliseconds, bearing a 200 status code. However, the first response perfectly matches a client written for yesterday's contract, while the second one does not. Four types of API changes can break dependencies: Availability (status, timeout, TLS, DNS failures), Shape (fields added or removed, types changed, objects becoming arrays), Contract (OpenAPI paths, methods, parameters, or response schemas changed), and Behavior (shape stays the same, but meaning changes).
The first three can be monitored automatically, but the fourth usually requires domain-specific checks. Mixing these together can make alerts vague and unhelpful. Instead, we should separate these issues and provide clear alerts. Raw JSON diffs are not helpful as they catch even expected changes like timestamps or request IDs. A useful diff should look like this:
{
rule: "type_changed",
path: "$.customer",
before: "object",
after: "array",
severity: "breaking"
}
This level of detail is small enough for webhooks, CI checks, or incident timelines, and it directly points to where to look. Here's a practical monitoring loop for each external API dependency:
1. Probe a representative endpoint.
2. Remove known volatile fields.
3. Derive a normalized response shape.
4. Compare it with the last accepted observation.
5. Classify the change.
6. Keep the evidence needed to reproduce it.
7. Alert only when a rule says the change matters.
The "last accepted observation" is crucial. If every response automatically becomes the new baseline, a single malformed response can quietly normalize the failure. Also, avoid testing with private credentials unless the monitor has a clear data-handling model. Public HTTPS targets and synthetic test accounts are safer starting points.
Based on this, I created a small developer API called DependSignal. It checks the status and latency of public APIs, compares JSON response shapes, and returns field paths with rule evidence. It's designed to catch upstream drift before users report it. The service offers a no-key sample to allow inspection without creating credentials: https://dependsignal.strigsapi.com/.
The part I'm still refining is defining what constitutes a breaking API change for different teams. Is it status, schema, behavior, or some combination?
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.