Integrations

Webhooks

Available on Starter, Pro, Business · 5-minute read

Forward every form submission to any HTTP endpoint — Zapier, Make, your own server, Slack, Discord, your CRM. JSON payload, optional HMAC signature for verification.

Setup

  1. Dashboard → form → Edit
  2. Set Webhook URL to your endpoint (must be HTTPS)
  3. Save

Every successful submission to this form now also POSTs JSON to your URL, in parallel with the email send.

Payload format

POST https://your-server.com/webhook
Content-Type: application/json
User-Agent: JustForms/1.0
X-JustForms-Signature: a1b2c3...  (if signing key set)

{
  "formId": "contact-abc123",
  "submissionId": "0193ee5a-4d3f-7e21-b9f6-...",
  "data": {
    "name": "Alex",
    "email": "alex@example.com",
    "message": "Hello"
  },
  "utm": {
    "utm_source": "google",
    "utm_medium": "cpc",
    "gclid": "Cj0KCQ..."
  },
  "country": "US",
  "createdAt": 1730000000000
}

HMAC signature verification (Business plan)

Set WEBHOOK_SIGNING_KEY as a Worker secret. We include X-JustForms-Signature header on every webhook — hex HMAC-SHA256 of the request body.

Node.js verification

const crypto = require('crypto');

function verify(req) {
  const sig = req.headers['x-justforms-signature'];
  const expected = crypto
    .createHmac('sha256', process.env.JUSTFORMS_WEBHOOK_KEY)
    .update(req.rawBody)        // raw bytes — don't use JSON.stringify
    .digest('hex');
  // constant-time compare
  return sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

Python verification

import hmac, hashlib

def verify(raw_body: bytes, sig_header: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, sig_header)

Retries

If your endpoint returns non-2xx, JustForms retries:

Your endpoint should respond within 10 seconds. Slower responses get queued for retry.

Common destinations

Zapier

Create a Zap → trigger "Catch Hook" → copy the webhook URL → paste in JustForms.

Slack

Slack → Apps → Incoming Webhooks → Add to Slack → choose channel → copy URL.

Note Slack expects a specific JSON shape ({ "text": "..." }). Use Zapier or Make as a transformer to convert our payload to Slack's format — or use a small Worker as proxy.

Discord

Server settings → Integrations → Create Webhook → copy URL. Discord accepts { "content": "message" }. Same transformer caveat applies.

Custom server

Any HTTPS endpoint that returns 2xx within 10s. Recommended: validate the signature, write to your DB, return { ok: true }.