Help

Webhook reference

Payload schema, the HMAC signature, headers, and retry behavior.

An enabled webhook sends an HTTP POST to your endpoint for each submission. See Webhooks for setup.

Headers

HeaderValue
Content-Typeapplication/json
X-HigherStack-Eventform.submission
X-HigherStack-Signaturesha256=<hex HMAC of the raw body>

Payload

JSON
{
  "formId": "string",
  "formTitle": "string",
  "submissionId": "string",
  "createdAt": "ISO-8601 timestamp",
  "data": { "<field name>": "<answer>", "…": "…" },
  "tracking": {
    "eventId": "string",
    "clickIds": { "gclid": "…", "fbclid": "…" },
    "utm": { "utm_source": "…", "utm_campaign": "…" },
    "pageUrl": "…", "referrer": "…"
  }
}

tracking is present only when the submission captured attribution.

Verifying the signature

Compute an HMAC-SHA256 of the exact raw request body with your webhook secret and compare to the header.

Node.js
const crypto = require('crypto');
const expected = 'sha256=' + crypto
  .createHmac('sha256', SECRET)
  .update(rawBody) // the raw string, not re-serialized JSON
  .digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));

Retries & idempotency

  • Deliveries retry a few times with a short backoff; each attempt times out after ~10 seconds.
  • Retries happen on network errors, 5xx and 429. A 4xx (other than 429) is treated as permanent — fix and re-test.
  • Because of retries, the same submissionId may arrive more than once. De-duplicate on submissionId.
  • Respond 2xx quickly to acknowledge receipt.

Still need help?

A dedicated support form is coming soon. In the meantime, jump back into the product or reach the team from the contact page.