Subscribe to events from your boards.
Register an HTTPS endpoint and Index will POST a JSON payload to it every time a selected event fires — entry.created, suggestion.created, and others. Each delivery is signed with HMAC-SHA256 so your receiver can verify it came from Index and was not tampered with in transit.
The secret is generated server-side and returned exactly once. Capture it immediately — Index has no way to show it again.
Read-only — to change which events a subscription receives, delete it and register a new one.
Every outgoing delivery carries the headers below. Compute HMAC-SHA256(secret, raw_body) and compare with X-INDEX-Signature using a constant-time check — never ==, which leaks the secret over time.
- X-INDEX-EventThe event name, e.g. entry.created
- X-INDEX-DeliveryA UUID4 unique per attempt — survives retries
- X-INDEX-Signaturesha256=<hex_digest> of the raw request body
# Flask receiver — verify X-INDEX-Signature before trusting the payload. import hmac, hashlib from flask import Flask, request, abort app = Flask(__name__) SECRET = "<your subscription secret>".encode() @app.route("/webhook", methods=["POST"]) def receive(): raw = request.get_data() # bytes, BEFORE any parsing sent = request.headers.get("X-INDEX-Signature", "") want = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(sent, want): abort(401) payload = request.get_json() # …handle payload[event]… return "", 204
// Express receiver — express.raw() preserves the body for HMAC. const express = require("express"); const crypto = require("crypto"); const SECRET = "<your subscription secret>"; const app = express(); app.post( "/webhook", express.raw({ type: "application/json" }), (req, res) => { const sent = req.headers["x-index-signature"] || ""; const want = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex"); const a = Buffer.from(sent), b = Buffer.from(want); if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) { return res.sendStatus(401); } const payload = JSON.parse(req.body.toString("utf8")); // …handle payload.event… res.sendStatus(204); } );
# Reproduce a delivery against a local receiver. Hash MUST be over the # exact bytes you POST — re-serializing the JSON will change the digest. BODY='{"event":"entry.created","entry_id":"e_demo","test":true}' SECRET='<your subscription secret>' SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')" curl -X POST http://localhost:3000/webhook \ -H "Content-Type: application/json" \ -H "X-INDEX-Event: entry.created" \ -H "X-INDEX-Delivery: 00000000-0000-0000-0000-000000000000" \ -H "X-INDEX-Signature: $SIG" \ --data-binary "$BODY"