Skip to Content
Welcome to Novee Developer Portal 🎉

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 secret is 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:

  1. Accept POST requests with a JSON body.
  2. Verify the X-Signature header (see Security).
  3. Return a 2xx HTTP 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", 200

Step 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