Skip to content

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.

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 receives POST requests.
  • 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.

EventFires whenPayload fields
build.completedAn instance finishes building and is runningdatabaseId, databaseName, endpointUrl, timestamp
build.failedA build failsdatabaseId, databaseName, error, timestamp
instance.unhealthyHealth monitoring marks a running instance unhealthydatabaseId, databaseName, healthStatus, timestamp
instance.recoveredAn instance returns to healthy after being unhealthydatabaseId, databaseName, timestamp

timestamp is an ISO-8601 UTC string. All payloads are JSON objects.

POST /your-endpoint HTTP/1.1
Content-Type: application/json
X-Reflexdb-Event: build.completed
X-Reflexdb-Signature: t=1753622400,v1=9f2c…<hex>
{"databaseId":"8ce4ca3f-…","databaseName":"web-prod","endpointUrl":"https://8ce4ca3f-….reflexdb.cloud","timestamp":"2026-07-27T12:00:00.000Z"}

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 object
function 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 hashlib
import 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.

HeaderValue
X-Reflexdb-EventThe event type (e.g. build.completed)
X-Reflexdb-Signaturet=<unix_seconds>,v1=<hex HMAC-SHA256>
Content-Typeapplication/json