Verify emails on any website form with the Spaw form helper

updated · September 3, 2026

One script tag adds live email verification to Webflow, Framer, Squarespace, Carrd or plain HTML forms: typo fixes and dead-address notices, never blocking.

Mechanism
Dependency-free script served from spaw.co
Works today
Yes, on any page that accepts custom code
Auth
Domain-locked publishable key, or your own proxy endpoint
Cost
1 credit per answered lookup, undeliverable answers free
Bot protection
Optional Cloudflare Turnstile pair on the key

The Spaw form helper is a small script that watches the email inputs you mark, verifies the address when the visitor leaves the field, and renders two things: a "Did you mean …?" correction when the address looks like a typo, and a notice when the address cannot receive mail. It never blocks a submit and never waits for the API, so a slow network or an empty credit balance only means the hint does not appear. It works on any page where you can add custom code, which covers Webflow, Framer, Squarespace, Carrd and a hand-written HTML form alike.

Add it to a form

  1. On the API keys page, create a publishable key and lock it to the domains your form runs on. A publishable key can only run single email lookups from those origins, so it is safe in page source.
  2. Give the key a daily credit cap. Once the cap is spent the browser endpoint answers 429 KEY_SPEND_CAP_REACHED until the next day, and the helper stays quiet.
  3. Add the script and mark the input:
<script src="https://spaw.co/spaw-form.js" data-key="pk_live_…" defer></script>

<input type="email" name="email" data-spaw-email>
  1. For forms open to the public, store a Cloudflare Turnstile site key and secret on the publishable key and add data-turnstile-site-key to the script tag. The helper then fetches a fresh single-use token before every lookup and the endpoint refuses lookups without one, so a bot scripting your form cannot spend your credits. Turnstile only shows a challenge when Cloudflare needs one.

When you cannot set an attribute on the input

Some builders let you add custom code to the page but not attributes to a form field. Mark the field from a short script placed before the helper's script tag. Listeners registered earlier run first, so the input is marked before the helper looks for it:

<script>
  document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('form input[type="email"]').forEach(function (input) {
      input.setAttribute('data-spaw-email', '');
    });
  });
</script>
<script src="https://spaw.co/spaw-form.js" data-key="pk_live_…" defer></script>

In Webflow and Framer, paste both tags into the site's custom code section that lands in the head; Squarespace and Carrd take them in the page or site code injection settings. On a plain HTML page, put them anywhere in the document.

Keep your secret key on the server instead

If you would rather not use a publishable key, point data-endpoint at a route you host. The helper posts { "email": "…" } there and expects the API's JSON back unchanged; the route adds your secret key and forwards the request to POST /api/v1/email. A five-line proxy in any framework does it; the product page shows Laravel and Node versions. Rate-limit the route, because it spends your credits.

Enforce your own policy

Every verdict is emitted as a bubbling spaw:result event on the input, with the full API response in event.detail. The helper itself only hints; the event is where you decide:

<script>
  addEventListener('spaw:result', function (event) {
    var result = event.detail;

    if (result.disposable || result.deliverable === 'undeliverable') {
      document.querySelector('button[type="submit"]').disabled = true;
    }
  });
</script>

The response is the same 27-field answer the API gives a server, minus the billing block, so page visitors never see your balance. Branch on deliverable, use did_you_mean to offer the fix, and read reason before refusing anything marked risky: a catch-all domain is risky but often a fine address.

Cost

One credit per answered lookup, charged to the key's owner. Undeliverable answers, repeats within seven days and the free test addresses on spaw.test cost nothing and never count toward the key's daily cap. Every account gets 10 free lookups a month.

Related

markdown version: /integrations/website-forms.md

Verify addresses the same way

The Spaw API runs every check described here on each lookup, with an SMTP handshake that never sends mail. 10 free lookups a month, no card required.

Get your API key

More integrations