Subscribe to Flipdish Events (v3)
Use Flipdish Flipdish Webhooks to receive HTTP POSTs when things happen in your account (e.g., menu.published.v1). You configure which event types to receive and the callback URL in the Portal.
These docs describe the delivery contract and how to verify requests. See the Event schemas in API Reference v3.0 → Flipdish Webhooks for exact payloads.
Prerequisites
- Only users with the Owner or Managed Owner role in the Flipdish portal can create webhooks, as these roles include the Edit Webhooks permission.
- Access to the Flipdish Portal with permission to manage the Org’s settings
- An HTTPS endpoint you control (staging recommended for first tests)
- Your subscription’s shared secret for request verification
1. How it works
- In the Portal, go to Settings → Webhooks and create a Webhook Subscription.
- Select one or more event types (e.g.,
menu.published.v1). - Provide your HTTPS callback URL
- When an event occurs, Flipdish sends an HTTP POST to your URL with the event payload.
Org-scoped ownership
Webhook subscriptions now belong to the OrgId, not a user or OAuth app.
2. Request format
- Method:
POST - Content-Type:
application/json - Body: Event payload (see schemas in API Reference), e.g. menu published v1.
Headers
X-Flipdish-Event-Type: <event-type> # e.g., menu.published.v1
X-Flipdish-Event-Version: v1
X-Flipdish-Timestamp: 2025-08-14T12:34:56.789Z
X-Flipdish-Signature: t=2025-08-14T12:34:56.789Z,sha256=<hex>See the Delivery contract section below for details on each header.
Response contract
- Return any 2xx to acknowledge receipt.
- Non-2xx or timeouts are treated as failures and will be retried.
Delivery contract
- Method:
POST, Content-Type:application/json - Acknowledge with any 2xx once you persist the event
- Retries are automatic (at-least-once semantics). Handlers must be idempotent
| Header | Description |
|---|---|
X-Flipdish-Event-Type | Event type identifier (e.g., menu.published.v1) |
X-Flipdish-Event-Version | Event version (e.g., v1, v2) |
X-Flipdish-Timestamp | ISO-8601 timestamp when the event was sent |
(planned) X-Flipdish-Signature | HMAC-SHA256 signature for payload verification |
(planned) X-Flipdish-Idempotency-Key | Key to support idempotent processing |
Verifying requests
Below is a minimal Node.js/TypeScript example. It uses the raw request body, concatenates ${timestamp}.${rawBody}, computes an HMAC-SHA256 with your subscription secret, and compares using a timing-safe comparison.
import crypto from 'node:crypto';
function timingSafeEqual(a: string, b: string): boolean {
const ab = Buffer.from(a, 'utf8');
const bb = Buffer.from(b, 'utf8');
if (ab.length !== bb.length) return false;
return crypto.timingSafeEqual(ab, bb);
}
export function verifySignature(
rawBody: string,
timestamp: string,
signature: string,
secret: string,
): boolean {
const payload = `${timestamp}.${rawBody}`;
const expected = crypto.createHmac('sha256', secret).update(payload, 'utf8').digest('hex');
return timingSafeEqual(expected, signature);
}Usage sketch (framework-agnostic):
// Pseudocode – ensure you read the RAW body bytes (do not JSON.parse before signing!)
const rawBody = getRawBodyFromHttpFramework(req); // string or Buffer → string
const timestamp = req.headers['x-flipdish-timestamp'] as string;
const signatureHeader = req.headers['x-flipdish-signature'] as string; // "sha256=<hex>" or similar
const signature = signatureHeader.split('sha256=')[1] ?? signatureHeader; // normalize to hex only
if (!verifySignature(rawBody, timestamp, signature, process.env.FLIPDISH_WEBHOOK_SECRET!)) {
return res.status(401).send('Invalid signature');
}
// Persist event, then acknowledge with 2xx
res.status(200).send('OK');3. Testing your endpoint
- Create a subscription to a non-critical URL (staging).
- Trigger a known event (e.g., publish a test menu).
- Confirm you receive a POST and that verification passes.
- Return
2xxwhen you persist the event; retry logic will handle transient outages.
4. Operational guidance
- Time budget: Keep handlers fast; offload work to a queue.
5. Where to find event schemas
Go to API Reference → Webhook Events and open the event type page (e.g., menu.published.v1) for the exact JSON schema and example payloads.
6. Troubleshooting
- We don’t see any requests: Check that the subscription is enabled, the URL is public and HTTPS, and that your firewall allows Flipdish IPs (if applicable).
7. Legacy vs New
| Aspect | Legacy Webhooks | Flipdish Webhooks |
|---|---|---|
| Ownership | Webhooks tied to a user/OAuth app | Org-scoped subscriptions (belong to orgId) |
| Location in Portal | User → Developer tools → OAuth apps → Webhooks | Settings → Webhooks |
| Verification | Legacy app secret, varied patterns | HMAC-SHA256 over ${timestamp}.${rawBody} with timing-safe compare |
| Supported events | Legacy set, limited growth | New v3.0 events (e.g., menu.published.v1, menu.published.v2) |
Updated 4 months ago
