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

# Manually add endpoints to the API base path

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>If your domain uses APIs hosted on the same domain and you don't have enabled [API Discovery](/waap/api-discovery-and-protection/api-discovery), you can manually add endpoints to the API base path. This will define a communication path for WAAP to expect API requests and protect your endpoints.</p>

    <Info>
      **Info**

      This setting doesn't add API endpoints to the allowlist.
    </Info>

    <p>When you enter a path, note that:</p>

    * Paths are recursively allowed. For example, `api/` allows `api/v1/*`, `api/v2/*`, etc.
    * Regex/wildcard input is not accepted. Use `api/` instead of `api/*`.
    * Don't enter the protocol or domain. Use `api/` instead of `https://example.foobar.com/api/`. The domain is automatically added.
    * Paths are not case-sensitive. `API/` and `api/` are interchangeable.
    * To add multiple APIs, you must create separate entries.

    ## Add endpoints to the base path

    1. In the [Gcore Customer Portal](https://portal.gcore.com/accounts/reports/dashboard), navigate to **WAAP** > **Domains**.

    <Frame>
      <img src="https://mintcdn.com/gcore/vUqVStR9rqeM7pbR/images/docs/waap/api-discovery-and-protection/domains-page.png?fit=max&auto=format&n=vUqVStR9rqeM7pbR&q=85&s=8f1884ba3cd1f10268b4fcde5a0e29f1" alt="Domains page in the Customer Portal" width="1024" height="324" data-path="images/docs/waap/api-discovery-and-protection/domains-page.png" />
    </Frame>

    2. Choose a domain from the list and click its name to open it. You'll be directed to the **Overview** page.
    3. In the sidebar, click **Settings**. On the page that opens, select the **API Base Path** tab.

    <Frame>
      <img src="https://mintcdn.com/gcore/vUqVStR9rqeM7pbR/images/docs/waap/api-discovery-and-protection/api-base-path-settings.png?fit=max&auto=format&n=vUqVStR9rqeM7pbR&q=85&s=c0f4b972a4b4159bda225bbba5741690" alt="API base path settings" width="1024" height="300" data-path="images/docs/waap/api-discovery-and-protection/api-base-path-settings.png" />
    </Frame>

    4. Either enable the **Set as API Domain** checkbox to treat the whole domain as an API or enter a specific API endpoint path into the **Host** input field.
    5. Click the **Add** button, and the endpoint will appear in the **Endpoint** table below.

    ## Remove endpoints from the base path

    1. Find the relevant endpoint and click the three-dot icon next to it.
    2. Select **Delete**.
    3. Confirm your action by clicking **Delete** again.

    <p>After you configure the API base path, CAPTCHA and JavaScript validation will be disabled for added endpoints.</p>

    <p>The [DDoS protection](/waap/ddos-protection), [IP reputation](/waap/waap-policies/ip-reputation), and rate limitation features will continue to protect those endpoints. Custom [WAAP rules](/waap/waap-rules/custom-rules) and [firewall rules](/waap/firewall/access-control#managing-allowed-and-blocked-ips) can also impact content delivery via API and potentially block users.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>If a domain uses APIs hosted on the same domain and [API Discovery](/waap/api-discovery-and-protection/api-discovery) is not enabled, manually configure the API base path via the [Domains](/api-reference/waap#domains) settings endpoints to tell WAAP which paths to treat as API traffic. WAAP then disables CAPTCHA and JavaScript validation for those paths while keeping DDoS, IP reputation, and rate limiting active. Response examples include only the fields used in each step.</p>

    <Info>
      **Info**

      This setting doesn't add API paths to the allowlist.
    </Info>

    <p>When configuring API paths, note that:</p>

    * Paths are recursively allowed. For example, `api/` covers `api/v1/*`, `api/v2/*`, etc.
    * Regex/wildcard input is not accepted. Use `api/` instead of `api/*`.
    * Don't include the protocol or domain. Use `api/` instead of `https://example.foobar.com/api/`.
    * API paths are not case-sensitive. `API/` and `api/` are interchangeable.

    <Warning>
      **Warning**

      The `api_urls` field **replaces** the entire list on every update. Sending `{"api_urls": ["api/v3/"]}` will erase all previously configured paths, leaving only `api/v3/`. Always retrieve the current list first and include all existing paths in the update.
    </Warning>

    <Info>
      **Info**

      To make API calls, an [API token](/account-settings/api-tokens) is required. To get the domain ID, use [List domains](/waap/getting-started/manage-domains#list-domains).
    </Info>

    ```bash theme={null}
    export GCORE_API_KEY=your_api_key
    export DOMAIN_ID=your_domain_id
    ```

    ## View current configuration

    <p>Returns the current API base path settings, including the `is_api` flag and the configured `api_urls` list.</p>

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

        load_dotenv()
        client = Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["DOMAIN_ID"])

        settings = client.waap.domains.settings.get(domain_id)
        print("is_api:", settings.api.is_api)
        print("api_urls:", settings.api.api_urls)
        ```
      </Tab>

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

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

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

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

            settings, err := client.Waap.Domains.Settings.Get(context.TODO(), domainID)
            if err != nil {
                panic(err.Error())
            }
            fmt.Println("is_api:", settings.API.IsAPI)
            fmt.Println("api_urls:", settings.API.APIURLs)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X GET "https://api.gcore.com/waap/v1/domains/${DOMAIN_ID}/settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        <Accordion title="Response">
          ```json theme={null}
          {
            "api": {
              "is_api": false,
              "api_urls": ["api/v1/", "api/v2/"]
            }
            // ...
          }
          ```
        </Accordion>
      </Tab>
    </Tabs>

    ## Configure API paths

    <p>Add or remove API paths by sending the complete updated list. Always read the current list first, then modify it and send the result. Both operations use the same `PATCH /waap/v1/domains/{id}/settings` call. Returns HTTP 204 with no response body.</p>

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

        load_dotenv()
        client = Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["DOMAIN_ID"])

        settings = client.waap.domains.settings.get(domain_id)
        current = settings.api.api_urls or []

        # Add a path
        client.waap.domains.settings.update(
            domain_id,
            api={"api_urls": current + ["api/v3/"]},
        )

        # Remove a path
        # client.waap.domains.settings.update(
        #     domain_id,
        #     api={"api_urls": [u for u in current if u != "api/v2/"]},
        # )
        ```
      </Tab>

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

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

            "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("DOMAIN_ID"), 10, 64)

            settings, err := client.Waap.Domains.Settings.Get(context.TODO(), domainID)
            if err != nil {
                panic(err.Error())
            }

            // Add a path
            err = client.Waap.Domains.Settings.Update(context.TODO(), domainID, waap.DomainSettingUpdateParams{
                API: waap.DomainSettingUpdateParamsAPI{
                    APIURLs: append(settings.API.APIURLs, "api/v3/"),
                },
            })
            if err != nil {
                panic(err.Error())
            }
            fmt.Println("Updated.")

            // Remove a path: filter the list and send the result
            // pathToRemove := "api/v2/"
            // var updated []string
            // for _, u := range settings.API.APIURLs {
            //     if u != pathToRemove {
            //         updated = append(updated, u)
            //     }
            // }
            // client.Waap.Domains.Settings.Update(ctx, domainID, waap.DomainSettingUpdateParams{
            //     API: waap.DomainSettingUpdateParamsAPI{APIURLs: updated},
            // })
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        # Retrieve current paths first, then send the full updated list.
        # This example adds api/v3/ to an existing [api/v1/, api/v2/] list.
        curl -X PATCH "https://api.gcore.com/waap/v1/domains/${DOMAIN_ID}/settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"api": {"api_urls": ["api/v1/", "api/v2/", "api/v3/"]}}'

        # To remove api/v2/, send the list without it:
        # -d '{"api": {"api_urls": ["api/v1/", "api/v3/"]}}'
        ```
      </Tab>
    </Tabs>

    ## Set domain as API

    <p>When `is_api` is enabled, WAAP treats all domain traffic as API requests and disables browser challenges globally — individual `api_urls` entries are ignored but remain stored and take effect again when `is_api` is set back to `false`. Returns HTTP 204 with no response body.</p>

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

        load_dotenv()
        client = Gcore(api_key=os.environ["GCORE_API_KEY"])
        domain_id = int(os.environ["DOMAIN_ID"])

        client.waap.domains.settings.update(
            domain_id,
            api={"is_api": True},
        )
        ```
      </Tab>

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

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

            "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("DOMAIN_ID"), 10, 64)

            err := client.Waap.Domains.Settings.Update(context.TODO(), domainID, waap.DomainSettingUpdateParams{
                API: waap.DomainSettingUpdateParamsAPI{
                    IsAPI: gcore.Bool(true),
                },
            })
            if err != nil {
                panic(err.Error())
            }
            fmt.Println("Updated.")
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X PATCH "https://api.gcore.com/waap/v1/domains/${DOMAIN_ID}/settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"api": {"is_api": true}}'
        ```
      </Tab>
    </Tabs>
  </MethodSection>
</MethodSwitch>
