Webhooks
Webhooks let your server receive HTTP notifications when events occur in your Relay app.
How It Works
- You register a webhook endpoint URL in your app settings
- When events you subscribed to occur, Relay sends a POST request to your URL
- Your server processes the payload and responds with a 2xx status
Every webhook delivery is signed with HMAC-SHA256 so you can verify authenticity.
Creating a Webhook Endpoint
Go to your app dashboard → Webhooks tab → Add Endpoint.
Configure:
| Field | Description |
|---|---|
| URL | The HTTPS endpoint that will receive webhooks |
| Secret | Auto-generated. Used to sign payloads |
| Event Types | Which events to send (or all) |
| Enabled | Toggle on/off without deleting |
Payload Format
Every webhook delivery is a POST request with a JSON body:
{
"event": "channel.occupied",
"data": {
"channel": "chat-room-42",
"subscription_count": 1
},
"timestamp": 1712300000
}
Headers
| Header | Description |
|---|---|
X-Relay-Signature |
HMAC-SHA256 signature of the body |
X-Relay-Event |
Event type (e.g. channel.occupied) |
X-Relay-Timestamp |
Unix timestamp of the delivery |
Content-Type |
application/json |
Verifying Signatures
Compute the HMAC-SHA256 of the raw request body using your webhook secret:
$signature = hash_hmac('sha256', $requestBody, $webhookSecret);
if (hash_equals($signature, $request->header('X-Relay-Signature'))) {
// Valid — process the webhook
}
const crypto = require('crypto');
const signature = crypto
.createHmac('sha256', webhookSecret)
.update(rawBody)
.digest('hex');
if (signature === req.headers['x-relay-signature']) {
// Valid
}
Or use the server-side verification endpoint:
POST /api/v1/apps/{appId}/webhooks/verify
Retry Behavior
If your endpoint returns a non-2xx status or times out (10s), Relay retries:
| Attempt | Delay |
|---|---|
| 1st retry | 10 seconds |
| 2nd retry | 60 seconds |
| 3rd retry | 5 minutes |
After 3 failures, the delivery is marked as failed and visible in the Webhooks tab.
Certificate Pinning
For extra security, enable certificate pinning on your webhook endpoint. Relay captures the TLS certificate fingerprint and refuses to deliver if it changes — protecting against man-in-the-middle attacks.
Enable in your webhook endpoint settings → Pin Certificate.
Dead Letter Queue
Failed deliveries after all retries are sent to the Dead Letter Queue (DLQ). You can:
- Inspect the original payload
- Retry the delivery
- Discard if no longer needed
Access the DLQ from your app dashboard.
Available Event Types
| Event | Triggered When |
|---|---|
channel.occupied |
First subscriber joins a channel |
channel.vacated |
Last subscriber leaves a channel |
member.added |
User joins a presence channel |
member.removed |
User leaves a presence channel |
client_event |
Client triggers a channel event |