Gareth Wilson Gareth Wilson

Guide to Front Webhooks: Features and Best Practices

Published


Front webhooks notify your application about inbox activity: a message is received or sent, a conversation is moved, a tag is added, an assignee changes. If you're building an integration on Front, webhooks are how you react to conversation activity in real time.

This guide covers how Front's application webhooks work, the events you'll handle, how to verify the X-Front-Signature, the challenge handshake, and the best practices for production, plus how the legacy rule webhooks differ (so you don't conflate the two).

What are Front webhooks?

Front has two webhook systems. This guide covers application webhooks (the modern system used by partner and Core API apps), which sign deliveries with an X-Front-Signature keyed with your app's signing key. The older rule webhooks (a settings-based rule action) sign differently, covered at the end.

Application webhooks POST a JSON event to your endpoint, verify your endpoint with a challenge at subscription time, and retry a few times before auto-disabling.

Front webhook features

FeatureDetails
SystemApplication webhooks (modern); rule webhooks are legacy
Signature headerX-Front-Signature (base64 HMAC-SHA256)
Signed contentX-Front-Request-Timestamp + ":" + raw body
Signing keyApp signing key
HandshakeX-Front-Challenge: echo the value within 10s
RetriesUp to 3x on 408/429/500/timeout, then auto-disables
Legacy rule webhooksHMAC-SHA1 over the body only, keyed with the "API Secret", 5s timeout, no retries
SDKNo official server-side SDK (community only)

Common events

Front application webhook events cover conversation and message activity:

EventFires when
inbound_receivedAn inbound message is received
outbound_sentAn outbound message is sent
conversation_movedA conversation is moved (inbox/status change)
message_delivery_failedA message fails to deliver
tag_addedA tag is added to a conversation
assignee_changedA conversation's assignee changes
new_comment_addedA comment is added to a conversation

Subscribe to the events you process, and consult Front's webhook reference for the full list.

Setting up Front webhooks

Create an application webhook subscription for your app. At subscription time Front sends a validation request with an X-Front-Challenge header; echo the challenge value back within 10 seconds as a 200 (as a text/plain body, a form challenge=<v>, or JSON {"challenge":"<v>"}). Copy your app's signing key into your environment for verifying deliveries.

Securing Front webhooks

Each delivery carries an X-Front-Signature (base64) and an X-Front-Request-Timestamp. To verify, build the message {timestamp}:{raw body}, compute a base64 HMAC-SHA256 with your app signing key, and compare in constant time. Always use the raw body.

const crypto = require("crypto");

const SIGNING_KEY = process.env.FRONT_APP_SIGNING_KEY;

function verify(rawBody, timestamp, signature) {
  const message = `${timestamp}:${rawBody}`;
  const expected = crypto
    .createHmac("sha256", SIGNING_KEY)
    .update(message)
    .digest("base64");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  // Subscription handshake
  const challenge = req.headers["x-front-challenge"];
  if (challenge) return res.status(200).json({ challenge });

  const timestamp = req.headers["x-front-request-timestamp"];
  if (!verify(req.body.toString("utf8"), timestamp, req.headers["x-front-signature"])) {
    return res.sendStatus(401);
  }

  res.sendStatus(200); // acknowledge fast
  processQueue.add(JSON.parse(req.body)); // process asynchronously
});

The same check in Python:

import base64
import hashlib
import hmac
import os

SIGNING_KEY = os.environ["FRONT_APP_SIGNING_KEY"].encode()


def verify(raw_body: str, timestamp: str, signature: str) -> bool:
    message = f"{timestamp}:{raw_body}".encode()
    expected = base64.b64encode(hmac.new(SIGNING_KEY, message, hashlib.sha256).digest()).decode()
    return hmac.compare_digest(expected, signature or "")

How legacy rule webhooks differ

Front's older rule webhooks (configured as a rule action, not an app) use a different scheme: base64 HMAC-SHA1 over the body only, keyed with the "API Secret" from the Webhooks app, a 5-second timeout, and no retries. Don't reuse the application-webhook verifier for these; the algorithm, the signed content, and the key source all differ.

Front webhook limitations and pain points

Two systems, two schemes

The Problem: Application webhooks use HMAC-SHA256 over timestamp:body keyed with the app signing key; rule webhooks use HMAC-SHA1 over the body keyed with the API Secret. Conflating them fails verification.

Why It Happens: Front has two generations of webhooks with different signing.

Workarounds:

  • Know which system you're on. For apps, verify SHA256 over timestamp:body; for rule webhooks, SHA1 over the body with the API Secret.

How Hookdeck Can Help: Hookdeck verifies each source with the correct scheme at the edge, so your application receives pre-verified events without branching on which Front system sent them.

The challenge handshake

The Problem: Application webhooks won't activate until you echo the X-Front-Challenge within 10 seconds, in one of the accepted formats.

Why It Happens: Front validates the endpoint before delivering events.

Workarounds:

  • Detect X-Front-Challenge and echo it fast (JSON {"challenge":"<v>"} works).

How Hookdeck Can Help: Hookdeck can complete the handshake and forward verified events to your endpoint, so activation isn't a manual step.

Limited retries then auto-disable

The Problem: Application webhooks retry up to 3 times (on 408/429/500/timeout) and then auto-disable. A short outage can drop events; a sustained one disables the subscription.

Why It Happens: Front's retry budget is small and it prunes failing subscriptions.

Workarounds:

  • Acknowledge fast so transient issues don't burn the 3-attempt budget; monitor subscription status and re-enable.

How Hookdeck Can Help: Hookdeck accepts every delivery and retries to your downstream on a schedule you control, so Front's 3-attempt limit isn't your only safety net and a sustained outage doesn't disable the subscription.

Duplicates and raw-body handling

The Problem: Retries mean duplicates, and the signature is over timestamp:body, so re-serializing the body breaks verification.

Why It Happens: At-least-once delivery plus a timestamp-bound signature.

Workarounds:

  • Verify against the raw body, and dedupe on the event/conversation ID.

How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge and verifies against the bytes as received. See our guide to webhook idempotency.

Best practices

Verify over timestamp:body with the app signing key

Build {timestamp}:{raw body}, base64 HMAC-SHA256 with the app signing key, and compare in constant time. Don't reuse this for legacy rule webhooks.

Echo the challenge fast

Detect X-Front-Challenge and return it within 10 seconds to activate the subscription.

Acknowledge fast, process asynchronously

Return 200 immediately and defer work to a queue so transient slowness doesn't burn the retry budget. See why to process webhooks asynchronously.

Dedupe and monitor status

Dedupe on the event/conversation ID, and watch for auto-disable after sustained failures.

Make Front webhooks production-ready

Hookdeck completes the challenge, verifies X-Front-Signature, deduplicates, and durably queues every conversation event

Conclusion

Front application webhooks verify with an X-Front-Signature (base64 HMAC-SHA256 over timestamp:body, keyed with the app signing key), activate via an X-Front-Challenge handshake, and auto-disable after 3 failed attempts. The trap to avoid is conflating them with the legacy rule webhooks, which use HMAC-SHA1 over the body with the API Secret.

Hookdeck completes the handshake, verifies the signature, deduplicates, and durably queues every event at the edge, so your app only ever processes verified, unique conversation events without disabling on a bad day.

Get started with Hookdeck for free and handle Front webhooks reliably in minutes.


Gareth Wilson

Gareth Wilson

Product Marketing

Multi-time founding marketer, Gareth is PMM at Hookdeck and author of the newsletter, Community Inc.