Forms
Spam protection and captcha
Spam protection in Mailiy: honeypot, spam filter, blocked IPs and optionally ALTCHA, hCaptcha, Turnstile or reCAPTCHA.

Every form has a honeypot field (botcheck), a rate limit and, if you want, allowed domains. That is usually enough. If spam still gets through, pick a captcha under Settings, for one form or as the website default.
ALTCHA has the browser solve a small computing task, with no picture puzzles and no third party. Mailiy hands out the task. Once ALTCHA is on, the snippet under Setup includes the widget:
<altcha-widget challengeurl="https://mailiy.com/api/altcha"></altcha-widget>
<script type="module" src="https://mailiy.com/api/altcha.js"></script>Mailiy serves the script itself, so your page loads nothing from a CDN. You can also put the file from the npm package altcha on your own server.
hCaptcha, Cloudflare Turnstile and reCAPTCHA work too. You create an account there, add their widget with your site key and enter the secret key in the dashboard. Mailiy stores it encrypted and never shows it again. We do not pass your visitors' IP address on when checking.
If the token is missing or wrong, Mailiy answers captcha_failed (403) and counts the submission as spam.
Spam filter and spam tab
Under Settings you turn on a spam filter per form. Normal sorts out link dumps and typical sales pitches, Strict any submission with a link or HTML. The sender still gets a normal success answer so bots learn nothing. You get no email; the submission sits in the Spam tab for 7 days and is then deleted. “Not spam” delivers it after all and moves it to the normal list. If retention is set to “Don't store”, we drop spam right away.
Under Blocked IP addresses you enter single addresses or ranges like 198.51.100.0/24 (IPv4 and IPv6). We drop submissions from there silently and store nothing.
Submissions from servers
Browsers always send the page they come from. If that is missing, the request comes from a server or script. With “Accept server submissions only with an API key” on, we refuse such requests with api_key_required (403) unless they send your API key as Authorization: Bearer mk_…. It has to be a key with write access that covers this website. With the key, the allowed-domains check and the captcha are skipped too, and the rate limit rises to 60 a minute. Never put the key in browser code.