Skip to content

Outbound Webhooks & HMAC Signatures ​

FlowForm dispatches real-time outbound webhooks upon every completed form submission, enabling downstream pipelines (CRMs, Slack, Discord, internal databases, or microservices).


Webhook Architecture & Retries ​

Outbound webhooks are queued and dispatched with:

  • 3 Exponential Retries: [10s, 60s, 300s] backoff delays if the target endpoint returns a non-2xx status code or experiences connection timeouts.
  • HMAC-SHA256 Signatures: A cryptographic signature header (X-FlowForm-Signature) verifying that the payload originated from FlowForm and was not tampered with in transit.
  • Unique Event IDs: X-FlowForm-Submission-Id for idempotency tracking.

Webhook Headers ​

HeaderDescription
Content-Typeapplication/json
User-AgentFlowForm-Webhook/1.0
X-FlowForm-Eventform.submission
X-FlowForm-Submission-IdUnique submission UUID (e.g. 9f1a2b...)
X-FlowForm-TimestampUnix timestamp of dispatch
X-FlowForm-SignatureHex-encoded HMAC-SHA256 signature generated with your webhook_secret

Signature Verification Examples ​

Node.js / Express ​

javascript
const crypto = require('crypto');

function verifyFlowFormWebhook(req, secret) {
  const signature = req.headers['x-flowform-signature'];
  const rawBody = JSON.stringify(req.body);
  
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');

  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Python / FastAPI ​

python
import hmac
import hashlib

def verify_flowform_webhook(payload_bytes: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode('utf-8'), payload_bytes, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature_header, expected)

PHP ​

php
$signature = $_SERVER['HTTP_X_FLOWFORM_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');
$expected = hash_hmac('sha256', $payload, $webhookSecret);

if (hash_equals($expected, $signature)) {
    // Verified FlowForm submission payload
}

Licensed under CC BY 4.0.