title: "Public Routes" description: "Unauthenticated endpoints — cron heartbeat pings, public status pages, uptime badges, and custom endpoint reads." last_updated: "2026-05-24"
Public Routes
These endpoints don't require a bearer token. Some are fully public (anyone with the slug can hit them); others use scoped keys (bw_api_* for custom endpoints, bw_tv_* for TV dashboards).
Cron heartbeat pings
These are the URLs your cron jobs actually hit. The slug embedded in each URL is created when you create a cron check and acts as the secret (UUIDv4, 122 bits of entropy). Conceptual docs: Cron heartbeat monitoring.
Success ping
Records a successful run. Accepts GET, POST, HEAD (the route handler is router.all(...)). Request body, if present, is captured and truncated to 10 KB.
curl https://api.boxwatch.app/ping/9b1a3c8e-2f4d-4a7e-9c1d-5b2e6a8d0f12Start ping
Marks the job as started. Pair with a later success or fail ping to compute duration.
curl https://api.boxwatch.app/ping/9b1a3c8e-2f4d-4a7e-9c1d-5b2e6a8d0f12/start
./run-backup.sh && \
curl https://api.boxwatch.app/ping/9b1a3c8e-2f4d-4a7e-9c1d-5b2e6a8d0f12 || \
curl https://api.boxwatch.app/ping/9b1a3c8e-2f4d-4a7e-9c1d-5b2e6a8d0f12/failFail ping
Records a failure. Triggers a cron_fail alert if the check has alert_on_fail enabled.
Fail with exit code
Same as /fail but stores :code as the exit code on the ping record. Use to surface the script's real exit status in the dashboard.
./run-backup.sh
EXIT=$?
if [ $EXIT -eq 0 ]; then
curl https://api.boxwatch.app/ping/SLUG
else
curl https://api.boxwatch.app/ping/SLUG/fail/$EXIT
fiResponse (all ping endpoints)
Every ping returns 200 OK immediately, regardless of whether the slug exists. The DB work runs asynchronously after the response is sent.
{ "ok": true }This means a malformed or unknown slug looks identical to a successful ping at the HTTP layer — by design, so attackers can't enumerate slugs. If you mistype your URL the ping silently won't be recorded; verify in the dashboard.
Rate limit
60 pings per minute per slug. Excess pings still return 200 OK but are silently dropped (not recorded, no state change). Resets every 60 seconds.
Body capture
Bodies of any content type are accepted, up to 12 KB, then stored truncated to 10 KB. Use this to capture script output. JSON bodies are stringified; raw text and binary are stored as UTF-8.
Public status page
Returns the full JSON payload that powers the published status page. Cached for 60 seconds (Cache-Control: public, max-age=60).
Response — 200 OK
{
"status_page": {
"slug": "status-acme",
"name": "Acme Status",
"description": "Production health for Acme APIs",
"logo_url": "https://acme.example/logo.png",
"theme": "dark",
"overall_status": "operational"
},
"servers": [
{
"id": 12,
"name": "web-01",
"status": "online",
"metrics": { "cpu": 17.4, "memory": 62.1, "disk": 41.0 },
"uptime_chart": [
{ "date": "2026-05-23", "uptime": "100.0" },
{ "date": "2026-05-24", "uptime": "99.8" }
]
}
],
"active_incidents": [],
"past_incidents": [
{
"id": "1c2d3e4f-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"title": "API latency elevated",
"status": "resolved",
"severity": "major",
"message": "Investigating elevated response times on the /v1/* endpoints.",
"affected_servers": [12, 18],
"updates": [
{ "status": "investigating", "message": "Investigating...", "created_at": "..." },
{ "status": "resolved", "message": "Recovered at 18:42 UTC.", "created_at": "..." }
],
"created_at": "2026-05-23T22:14:00Z",
"resolved_at": "2026-05-23T23:01:00Z"
}
],
"timestamp": "2026-05-24T18:42:11Z"
}overall_status is computed from active incidents: major_outage (any critical), partial_outage (any major), minor_issues (other active incidents), or operational. Past incidents are limited to the last 14 days, max 10.
Errors
404— Status page not found or disabled.
Uptime badge
Returns an SVG badge showing 30-day uptime or current status. Cached 5 minutes. CORS-friendly (Access-Control-Allow-Origin: *).
Query parameters
| Param | Type | Default | Notes |
|---|---|---|---|
style | string | uptime | uptime (percentage) or status (current state text). |
Response — 200 OK
Returns image/svg+xml content directly — embed in markdown or HTML:
<img src="https://api.boxwatch.app/badge/12" alt="uptime" />Color thresholds for uptime style:
- Green
#22c55e— ≥ 99.5% - Yellow
#eab308— ≥ 95% - Red
#ef4444— < 95%
Errors
404— Returns plain textNot found.
Custom API endpoint
Reads metrics through a scoped endpoint key (bw_api_*). The endpoint config locks down which servers and which metrics are returned. Conceptual docs: Custom API endpoints.
Pass the key via header (X-API-Key: bw_api_...) or query string (?key=... or ?api_key=...).
curl -H "X-API-Key: bw_api_1234..." \
https://api.boxwatch.app/v/your-endpoint-idResponse — 200 OK
{
"data": [
{
"server_name": "web-01",
"hostname": "web-01.prod",
"cpu": 17.4,
"memory": 62.1,
"disk": 41.0,
"timestamp": "2026-05-24T18:42:11Z"
}
],
"timestamp": "2026-05-24T18:42:11Z"
}Returns metrics from the last hour, capped at 100 rows. Cached 60 seconds.
Errors
401— Missing or invalid endpoint key.403— Wrong key type passed (e.g. full-scope or TV key).
TV dashboard data
Reads dashboard data through a TV-scoped key (bw_tv_*). Same header/query conventions as /v/. Conceptual docs: TV dashboards.
Response — 200 OK
{
"dashboard": {
"id": "dash-uuid",
"name": "Ops floor",
"layout": { "servers": [12, 18, 47] }
},
"servers": [
{
"id": 12,
"name": "web-01",
"hostname": "web-01.prod",
"ip": "10.0.1.5",
"status": "online",
"last_seen": "2026-05-24T18:42:11Z",
"metrics": {
"cpu": 17.4,
"memory": 62.1,
"disk": 41.0,
"load_1m": 0.42,
"load_5m": 0.61,
"load_15m": 0.55,
"uptime": 2419200,
"network_in": 134217,
"network_out": 98214
}
}
],
"timestamp": "2026-05-24T18:42:11Z"
}status per server is online (last seen < 10 min), warning (online but any metric > 90%), or offline. Cached 60 seconds.
Errors
401— Missing or invalid TV key.403— Wrong key type passed.
Tracking scripts
Returns admin-configured analytics snippets used by the marketing site. Not relevant for API consumers — exposed only because the marketing site fetches it client-side.
{
"head": "<!-- analytics snippet -->",
"conversion": "<!-- conversion snippet -->",
"timestamp": "2026-05-24T18:42:11Z"
}See also
- Cron heartbeat monitoring — the conceptual model for
/ping/:slug - Status pages — page configuration
- Custom API endpoints — for
/v/:endpoint_id - TV dashboards — for
/tv/:dashboard_id