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

# Known Bots

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>This policy group functions uniquely in WAAP. Instead of challenging or blocking incoming traffic like other policy groups, it's designed to recognize and allow traffic from legitimate automated services.</p>

    <p>These services include:</p>

    * Common web crawlers like Google and Microsoft bots
    * Preview fetch bots like Slack, Facebook, or Twitter
    * SEO and monitoring tools
    * Other tools like Instant Payment Notification (IPN) requests from PayPal or HiPay

    <p>All these automation services often access your domain to gather some information and are considered beneficial or necessary for normal web activities. Note that some policies are set to **Policy-based** mode by default, and you can set them to **Allow** to fully permit traffic from the relevant services.</p>

    <p>In some cases, you might want to restrict automation tools from accessing your domain. For instance, you can do so to enforce specific data protection requirements on a domain, protect it from potentially harmful services, or restrict paid content from unauthorized use. In this case, adjust the mode for particular bots in the Known Bots section.</p>

    <Info>
      **Info**

      This policy group is available in the Pro and Enterprise plans. More details on the [Security pricing page](https://gcore.com/pricing/security#waap).
    </Info>

    ## Configure Known Bots

    <p>You can review and configure relevant bots in the [Gcore Customer Portal](https://portal.gcore.com/accounts/reports/dashboard):</p>

    1. Navigate to **WAAP** > **Bot Management**.

    2. In the domain dropdown at the top of the page, select the needed domain.

    3. Click the **Known Bots** tab to view and adjust the list of allowed bots.
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Known Bots policies control how WAAP handles traffic from 136 recognized automated services — search engine crawlers, social media preview bots, monitoring tools, and payment processors. Each bot can be set to **Allow** (bypass WAF inspection) or **Policy-based** (subject to other active WAF rules).</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required, along with the ID of a [WAAP-protected domain](/waap/getting-started/configure-waap-for-a-domain) and the [Python](/developer-tools/sdks/python) or [Go](/developer-tools/sdks/go) SDK installed for SDK examples. This policy group is available on the Pro and Enterprise WAAP plans.
    </Info>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export WAAP_DOMAIN_ID="{YOUR_DOMAIN_ID}"
    ```

    ## View bot modes

    <p>Retrieve the full list of Known Bots policies and their current modes for a domain.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import gcore
        import os

        client = gcore.Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["WAAP_DOMAIN_ID"])

        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        bot_set = next(
            rs for rs in rule_sets if rs.resource_slug == "common-automated-services"
        )

        for bot in bot_set.rules:
            mode = "Allow" if bot.mode else "Policy-based"
            print(f"{bot.name}: {mode} ({bot.id})")
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            gcore "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/option"
            "github.com/G-Core/gcore-go/waap"
        )

        func main() {
            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))
            domainID, _ := strconv.ParseInt(os.Getenv("WAAP_DOMAIN_ID"), 10, 64)

            ruleSets, _ := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
            for _, rs := range *ruleSets {
                if rs.ResourceSlug == "common-automated-services" {
                    for _, bot := range rs.Rules {
                        mode := "Policy-based"
                        if bot.Mode {
                            mode = "Allow"
                        }
                        fmt.Printf("%s: %s (%s)\n", bot.Name, mode, bot.ID)
                    }
                }
            }
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X GET "https://api.gcore.com/waap/v1/domains/${WAAP_DOMAIN_ID}/rule-sets" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          | jq '.[] | select(.resource_slug == "common-automated-services") | .rules[] | {name, id, mode}'
        ```
      </Tab>
    </Tabs>

    <p>The API returns all policies in the group. `mode: true` means Allow; `mode: false` means Policy-based.</p>

    ## Toggle a bot mode

    <p>Switch a bot between Allow and Policy-based. Each call flips the current mode. Use the View bot modes response to find the bot ID.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import gcore
        import os

        client = gcore.Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["WAAP_DOMAIN_ID"])

        # Find the bot ID by name
        rule_sets = client.waap.domains.list_rule_sets(domain_id)
        bot_set = next(
            rs for rs in rule_sets if rs.resource_slug == "common-automated-services"
        )
        bot = next(r for r in bot_set.rules if r.name == "Google Bot")

        result = client.waap.domains.policies.toggle(bot.id, domain_id=domain_id)
        mode = "Allow" if result.mode else "Policy-based"
        print(f"Google Bot is now {mode}")
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            gcore "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/option"
            "github.com/G-Core/gcore-go/waap"
        )

        func main() {
            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))
            domainID, _ := strconv.ParseInt(os.Getenv("WAAP_DOMAIN_ID"), 10, 64)

            // Find the bot ID by name
            ruleSets, _ := client.Waap.Domains.ListRuleSets(context.Background(), domainID)
            var botID string
            for _, rs := range *ruleSets {
                if rs.ResourceSlug == "common-automated-services" {
                    for _, bot := range rs.Rules {
                        if bot.Name == "Google Bot" {
                            botID = bot.ID
                        }
                    }
                }
            }

            result, _ := client.Waap.Domains.Policies.Toggle(context.Background(), botID, waap.DomainPolicyToggleParams{DomainID: domainID})
            mode := "Policy-based"
            if result.Mode {
                mode = "Allow"
            }
            fmt.Printf("Google Bot is now %s\n", mode)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        # Set BOT_POLICY_ID to the bot ID from the View bot modes response
        export BOT_POLICY_ID="{BOT_POLICY_ID}"

        curl -X PATCH "https://api.gcore.com/waap/v1/domains/${WAAP_DOMAIN_ID}/policies/${BOT_POLICY_ID}/toggle" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        {"mode": true}
        ```
      </Tab>
    </Tabs>

    <p>The API returns the updated mode. `mode: true` means Allow; `mode: false` means Policy-based.</p>
  </MethodSection>
</MethodSwitch>
