WebhooksAll sections
Webhooks
Webhooks send an HTTP request to a URL you choose when something happens in your backend: a row is inserted, updated or deleted, or a user signs up. Each request is signed, retried if it fails, and logged.
In the console: Connect › WebhooksUpdated October 12, 2026
Why you need it
Your backend is rarely the only system involved. A new order might need to reach a warehouse system, a CRM or your own server. Without webhooks those systems have to keep asking whether anything changed. With them, Backenly tells them the moment it happens, and the signature proves the request really came from your backend.
For example
- Every new order is posted to your warehouse system.
- Your CRM hears about each new sign-up.
- A search index stays in sync as products are updated or deleted.
- A job on your own server starts when a new upload record is inserted.
How it works
Add an endpoint
Choose an event,
row.inserted,row.updated,row.deletedorauth.user.created, and the URL to call. The signing secret is shown once.The database captures the event
Row events are captured inside PostgreSQL, so they fire for every writer: the REST API, functions and the table editor alike.
Backenly sends a signed POST
X-Webhook-Signaturecarries an HMAC-SHA256 of the raw body. Your receiver computes the same HMAC and rejects anything that does not match.Failures are retried and logged
A failed delivery is retried, up to five attempts over about 35 minutes. The delivery log shows every attempt with its status code, and a failed delivery can be sent again.
Try it
Once your coding agent is connected, ask it:
Send a signed webhook to https://example.com/hooks/orders whenever a row is inserted into the orders table.import crypto from 'node:crypto'
// rawBody: the exact bytes received, before any JSON parsing.
export function isFromBackenly(rawBody, signatureHeader, secret) {
const expected =
'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
const a = Buffer.from(expected)
const b = Buffer.from(signatureHeader ?? '')
return a.length === b.length && crypto.timingSafeEqual(a, b)
}Good to know
- Delivery is at least once.
X-Webhook-Deliverystays the same when a retry re-sends an event, so use it to discard duplicates. - Send test makes a real signed request and shows what your receiver answered.
- The
userstable has no row events. Useauth.user.createdfor sign-ups; its payload never includes the password hash. - Webhooks tell your own services about changes. To call a provider such as Stripe or Resend from your backend, use Integrations.