Health
Two open probes for uptime monitors. No key, and not the agent error envelope.
Read as MarkdownTwo routes an uptime monitor or a load balancer can call with no API key. They answer in their own small shape, never the { error: { code, ... } } envelope every other route uses.
| Endpoint | Checks | Brake |
|---|---|---|
GET /health | Nothing. The API process answered | None |
GET /health/ready | One database query, with a 3 second timeout | 60 requests a minute per IP address |
- Both send
Cache-Control: no-store. - No key needed. A key sent anyway is ignored.
- No version, commit or region in either body.
Liveness
GET/api/v1/healthNo auth
Touches nothing but the process. Use it to ask "is the API up".
curl -s https://app.riffads.com/api/v1/health{
"ok": true,
"status": "ok",
"service": "riffads-api"
}This is the only answer it gives. Anything else (a timeout, a 5XX from the platform in front) means the API is down.
Readiness
GET/api/v1/health/readyNo auth
Runs one query against the database. Use it to ask "can the API serve a real request".
curl -s -w "\n%{http_code}\n" https://app.riffads.com/api/v1/health/ready{
"ok": true,
"status": "ready",
"checks": { "database": "ok" }
}{
"ok": false,
"status": "unavailable",
"checks": { "database": "down" }
}503when the query fails or takes longer than 3 seconds.- The reason is never in the body. Only
database: "down".
The IP brake
/health/ready does real work, so it is braked at 60 requests a minute per IP address. Over it:
{
"error": "too_many_requests",
"error_description": "Too many requests from this address. Please wait and try again."
}- Sent with
Retry-Afterin seconds andCache-Control: no-store. /healthis never braked.- One monitor every 30 seconds is far below it.
What healthy does not mean
- Readiness checks the database only. Renders run on outside model providers. A provider outage shows up on the generation (
provider_unavailable), not here. - A healthy probe does not mean your key works. Test the key with a cheap read such as
GET /capabilities. Authentication.
Branch on the HTTP status
Both probes answer ok plus status. Branch on the HTTP status first (200, 429 or 503), then on status. Never parse them as the agent envelope: there is no error.code and no retryable here.
Worked example: a monitor
Poll liveness often and readiness less often:
# Every 30 seconds: is the API up?
curl -sf https://app.riffads.com/api/v1/health > /dev/null || echo "RiffAds API down"
# Every 2 minutes: can it serve a request?
code=$(curl -s -o /dev/null -w "%{http_code}" https://app.riffads.com/api/v1/health/ready)
[ "$code" = "200" ] || echo "RiffAds API not ready ($code)"A 429 from readiness means your monitors share an address and poll too often. Slow them down: it is not an outage.