API monitoring: how to check JSON response, not just HTTP 200
· 7 min read
In brief: A JSON API can return HTTP 200 with a body of {"status":"error","message":"DB unavailable"} - monitoring that watches only the status code reports "UP". True API monitoring also checks the content of the response, not just the HTTP layer.
In brief: A JSON API can return HTTP 200 with a body of {"status":"error","message":"DB unavailable"} - monitoring that watches only the status code reports "UP". True API monitoring also checks the content of the response, not just the HTTP layer.
The problem: HTTP 200 != working API
REST API conventions say to use status codes properly (200 OK, 4xx client error, 5xx server error). In practice:
- Some APIs always return 200, the error is in the JSON body
- An API gateway may transform 5xx into 200 with an error JSON
- Frontend BFF endpoints often wrap backends and return 200 if the communication happened, even if the backend failed
- GraphQL endpoints always return 200, errors are in the
errors[]field
From the perspective of classic monitoring (HTTP status code) everything is OK. From the real client's perspective the API is broken.
Content matching: keywords
The simplest addition to HTTP monitoring is keyword match. You define a string that must be in the response - if it's missing, alert.
Example for a health check endpoint:
GET /api/health HTTP/1.1
{
"status": "ok",
"checks": {
"database": "ok",
"redis": "ok",
"queue": "ok"
},
"version": "1.42.3"
}
Set keyword match to "status":"ok". If the DB goes down and the endpoint returns "status":"degraded", monitoring catches it.
Negative matching: what should be missing
Sometimes it's more useful to check that a certain string is NOT in the response:
"error"- error in the body"maintenance"- unexpected maintenance mode"deprecated"- API endpoint became deprecated- SQL error fragments:
"SyntaxError","undefined","null pointer"- leaking backend errors
Advanced assertions - roadmap
Plain text match has limits. For serious API monitoring, structured assertions over JSON structure (JSONPath expressions) and multi-step synthetic transactions (login -> protected endpoint -> logout) are appropriate.
JSONPath assertions and multi-step synthetic transactions are on the ePulz.io roadmap but are not currently implemented. If you need them today, combine an ePulz.io HTTP monitor with your own side script that sends the result through a heartbeat monitor (on failure simply don't send the heartbeat).
Authentication in monitoring
The monitored endpoint often requires auth. Options:
- Bearer token in Authorization header - typically long-lived monitoring token without expiry (must be stored securely)
- API key in query parameter - visible in logs, not preferred
- HMAC signature - timestamp + URL + body hash signed with a shared secret. Most secure.
- mTLS - client cert on the monitoring side. Suitable for internal APIs.
Security note: For monitoring create a dedicated account / token with minimal permissions (read-only health endpoint, not an admin token). Rotate the token regularly. If the monitoring service leaks, the entire access to the API doesn't leak.
Response time SLO
API response time is as important as the HTTP code. A client with a 30 s timeout sees no difference between "API returns 200 in 25 s" and "API timed out". From a UX standpoint both are bad.
Set up:
- Hard timeout - after 10-15 s monitoring reports DOWN
- Soft threshold - response time between 500-2000 ms = warning (degraded performance)
- Trending alerts - alert if 95th percentile response time rises by 50% in the last 24 h
Per-endpoint monitoring
A large API has dozens of endpoints. Don't monitor just /health - even that can lie. Identify 3-5 critical endpoints:
- Most-used business operations (POST /api/orders, GET /api/dashboard)
- Read endpoint for a cache hit (fast response)
- Write endpoint with a DB roundtrip
- External integration endpoint (calls a third party - detects dependency outages)
Monitor each one separately. During an incident you see exactly which part of the API fell.
Conclusion
API monitoring can't be reduced to HTTP status code. Quality monitoring combines status + content match + response time + per-endpoint granularity + authentication, to resemble a real client - not just an HTTP client.
API monitoring with keyword match
Status code + keyword in content + response time + auth headers. Per-endpoint granularity.
Try ePulz.io free - 7 days, no credit card needed.
Create account