Shriek
Beta Base URL: https://shriek.dev
Overview
Shriek records alerts about your services and tells you when something goes quiet.
- Alerts. Your service posts an alert. Shriek appends it to your feed, which nothing can edit or delete. The feed is the record: you read it, and phone notifications are an extra on top.
- Dead-man’s switches. Your service registers a source and promises to
send a heartbeat at least every N seconds. If the heartbeats stop, Shriek
raises one
critical“no signal” alert, and oneinfo“recovered” alert when they start again. It never repeats the alert while the source stays silent. - Incidents. Your service opens an incident when something is wrong and
resolves it when it is fixed. Give it a
dedup_keyand opening it again while it is open does nothing. - The board. One row per service:
green, orredwhile any of its sources is silent or has an open incident. - A public status page. You choose which sources appear publicly, under a label you pick, and write the public updates yourself. Component names and alert details never appear there; service names do.
critical alerts also go to the phones registered to your tenant through
the Shriek Android app.
Shriek is for developers who run services and want to know when one fails, including the failures that make no noise: a job that never started, or a monitor that died.
What beta means here: Shriek runs in production, and Stackwell’s own services report to it. Tenants are set up by Stackwell by hand: there is no self-serve sign-up. Some behaviour is not finished; Concepts and Data and privacy mark each gap “Not yet”.
Quickstart
This sets up one dead-man’s switch for a nightly job and reads it back.
1. Check that Shriek is reachable
No credentials needed:
curl -fsS https://shriek.dev/health
{"service":"shriek","status":"ok"}
2. Get a tenant and a credential
Your data lives in a tenant. Stackwell creates the tenant and connects
your ChirpAuth client to it. Your service then calls Shriek with a ChirpAuth
machine token for that client; see Authentication. The
examples below keep the token in $SHRIEK_TOKEN.
3. Register a source
A source is a service (a row on the board) and a component within it.
This one expects a heartbeat at least once an hour:
curl https://shriek.dev/v1/shriek/expectations \
-H "Authorization: Bearer $SHRIEK_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {"service": "billing", "component": "nightly-export"},
"period_secs": 3600
}'
{
"source": {"service": "billing", "component": "nightly-export"},
"period": 3600,
"since": 1793911201
}
Times are Unix seconds. If no heartbeat arrives by since + period, the
source starts firing.
4. Send heartbeats
Call this each time the job succeeds:
curl https://shriek.dev/v1/shriek/heartbeat \
-H "Authorization: Bearer $SHRIEK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"source": {"service": "billing", "component": "nightly-export"}}'
{"ok": true, "at": 1793911202}
5. Read the board
curl https://shriek.dev/v1/shriek/board \
-H "Authorization: Bearer $SHRIEK_TOKEN"
[
{"service": "billing", "health": "green", "firing": []}
]
If the job misses its hour, the row turns red, firing lists the source,
and a critical “no signal” alert appears in your feed
(GET /v1/shriek/alerts). The next heartbeat turns it green again. See
API examples for alerts, incidents and the public status
page.
Authentication
Your service calls Shriek with a ChirpAuth machine token for a client that Stackwell has connected to your tenant. People in your tenant use the Shriek Android app, which signs them in with ChirpAuth. Both see and change the same tenant data. The public status page needs no credential. Authentication has the details.
API reference
The full endpoint list is in the generated API reference. API examples walks through the endpoints a service uses, with real requests and responses, and Concepts explains the rules they follow.
Conventions shared by every endpoint:
- Base URL
https://shriek.dev. Your tenant’s endpoints start with/v1/shriek/; the public status page is under/public/{tenant}. - Request and response bodies are JSON; send
Content-Type: application/json. - Times are Unix seconds (whole seconds since 1970, UTC).
- Every endpoint acts on the caller’s own tenant, which comes from the
credential. You never name your tenant in a
/v1/call. - Lists are not paged.
- There are no idempotency keys. An incident’s
dedup_keymakes opening it safe to repeat; nothing else is.
Errors and limits
Errors are JSON, {"error": "<message>"}, except parsing errors, which are
plain text. Text fields are capped at 256 bytes, alert details at 4096 bytes,
and request bodies at 64 KiB. Each IP address can make 2,000 requests per
5 minutes. Errors and limits lists the status codes and
every limit.
Data and privacy
Shriek keeps every alert you send for as long as it runs: there is no way to delete one. Your public updates and the labels and service names you publish are readable by anyone. Data and privacy says what is stored, who can read it, and what cannot be deleted.