Webhooks
ReflexDB delivers platform events to an HTTPS endpoint you control. Use them to react to builds finishing, builds failing, or an instance going unhealthy — without polling the dashboard.
Configuring a webhook
Section titled “Configuring a webhook”Create and manage webhooks in the dashboard under Settings → Webhooks (per instance, on the instance detail page). At creation you choose:
- URL — an
https://endpoint that receivesPOSTrequests. - Events — one or more of the event types below.
A signing secret (32-byte hex) is shown once at creation. Store it securely — you’ll need it to verify deliveries, and it cannot be retrieved again.
Each subscription keeps a delivery history with retry controls.
Event catalog
Section titled “Event catalog”| Event | Fires when | Payload fields |
|---|---|---|
build.completed | An instance finishes building and is running | databaseId, databaseName, endpointUrl, timestamp |
build.failed | A build fails | databaseId, databaseName, error, timestamp |
instance.unhealthy | Health monitoring marks a running instance unhealthy | databaseId, databaseName, healthStatus, timestamp |
instance.recovered | An instance returns to healthy after being unhealthy | databaseId, databaseName, timestamp |
timestamp is an ISO-8601 UTC string. All payloads are JSON objects.
Example delivery
Section titled “Example delivery”POST /your-endpoint HTTP/1.1Content-Type: application/jsonX-Reflexdb-Event: build.completedX-Reflexdb-Signature: t=1753622400,v1=9f2c…<hex>
{"databaseId":"8ce4ca3f-…","databaseName":"web-prod","endpointUrl":"https://8ce4ca3f-….reflexdb.cloud","timestamp":"2026-07-27T12:00:00.000Z"}Verifying signatures
Section titled “Verifying signatures”Every delivery is signed with HMAC-SHA256 using your subscription’s signing secret. Verify it before trusting the payload.
Header format:
X-Reflexdb-Signature: t=<unix_seconds>,v1=<hex>where <hex> is HMAC-SHA256(secret, "<t>.<raw_request_body>") as a lowercase hex string.
Node.js:
import crypto from "node:crypto";
// rawBody: the exact bytes received (Buffer/string), not a re-serialized objectfunction verify(rawBody, signatureHeader, secret) { const parts = Object.fromEntries( signatureHeader.split(",").map((kv) => kv.split("=")), ); const t = parts["t"]; const provided = parts["v1"]; if (!t || !provided) return false;
const expected = crypto .createHmac("sha256", secret) .update(`${t}.${rawBody}`) .digest("hex");
const a = Buffer.from(expected); const b = Buffer.from(provided); return a.length === b.length && crypto.timingSafeEqual(a, b);}Python:
import hashlibimport hmac
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool: parts = dict(kv.split("=", 1) for kv in signature_header.split(",")) t, provided = parts.get("t"), parts.get("v1") if not t or not provided: return False signed = f"{t}.".encode() + raw_body expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, provided)You may also reject deliveries whose t is far from your current time to limit replay windows.
Headers reference
Section titled “Headers reference”| Header | Value |
|---|---|
X-Reflexdb-Event | The event type (e.g. build.completed) |
X-Reflexdb-Signature | t=<unix_seconds>,v1=<hex HMAC-SHA256> |
Content-Type | application/json |