mcpField
W
webflow-webhooks

webflow-webhooks

github.com/224-industriesDevelopment1072 installsUpdated 1w ago
Repository

About webflow-webhooks

A reference skill for implementing Webflow webhook endpoints, aimed at developers handling site events. It covers event types, signature checks, delivery behavior, and searchable setup documentation.

Key features

  1. 01Reference for 14 webhook event types
  2. 02HMAC-SHA256 signature verification
  3. 03Timestamp checks against replay attacks
  4. 04Webhook setup and API documentation
  5. 05Searchable reference files

Use cases

  1. 01Process Webflow form and CMS events
  2. 02Handle ecommerce and publishing notifications
  3. 03Verify webhook requests before processing

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/224-industries/webflow-skills --skill webflow-webhooks

After installing, type/webflow-webhooksin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
event-types.md
faq.md
overview.md
setup.md
verification.md
webhook-api.md
scripts/
search_references.py

Details

From the project README

Webflow Webhooks

Receive, verify, and process Webflow webhook events for form submissions, CMS changes, ecommerce orders, site publishing, and more.

Quick Start Workflow

Prerequisite: You need a Webflow account with an active site. For signature verification, create webhooks via the API (not the dashboard) — see Setup.

  1. Create webhook: Register a webhook via the Webflow API for your desired event type
  2. Receive events: Set up an endpoint that accepts POST requests with raw body parsing
  3. Verify signatures: Validate x-webflow-signature and x-webflow-timestamp headers
  4. Process events: Route events by triggerType and handle each accordingly
  5. Acknowledge: Return 200 to confirm receipt (other statuses trigger retries)
Signature Verification
const crypto = require('crypto');

function verifyWebflowSignature(rawBody, signature, timestamp, secret) {
  // Check timestamp to prevent replay attacks (5 minute window - 300000 milliseconds)
  const currentTime = Date.now();
  if (Math.abs(currentTime - parseInt(timestamp)) > 300000) {
    return false;
  }

  // Generate HMAC signature
  const signedContent = `${timestamp}:${rawBody}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedContent)
    .digest('hex');

  // Timing-safe comparison
  try {
    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(expectedSignature)
    );
  } catch {
    return false; // Different lengths = invalid
  }
}
Processing Events
app.post('/webhooks/webflow', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webflow-signature'];
  const timestamp = req.headers['x-webflow-timestamp'];

  if (!signature || !timestamp) {
    return res.status(400).send('Missing required headers');
  }

  const isValid = verifyWebflowSignature(
    req.body.toString(),
    signature,
    timestamp,
    process.env.WEBFLOW_WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(400).send('Invalid signature');
  }

  const event = JSON.parse(req.body);

  switch (event.triggerType) {
    case 'form_submission':
      console.log('New form submission:', event.payload.data);
      break;
    case 'ecomm_new_order':
      console.log('New order:', event.payload);
      break;
    case 'collection_item_created':
      console.log('New CMS item:', event.payload);
      break;
    case 'collection_item_published':
      console.log('Published CMS items:', event.payload.items);
      break;
  }

  res.status(200).send('OK');
});

Event Types

Webflow supports 14 webhook event types across 6 categories: Forms, Site, Pages, Ecommerce, CMS, and Comments. See references/event-types.md for the complete reference with all payload schemas and examples.

CategoryEventsRequired Scope
Formsform_submissionforms:read
Sitesite_publishsites:read
Pagespage_created, page_metadata_updated, page_deletedpages:read
Ecommerceecomm_new_order, ecomm_order_changed, ecomm_inventory_changedecommerce:read
CMScollection_item_created, collection_item_changed, collection_item_deleted, collection_item_unpublished, collection_item_publishedcms:read
Commentscomment_createdcomments:read

Environment Variables

# For webhooks created via OAuth App
WEBFLOW_WEBHOOK_SECRET=your_oauth_client_secret

# For webhooks created via API (after April 2025)
WEBFLOW_WEBHOOK_SECRET=whsec_xxxxx  # Returned when creating webhook

Best Practices

  1. Always verify signatures: Use HMAC-SHA256 verification for webhooks created via OAuth or API — see Verification
  2. Use raw body for verification: Never verify against parsed JSON; configure your framework accordingly
  3. Validate timestamps: Enforce a 5-minute window (300000ms) to prevent replay attacks
  4. Return 200 quickly: Acknowledge receipt immediately; process events asynchronously for heavy workloads
  5. Handle retries gracefully: Webflow retries up to 3 times on failure (10-minute intervals) — implement idempotency
  6. Use HTTPS in production: Webhook endpoints must use HTTPS for security

Important Notes

  • Never handle secrets in plain text. API tokens, OAuth client secrets, and webhook signing secrets must always be stored in environment variables or a secrets manager. Never ask the user for tokens or secrets directly, and never hard-code them in source files.
  • Webhooks created through the Webflow dashboard do NOT include signature headers
  • Only webhooks created via OAuth apps or API include x-webflow-signature and x-webflow-timestamp
  • Timestamp validation (5 minute window - 300000 milliseconds) is critical to prevent replay attacks
  • Return 200 status to acknowledge receipt; other statuses trigger retries (up to 3 times, 10-minute intervals)

Reference Documentation

Each reference file includes YAML frontmatter with name, description, and tags for searchability. Use the search script available in scripts/search_references.py to quickly find relevant references by tag or keyword.

Searching References
# List all references with metadata
python scripts/search_references.py --list

# Search by tag (exact match)
python scripts/search_references.py --tag <tag>

# Search by keyword (across name, description, tags, and content)
python scripts/search_references.py --search <query>

Scripts

  • scripts/search_references.py: Search reference files by tag, keyword, or list all with metadata

Comments

Markdown supported