use case · webflow

Add content-level spam scoring to Webflow forms.

Updated July 29, 2026

Webflow includes native Cloudflare Turnstile bot blocking and spam filtering, so enable those controls first. Add Siftfy when you need content-level scoring, custom allow, review, and block thresholds, or routing before a lead reaches your CRM. Connect it through a custom action, Webflow App, or automation endpoint.

Native controls are the right baseline for obvious bot traffic. Siftfy adds a separate content decision for forms where the message itself determines whether a submission should be delivered, held for review, or silently discarded.

Choose the integration path that matches your form

A custom form action can send the submission directly to your own HTTPS handler, where it can be classified before delivery. Webflow Apps and automation tools can also forward native submissions to a handler, which is useful when you want Webflow to keep the original record. Confirm the behavior for your workspace before cutover: custom actions bypass Webflow's submission processing and notification emails.

On-page CAPTCHA, by contrast, is a tax on every legitimate visitor and is bypassed by any bot running a real headless browser. Modern spam isn't dumb form-fillers — it's content. Classify the content.

Drop-in Cloudflare Worker

The pattern below is a small Cloudflare Worker used as the form's custom action and forwarding accepted submissions to your real destination. The same shape works on Vercel Functions, Netlify Functions, AWS Lambda, or a tiny Express app you already run. Three thresholds — definitely-spam (drop), maybe (queue), clean (deliver) — and a 2-second timeout so a slow Siftfy call never makes the form-submission UX feel broken.

javascript
// Cloudflare Worker used as a Webflow custom form action.
// Point the form action to https://your-worker.workers.dev/webflow.
// A custom action bypasses Webflow's own submission storage and emails,
// so forward accepted submissions to the destination you control.

// The drop threshold is not a constant: /v1/predict returns max_confidence,
// the highest score the model may return on its own word. Only a score above
// it carries evidence beyond the model, so only that is safe to drop.
const QUEUE_THRESHOLD = 0.50;  // human review between

export default {
  async fetch(req, env) {
    if (req.method !== "POST") return new Response("method", { status: 405 });

    // Webflow posts form fields as application/x-www-form-urlencoded.
    const form = await req.formData();
    const message = String(form.get("message") ?? form.get("description") ?? "");
    const email = String(form.get("email") ?? "");

    let probability = 0;
    let ceiling = null;
    try {
      const resp = await fetch("https://api.siftfy.io/v1/predict", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-API-Key": env.SIFTFY_KEY,
        },
        body: JSON.stringify({ text: message }),
        signal: AbortSignal.timeout(2000),
      });
      if (resp.ok) {
        ({ spam_probability: probability, max_confidence: ceiling = null } = await resp.json());
      }
    } catch {
      // Fall open on transport failure — don't drop a real lead.
    }

    if (ceiling !== null && probability > ceiling) {
      // Always 200 to Webflow, even on a hard block. The form sees "thanks"
      // and the spammer doesn't learn the threshold.
      return new Response("ok", { status: 200 });
    }

    // Forward clean / borderline submissions to your real handler
    // (CRM, email service, Airtable, n8n, whatever).
    await env.DESTINATION.fetch(`https://hooks.example.com/lead?score=${probability}`, {
      method: "POST",
      body: JSON.stringify({ email, message, probability }),
      headers: { "Content-Type": "application/json" },
    });

    return new Response("ok", { status: 200 });
  },
};

Wiring it up in Webflow

  1. Deploy the worker (or function) to a public HTTPS URL.
  2. Set the form's custom action to the worker URL and use POST.
  3. Test with a clean submission and a junk submission — junk should be silently dropped, clean should land at your destination.
  4. Set a SIFTFY_KEY secret on the worker (Cloudflare Dashboard → Workers → Variables → Encrypt).

Because a custom action bypasses Webflow's submission storage and notifications, the worker must forward accepted submissions to your inbox, CRM, database, or automation endpoint itself.

Edge cases worth handling

  • Multiple form types. Webflow sends a name field identifying the form. Branch on it if you classify a contact form differently from a newsletter signup (newsletters tolerate higher false positives).
  • Long message bodies. Siftfy truncates input above its model context — for long bug reports or product feedback, you don't need the entire body, just the first 500 words. Slice client-side.
  • Multilingual forms. The model is trained primarily on English, and the confidence ceiling is per-language — it can be lower than English, so read it from each response instead of raising a constant.
  • Don't reveal the score. Always return 200 to Webflow. A 4xx makes Webflow show a generic error to the user and tells the spammer their content was flagged.

Common questions

Does Webflow already block form spam?

Yes. Webflow includes native Cloudflare Turnstile bot blocking and its own spam filtering, and for many sites those controls are enough. Add Siftfy when you also need a content-level decision — for example, when spam is written to look like a real message and passes the native checks, or when you want submissions routed to block, review, and deliver queues based on a score.

How do I add Siftfy to a Webflow form?

Point the form's custom action at your own HTTPS endpoint — a Cloudflare Worker, Netlify or Vercel function, AWS Lambda, or an existing Express route. The handler sends the message text to POST /v1/predict with an X-API-Key header, then drops, queues, or forwards the submission based on the returned probability.

Does a custom form action break Webflow submissions or notifications?

A custom action bypasses Webflow's own submission storage and notification emails, so your handler must forward accepted submissions to your inbox, CRM, database, or automation endpoint. If you want Webflow to keep the original record, use a Webflow App or an automation tool to forward a copy to the same handler instead.

What block and review thresholds should I start with?

Take the hard-drop boundary from the response rather than choosing a number: drop only above the `max_confidence` it reports, and review from 0.50 up to that ceiling. Run in shadow mode against real submissions before enforcing. Always return HTTP 200 to Webflow even when you drop a submission, and fail open on transport errors so a slow classifier never loses a legitimate lead.

Try it free

10,000 submissions / month free. Read the /v1/predict reference, or peek at related use cases: contact forms, static sites, headless CMS.

Go deeper: stopping Webflow form spam, spam detection for headless forms, stopping contact-form spam without CAPTCHA.