Skip to main content

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:

HeaderValueDescription
x-s-kstringThe signing key for your webhook. Use this to verify the request authenticity.
Content-Typeapplication/jsonIndicates 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

FieldTypeRequiredDescription
emailstringYesEmail address of the user who checked in (normalized to lowercase)
usedReengIdstringYesThe Reeng ID that was used for the check-in
methodstringNoThe check-in method used (defaults to "ring" if not provided)
checkedInAtstringNoISO 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 2xx status 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 method field defaults to "ring" if not provided in the sync request
  • The checkedInAt field defaults to the current timestamp if not provided in the sync request