> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boxd.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Bot protection

> Keep crawlers from waking your sleeping machines.

Every machine gets a public HTTPS certificate, and public certificates are listed in public logs. Crawlers read those logs and probe every hostname they find. Without protection, each probe would wake a machine that was [sleeping](/guides/suspend-resume) just to answer a bot.

Bot protection stops that. When a request would wake a sleeping machine, boxd first asks the visitor to pass a quick browser check. A real browser gets through in a second or two and the machine wakes as usual. A crawler doesn't, and the machine stays asleep.

**On by default** for every machine.

## What visitors see

A visitor who hits a sleeping machine sees a short "This machine is asleep" page with a [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) check. Most of the time the check passes on its own without the visitor clicking anything. Once it passes, the page reloads, the machine wakes, and your app answers the request.

A passed check lasts **24 hours** in that browser, for every machine on the same domain. Visiting another sleeping machine under `boxd.sh` in that time doesn't ask again.

## When the check applies

The check only runs when **all** of these are true:

* The machine is asleep (in standby or hibernated). A running machine is never checked, since there's nothing to wake.
* The request is for the machine's main address, `myvm.boxd.sh` or `www.myvm.boxd.sh`. If your org has a [wildcard domain](/guides/custom-domains#org-wide-wildcard-domain), `myvm.vms.mysaas.com` and `www.myvm.vms.mysaas.com` are covered too.
* Bot protection is on for the machine.

These are never checked:

* [Named proxies](/guides/proxies) such as `api.myvm.boxd.sh`.
* [Custom domains](/guides/custom-domains) pointed at a single machine.
* Traffic over your org's [Tailscale](/guides/tailscale) network. Only your tailnet can reach it, so bot protection is off there whatever the machine's setting.
* SSH. It already requires your key, so it wakes machines as before.

The browser remembers a passed check with a boxd cookie. boxd removes that cookie before the request reaches your app, so your app never sees it.

## Webhooks and API clients

Only a browser can pass the check. A webhook sender, API client, `curl` or uptime monitor that hits a sleeping machine gets the check page with a `503` instead of your app, and the machine doesn't wake.

If a machine needs to be woken by something other than a browser, either turn bot protection off for it, or send that traffic to a [named proxy](/guides/proxies) (for example `hooks.myvm.boxd.sh`), which is never checked.

## Turning it off or on

<CodeGroup>
  ```bash CLI theme={"theme":"github-dark"}
  boxd machine config get myvm bot-protection      # on / off
  boxd machine config set myvm bot-protection off  # any request can wake it again
  boxd machine config set myvm bot-protection on
  ```

  ```typescript TypeScript theme={"theme":"github-dark"}
  await boxd.machines.setBotProtection("myvm", false);
  (await boxd.machines.get("myvm")).botProtection; // false
  ```

  ```python Python theme={"theme":"github-dark"}
  boxd.machines.set_bot_protection("myvm", False)
  boxd.machines.get("myvm").bot_protection  # False
  ```
</CodeGroup>

In the console, it's the **Bot protection** switch on the machine's **Settings** tab. From inside a machine, the in-VM `boxd` takes the same `machine config set <name> bot-protection off` command.

Forks keep the setting of the machine they came from, and a machine restored from a [snapshot](/guides/snapshots) keeps the setting the snapshot was taken with.
