Event Webhook
When check-ins are synced for an event, webhooks configured for that event's application will receive a POST request with the check-in data.
When Webhooks Are Triggered
Event webhooks are automatically triggered when check-ins are synced for an event via the sync check-ins endpoint. All active webhooks associated with the event's application will receive the webhook notification.
Webhook Request
HTTP Method
POST
Headers
The webhook request includes the following headers:
| Header | Value | Description |
|---|---|---|
x-s-k | string | The signing key for your webhook. Use this to verify the request authenticity. |
Content-Type | application/json | Indicates the request body is JSON |
Request Body
The request body is a JSON array of check-in objects. Each check-in object contains the following fields:
[
{
"email": "user@example.com",
"usedReengId": "reeng_abc123def456",
"method": "ring",
"checkedInAt": "2024-01-15T10:30:00.000Z"
},
{
"email": "another@example.com",
"usedReengId": "reeng_xyz789ghi012",
"method": "ring",
"checkedInAt": "2024-01-15T10:35:00.000Z"
}
]
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email address of the user who checked in (normalized to lowercase) |
usedReengId | string | Yes | The Reeng ID that was used for the check-in |
method | string | No | The check-in method used (defaults to "ring" if not provided) |
checkedInAt | string | No | ISO 8601 timestamp of when the check-in occurred (defaults to current timestamp if not provided) |
Webhook Delivery
- Webhooks are sent asynchronously and do not block the sync check-ins API response
- Multiple webhooks can be configured per application, and all active webhooks will receive the notification
- Webhook requests have a 10-second timeout
- Failed webhook deliveries are logged but do not affect the check-in sync operation
- Each webhook delivery attempt is recorded in the webhook events history
Verifying Webhook Requests
To verify that a webhook request is authentic, check the x-s-k header matches your webhook's signing key. The signing key is provided when you create a webhook and should be stored securely.
Example Verification (Node.js)
const crypto = require('crypto');
function verifyWebhook(req, signingKey) {
const receivedKey = req.headers['x-s-k'];
return receivedKey === signingKey;
}
// Usage
app.post('/webhook', (req, res) => {
const isValid = verifyWebhook(req, process.env.WEBHOOK_SIGNING_KEY);
if (!isValid) {
return res.status(401).json({ error: 'Invalid webhook signature' });
}
// Process webhook data
const checkins = req.body;
console.log('Received check-ins:', checkins);
res.status(200).json({ received: true });
});
Example Webhook Handler
Node.js (Express)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
// Verify the signing key
const signingKey = req.headers['x-s-k'];
if (signingKey !== process.env.WEBHOOK_SIGNING_KEY) {
return res.status(401).json({ error: 'Invalid signing key' });
}
// Process check-ins
const checkins = req.body;
checkins.forEach(checkin => {
console.log(`User ${checkin.email} checked in at ${checkin.checkedInAt}`);
console.log(`Used Reeng ID: ${checkin.usedReengId}`);
console.log(`Method: ${checkin.method}`);
});
// Always return 200 to acknowledge receipt
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
Python (Flask)
from flask import Flask, request, jsonify
import os
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
# Verify the signing key
signing_key = request.headers.get('x-s-k')
if signing_key != os.environ.get('WEBHOOK_SIGNING_KEY'):
return jsonify({'error': 'Invalid signing key'}), 401
# Process check-ins
checkins = request.json
for checkin in checkins:
print(f"User {checkin['email']} checked in at {checkin['checkedInAt']}")
print(f"Used Reeng ID: {checkin['usedReengId']}")
print(f"Method: {checkin['method']}")
# Always return 200 to acknowledge receipt
return jsonify({'received': True}), 200
if __name__ == '__main__':
app.run(port=3000)
Response Requirements
Your webhook endpoint should:
- Return a
2xxstatus code (200, 201, 202, etc.) to indicate successful receipt - Respond within 10 seconds (webhook requests timeout after 10 seconds)
- Handle errors gracefully - webhook failures are logged but don't affect check-in operations
Webhook Event History
All webhook delivery attempts are recorded in the webhook events history, including:
- Success/failure status
- Request body sent
- Headers used
- Timestamp of delivery attempt
Notes
- The webhook payload contains only the new check-ins that were synced, not all check-ins for the event
- Multiple check-ins can be sent in a single webhook request if multiple users checked in during the same sync operation
- If no check-ins are synced (all are duplicates), webhooks are not triggered
- The
methodfield defaults to"ring"if not provided in the sync request - The
checkedInAtfield defaults to the current timestamp if not provided in the sync request