One authenticated endpoint in — notifications out to the operator's channels.
v0.1.0
This is a private instance, not a public service. There is no signup: callers
are machines, each issued a key by the operator. Without one you get a
401 and nothing else.
curl -X POST https://notify.rlew.io/v1/notify \
-H 'Authorization: Bearer <your-key>' \
-H 'Content-Type: application/json' \
-d '{"title":"Backup failed","message":"nightly borg run exited 1","priority":"high"}'
title and message are required. priority
(low, default, high,
urgent), tags, html and
channels are optional. Omit channels and the
notification goes everywhere your key permits; naming one it doesn't is a
403, never a silent narrowing. Unknown fields are rejected rather
than dropped, so a caller with a stale schema finds out.
Add html and channels that can render it will — email does;
push channels ignore it and show message, which is why
message stays required as the plain-text alternative.
-d '{"title":"Weekly digest",
"message":"3 jobs failed, 41 succeeded",
"html":"<p>3 failed, <b>41</b> succeeded</p>"}'
Send a fragment and it arrives wrapped in a styled mail; send a whole
document — anything starting <!doctype or
<html — and it is used exactly as written, so a producer that
wants to own the markup can. It is passed through unaltered, which is
deliberate: posting at all requires a key the operator issued.
Callers here are scripts, so every outcome is explicit. Branch on the status
code; result repeats it in the body.
| Status | result | |
|---|---|---|
200 | delivered | Every selected channel delivered inside the response window |
202 | queued | Accepted and durably spooled; nothing delivered yet |
207 | partial | Mixed — the per-channel map says which was which |
400 | — | Malformed, or a field the API doesn't know |
401 | — | Missing or unknown key |
403 | — | Channel not permitted for this key |
429 | rate_capped | Global cap hit; honour Retry-After |
502 | failed | Every selected channel failed permanently |
A 202 is a promise, not a receipt: the message is on disk and its
real outcome is written to the operator's delivery log later, keyed by the
requestId the call returned. A channel being down means late
delivery, not a lost alert. Delivery is at-least-once, so a caller that times
out and retries may double-send.
GET /docs — the same contract as browsable reference, with a panel for firing a real requestGET /openapi.json — the full machine-readable contract, generated for this deploymentGET /llms.txt — the same, condensed, for agentsGET /health — liveness