Health
An unauthenticated probe that names the failing dependency rather than answering a bare 503. Checks Postgres, Redis, R2 and the browser pool.
Liveness probe
get
https://api.paperpony.dev/v1/healthno key requiredUnauthenticated. Rate limited to 60 requests per minute per IP address.
This is the one endpoint that does not use the error envelope: it answers 200 or 503 with a per-dependency report, because monitoring needs to know which dependency is down. A rate-limited request is a real API error and does use the envelope.
browser_pool reports the render workers. They publish a heartbeat and the API reads it, so no live worker with a warm browser reads as degraded, which is what would otherwise let renders queue forever behind a green probe.
Example
Unauthenticated. Limited to 60 requests a minute per address.
curl https://api.paperpony.dev/v1/healthimport { PaperPony } from 'paperpony';
// The probe is unauthenticated; the client still needs a key to construct.
const pony = new PaperPony({ apiKey: process.env.PAPERPONY_API_KEY });
const health = await pony.health();
console.log(health.status, health.checks);import os
import requests
response = requests.get(
"https://api.paperpony.dev/v1/health",
)
response.raise_for_status()
print(response.json())Returns
| Field | Type | Description |
|---|---|---|
statusrequired | "ok" | "degraded" | |
checksrequired | object |
Responses
| Status | Code | Meaning |
|---|---|---|
200 | Every dependency responded. | |
429 | rate_limited | Too many requests. Authenticated routes count per account, never per key. |
503 | At least one dependency is unavailable. |
Every error uses one envelope, and every response carries an
X-Request-Id. Quote it if you report a problem.