28 August 2026 · platforms, integration

Adding spam filtering to a form service in an afternoon

A walkthrough for form backends and builders: one platform key, a key per customer form, one call before delivery, and a button your customers will thank you for.

If you run a form backend, spam is the feature request you get in the form of complaints. “My inbox is full of SEO pitches.” “Can you add a CAPTCHA?” “I switched to a competitor.” Building a filter is a project; renting one is an afternoon. Here is the afternoon.

1. Provision keys the way you provision forms

You hold one platform key. When a customer creates a form, your backend calls the platform API once and gets a key for that form. Store it encrypted next to the form, the same way you store any per-form secret. Each form key carries its own settings, quota, usage and memory, so one customer’s corrections never affect another’s.

Rotate and revoke keys through the same API when forms are edited or deleted, and read the per-form usage roll-up for your own billing.

2. Classify before you deliver

In your delivery pipeline, right before the email or webhook goes out, send the submission and the visitor’s IP with the form’s key. If your ingest path answers the visitor’s browser, use fast mode: it returns in a few milliseconds and tags the handful of cases that would benefit from a second opinion. Re-check only those from your delivery queue.

Store the verdict id, label, score and reason codes on the submission. Deliver ham. Route spam to a Spam tab.

3. Give your customers the button

The single most effective support-ticket reducer is a “Not spam” button that works. Wire it to the feedback endpoint. The message is delivered, the sender gets a good mark for that form, and the customer just fixed their own problem without emailing you. A “Mark as spam” button on the inbox side does the reverse, and you can batch both.

4. Show the reason

Next to every filtered message, show the reason in plain words: “hidden field was filled in”, “same message sent to other sites this week”, “looks like a cold pitch”. Customers trust a filter they can see. The reason-code reference has suggested wording for every code.

5. Fail open

If spamex is slow or unreachable, deliver. Your customers should never lose a message because of a dependency. The integration guides show the pattern in each language.

That is the whole integration. Most of the afternoon goes on the Spam tab in your UI, which is the part your customers will actually notice.