Webhooks

Webhooks Overview

Webhooks are how FrontRow notifies your application when something happens in a creator’s account — a message, a new subscriber, a tip. Instead of polling the API, you register an endpoint and FrontRow POSTs an event payload to it within milliseconds of the trigger.

Available events

FrontRow currently supports 6 event types. Each has its own payload schema documented on its dedicated page.

Registering an endpoint

From your creator dashboard, open Settings → Developer → Webhooks and add an endpoint URL. Pick which events should trigger deliveries. FrontRow returns a unique signing secret per endpoint — copy it immediately, it’s only shown once.

Endpoints must be publicly reachable HTTPS URLs. Plain HTTP and loopback addresses are rejected at registration time. For local development, tunnel a public URL to your machine with ngrok or cloudflared.

Payload format

Every delivery is a JSON POST with three top-level fields: event, data, and timestamp. The shape of data depends on the event — see each event’s page for its schema.

Webhook envelope
1{
2 "event": "message.received",
3 "data": { /* event-specific payload */ },
4 "timestamp": "2026-04-28T12:10:01Z"
5}

Headers

  • X-FrontRow-Event — the event name (e.g. message.received).
  • X-FrontRow-Delivery — a unique delivery ID. Use it for idempotency — the same delivery may be retried.
  • X-FrontRow-Signature — an HMAC-SHA256 signature over the raw request body, prefixed with sha256=.
  • X-FrontRow-Timestamp — the ISO 8601 timestamp the event was generated. Reject deliveries older than five minutes to mitigate replay attacks.

Signature verification

Compute the HMAC of the raw body using your endpoint’s signing secret, then compare against X-FrontRow-Signature with a timing-safe equality check. Reject any request that fails.

verify.ts
1import crypto from "node:crypto";
2 
3export function verify(
4 rawBody: Buffer,
5 header: string | undefined,
6 secret: string
7): boolean {
8 if (!header) return false;
9 
10 const expected =
11 "sha256=" +
12 crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
13 
14 const a = Buffer.from(header);
15 const b = Buffer.from(expected);
16 
17 return a.length === b.length && crypto.timingSafeEqual(a, b);
18}

Delivery, retries, and idempotency

  • Acknowledge fast. Return a 2xx within 5 seconds. Acknowledge first, then process in a background queue.
  • Retries. Non-2xx responses (or timeouts) trigger exponential backoff retries up to 24 hours. After the final attempt, the delivery is dropped and visible in the dashboard’s delivery log.
  • Idempotency. Use X-FrontRow-Delivery as a primary key in your handler so retries don’t double-process.
  • Ordering. Webhooks are not strictly ordered. If you need a canonical order, sort by timestamp after dedup.

Testing

From the webhook dashboard, click Send test to deliver a sample payload for any event type. You can also trigger one programmatically:

POST /webhooks/test
1curl https://frontrow.center/api/v1/webhooks/test \
2 -H "Authorization: Bearer $FRONTROW_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{ "webhookId": "wh_abc123", "event": "message.received" }'

Next steps

Pick an event from the sidebar to see its payload, or jump straight into building a handler with the chatbot tutorial.