Getting Started
This guide walks you through registering a webhook and receiving your first event.
Prerequisites
- A valid Auth0 Bearer token with access to the Novee API.
- A Project ID — you must be a member of the project.
- A publicly accessible HTTPS endpoint to receive webhook events.
Step 1: Register a Webhook
Make a POST request to /webhooks/register with your project ID, callback URL, and the event types you want to receive.
curl -X POST https://api.novee.com/webhooks/register \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"projectId": "your-project-id",
"url": "https://your-server.com/webhook",
"types": ["FALL_DETECTION", "VITAL_THRESHOLD"]
}'Response
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d1",
"projectId": "your-project-id",
"url": "https://your-server.com/webhook",
"types": ["FALL_DETECTION", "VITAL_THRESHOLD"],
"secret": "whsec_a1b2c3d4e5f6..."
}⚠️ Important: The
secretis only returned once at registration time. Save it securely — you will need it to verify incoming webhook signatures.
Step 2: Implement Your Endpoint
Your endpoint must:
- Accept
POSTrequests with a JSON body. - Verify the
X-Signatureheader (see Security). - Return a
2xxHTTP status code to acknowledge receipt.
Minimal Example (Node.js / Express)
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = 'whsec_your_secret_here';
app.post('/webhook', (req, res) => {
const signature = req.headers['x-signature'];
const timestamp = req.headers['x-timestamp'];
const payload = JSON.stringify(req.body);
// 1. Verify timestamp is within 5 minutes
const now = Date.now();
const fiveMinutes = 5 * 60 * 1000;
if (Math.abs(now - Number(timestamp)) > fiveMinutes) {
return res.status(401).send('Timestamp too old');
}
// 2. Verify signature
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${timestamp}.${payload}`)
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signature)
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// 3. Process the event
console.log('Received webhook event:', req.body);
res.status(200).send('OK');
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));Minimal Example (Python / Flask)
import hmac
import hashlib
import time
import json
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret_here"
@app.route("/webhook", methods=["POST"])
def webhook():
signature = request.headers.get("X-Signature")
timestamp = request.headers.get("X-Timestamp")
payload = json.dumps(request.json, separators=(",", ":"))
# 1. Verify timestamp is within 5 minutes
now = int(time.time() * 1000)
if abs(now - int(timestamp)) > 5 * 60 * 1000:
abort(401, "Timestamp too old")
# 2. Verify signature
expected = hmac.new(
WEBHOOK_SECRET.encode(),
f"{timestamp}.{payload}".encode(),
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
abort(401, "Invalid signature")
# 3. Process the event
print("Received webhook event:", request.json)
return "OK", 200Step 3: Send a Test Event
Use the test endpoint to verify your integration:
curl -X POST https://api.novee.com/webhooks/test/project/your-project-id \
-H "Authorization: Bearer <YOUR_TOKEN>"This sends a TEST event to your registered URL with a sample payload: {"test": "test"}.
If your endpoint is configured correctly, you will receive the test webhook and the endpoint returns a 200 response.
Last updated on