MainSDK
Search⌘K
How-to

Use bot defence in your app

Score the sign-in, sign-up, reset and invite doors in process, challenge or refuse bots with a proof-of-work, and stop SMS and WhatsApp pumping before a message is paid for.

Building for 0.3

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

You will add bots to your app and check that it works. It takes about 15 minutes.

You need

1. Turn it on

Add a bots section. The five built-in doors (sign-in, sign-up, reset, whatsapp, invite) are scored with sensible thresholds. Start in observe to see what would be challenged.

main.yaml
bots:
  mode: observe

2. Protect a form of your own

Declare the door, render the token and honeypot in the page, and the engine refuses a post without a valid token with MAIN-BOT-0004.

main.yaml
bots:
  doors:
    contact: { path: /api/contact, form: true }
app/contact.ts
import { bots } from "mainsdk/bots";

const { html } = bots.formFields();   // put this inside your <form>

3. Solve challenges in the browser

web/send.ts
import { fetchWithChallenge } from "mainsdk/bots/client";

export async function send(data: FormData) {
  return fetchWithChallenge("/api/contact", { method: "POST", body: data });
}

4. Stop message pumping

Set the countries you serve and the send limits. The WhatsApp code send refuses before any message is paid for.

main.yaml
bots:
  pumping: { per-prefix: { max: 10, per: 1h }, countries: [IN] }

Check it worked

Run npx mainsdk check. It passes when bots is configured as shown.

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet