---
title: Probe locations & IP ranges
description: The 20 locations in 7 regions WatchFor checks from, the published IP ranges, and how to allowlist and cryptographically verify WatchForBot requests.
canonical: https://watchfor.io/docs/reference/probe-locations
---

# Probe locations & IP ranges

The 20 locations in 7 regions WatchFor checks from, the published IP ranges, and how to allowlist and cryptographically verify WatchForBot requests.

WatchFor runs checks from **20 locations across 7 world regions**. Checking
from many vantage points is what lets it tell a real outage from a local
network hiccup — and what makes latency numbers honest.

## Locations

| Region | Locations |
| --- | --- |
| Europe | Paris, Frankfurt, Vilnius, Madrid, Stockholm, London |
| North America | Ashburn, Columbus, Portland, Montreal, Querétaro |
| South America | São Paulo |
| Asia | Mumbai, Jakarta, Singapore, Tokyo |
| Middle East | Tel Aviv |
| Africa | Cape Town |
| Oceania | Sydney, Auckland |

Locations check over **IPv4 and IPv6** (all but one are dual-stack today).
The list grows over time — the
live list, with addresses and hostnames, is at
[watchfor.io/ip-ranges](/ip-ranges), and the location ids you need for the
API are returned by [`GET /v1/locations`](/docs/api/locations).

## Why multiple locations

- **Fewer false alarms** — a failure is [confirmed](/docs/alerting/incidents)
  from several locations before an incident opens and anyone is paged. A
  single failed location shows the monitor as **Degraded**, not **Down**.
- **Regional insight** — see when a problem affects one region but not others.
- **Honest latency** — response times reflect real-world distance, not one
  lucky data center.

Which locations a monitor uses, how many, and whether it runs from several at
once, is set per monitor and depends on your plan — see
[How checks run](/docs/monitors#how-checks-run) and [pricing](/pricing).

## Allowlisting WatchFor

If your service sits behind a firewall, WAF or allowlist, permit WatchFor's
probe addresses so checks aren't blocked. The full, current list — grouped by
region, with IPv4, IPv6 and hostnames — is at [watchfor.io/ip-ranges](/ip-ranges).

For automated allowlisting, pull one of the machine-readable endpoints on a
schedule instead of hard-coding addresses, so new locations are picked up
automatically:

- [`/ips.json`](/ips.json) — structured: `ipv4Prefix` / `ipv6Prefix` with
  `hostname`, `city` and `country` per entry
- [`/ipv4.txt`](/ipv4.txt) — plain IPv4 list, one per line
- [`/ipv6.txt`](/ipv6.txt) — plain IPv6 list, one per line

## Identifying and verifying WatchForBot

Every check that speaks HTTP identifies itself with one stable User-Agent:

```
Mozilla/5.0 (compatible; WatchForBot/1.0; +https://watchfor.io/bot)
```

A User-Agent can be spoofed, so there are three independent ways to verify a
request really came from WatchFor:

1. **Source IP** — requests come only from the published ranges above.
2. **Forward-confirmed reverse DNS** — every probe IP has a PTR record under
   `*.probe.watchfor.io`, named `<city>-<n>.<cc>.probe.watchfor.io` (for
   example `frankfurt-1.de.probe.watchfor.io`), and that hostname resolves
   back to the same IP. Reverse lookup, then forward lookup, then compare.
3. **Web Bot Auth request signatures** — HTTP(S) probe requests carry
   RFC 9421 HTTP message signatures with the `web-bot-auth` tag, signed with
   Ed25519:

   ```
   Signature-Agent: "https://watchfor.io"
   Signature-Input: sig1=("@authority" "signature-agent");created=…;expires=…;keyid="…";alg="ed25519";tag="web-bot-auth"
   Signature: sig1=:…base64 Ed25519 signature…:
   ```

   Fetch the public keys from
   `https://watchfor.io/.well-known/http-message-signatures-directory` and
   verify the signature — cryptographic proof that the request is ours.
   Bot-management platforms that support Web Bot Auth can allowlist WatchFor
   on this basis alone.

Signatures are sent by the HTTP-based probe types (website, API, MCP,
WebSocket, SSL/TLS certificate and grade, CDN, sitemap, favicon, Brotli, CMS,
domain and breach checks). Network-level checks (ping, TCP, UDP, DNS, MTR, NTP, SMTP,
FTP, SFTP) carry no HTTP headers, so verify those by IP and reverse DNS.

What the bot does — and doesn't:

- It performs exactly the checks a customer configured, on the schedule they
  chose, from one location per check.
- It does **not** crawl your site, follow links or harvest content; it only
  touches the exact target of each monitor. Blocking it only breaks monitoring
  for the customer who configured it.

The [bot page](/bot) is the public reference for all of this.

## Using Cloudflare? Allowlist us in two minutes

Cloudflare's bot protection (managed challenges, Bot Fight Mode, Super Bot
Fight Mode) can answer our probes with a JavaScript challenge — which a
monitoring request never solves. The result looks like a slow or failing site
in your dashboard even though real visitors are fine. One WAF rule fixes it:

1. In the Cloudflare dashboard open your zone → **Security → WAF → Custom
   rules** → **Create rule**.
2. Name it, for example, `Allow WatchFor monitoring`, and set the expression to
   match our User-Agent:

   ```
   (http.user_agent contains "WatchForBot")
   ```

3. Choose the action **Skip**, and tick at least *All managed challenges* and
   the bot-protection features you have enabled.
4. Deploy. Checks pass from the next run — nothing to restart on our side.

Worried about User-Agent spoofing? Add the probe IPs from
[`/ipv4.txt`](/ipv4.txt) and [`/ipv6.txt`](/ipv6.txt) to a Cloudflare
**IP list** and match `ip.src in $watchfor_probes` alongside the User-Agent.

The same idea applies to other CDNs and WAFs (Akamai, Fastly, AWS WAF):
exempt the `WatchForBot` User-Agent and/or our published IP ranges from bot
challenges and rate limits.

> **Info**
>
> Seeing failures only from WatchFor while your site is up? A firewall,
> rate limiter or bot challenge blocking probe IPs is the usual cause —
> allowlist the [published ranges](/ip-ranges) or add the Cloudflare rule
> above. The incident's [root-cause view](/docs/alerting/root-cause) shows the
> exact response each location received.

## Choosing IP version

Checks default to **IPv4**. Where your target supports it, switch a monitor to
**IPv6** in its settings — useful for verifying that your AAAA records and
IPv6 path actually work, not just that the IPv4 side does.

> **Also via API**
>
> `GET /v1/locations` lists every location with its id, city, country and
> region — pass those ids as `locations` when creating monitors. The
> `list_locations` MCP tool and `list-locations` A2A skill return the same.

---

Canonical page: https://watchfor.io/docs/reference/probe-locations · All docs: https://watchfor.io/docs · Site guide: https://watchfor.io/llms.txt
