watchfor (Python)
Official Python SDK + CLI for WatchFor — uptime & infrastructure monitoring (monitors, alert rules, incidents, maintenance windows) over the REST API. Zero dependencies (standard library only).
There is also a TypeScript SDK, an MCP server and an A2A agent for AI agents.
Install
pip install watchfor
Quick start
from watchfor import WatchFor
wf = WatchFor(api_key="wf_live_...") # create keys in Settings → API keys
# One-call org snapshot
print(wf.summary())
# List monitors
for m in wf.monitors.list()["data"]:
print(m["name"], m["status"])
# Create a monitor (idempotency key optional, for safe retries)
mon = wf.monitors.create(
{
"name": "example.com",
"type": "http",
"target": "https://example.com",
"interval": 300,
"locations": ["<location-id>"], # from wf.locations()
},
idempotency_key="create-example-1",
)
# Diagnose: firing incidents right now
for inc in wf.incidents.list(status="firing")["data"]:
print(inc["message"], inc["severity"])
# False positive? Keep the resolved incident on record but drop it from
# uptime, SLA, reports and the status page (include() undoes it)
wf.incidents.exclude(19351, reason="Probe-side DNS hiccup")
# Irreversible: wipe a monitor's checks and incidents; uptime restarts "since reset"
wf.monitors.reset(mon["id"])
# Older checks: pass next_cursor back as cursor (keep the same hours/success)
page = wf.monitors.checks(mon["id"], hours=24, limit=100)
if page["next_cursor"]:
wf.monitors.checks(mon["id"], hours=24, limit=100, cursor=page["next_cursor"])
# Delete a contact group that alert rules still use (409 without force)
wf.contact_groups.delete("<group-id>", force=True)
Live diagnostics
Run any of 18 checks from WatchFor's probe fleet against any public target, monitored or not — this measures right now, rather than reading what WatchFor recorded:
# What can I run, and how much budget is left?
catalog = wf.diagnostics.list()
# One check, optionally from a location you choose (plan-gated)
dns = wf.diagnostics.run(
"dns-lookup", "example.com", options={"recordType": "A", "resolver": "8.8.8.8"}
)
# A closed port / NXDOMAIN / failed handshake does NOT raise:
if not dns["success"]:
print("finding:", dns["error"])
print("runs left this hour:", dns["remaining"])
# The whole picture in one call: DNS + propagation + TLS + HTTP + ping
# from up to 3 regions, aggregated into one verdict
report = wf.diagnostics.diagnose_target("example.com")
print(report["verdict"]["status"], report["verdict"]["summary"])
Runs need a write key (a probe sends real traffic from WatchFor's IPs)
and spend the same per-plan hourly allowance as the dashboard Toolbox.
Details: https://watchfor.io/docs/api/diagnostics
Resource namespaces: wf.monitors, wf.alert_rules, wf.incidents,
wf.maintenance_windows, wf.contacts, wf.contact_groups,
wf.diagnostics. Top-level:
wf.summary(), wf.plan(), wf.me(), wf.locations(), wf.monitor_types(),
wf.incident_stats(period=...), wf.notifications(...), wf.activity(...).
Errors raise WatchForError with .status, .code and .message.
CLI
export WATCHFOR_API_KEY=wf_live_...
watchfor summary
watchfor monitors
watchfor incidents --status firing
watchfor checks <monitor_id> [--cursor <next_cursor>]
watchfor report --period 30d
Auth & scopes
Keys carry a scope: read (all GET endpoints) or write (read plus
create/update/delete). See
authentication. The API is also
reachable via OAuth 2.1 for MCP clients.
Reference
- OpenAPI spec: https://watchfor.io/openapi.json
- Guides: https://watchfor.io/docs/api
MIT License.
Releasing
./publish.sh # build, check, confirm, upload
./publish.sh --build # build and check only
Debian and Ubuntu mark the system Python "externally managed" (PEP 668), so
pip install build twine is refused and python3 -m build reports No module
named build. The script keeps its own .venv-publish instead of touching the
system Python. Credentials are read from ~/.pypirc as usual.
Release files for watchfor 0.7.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| watchfor-0.7.1.tar.gz | 11.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| watchfor-0.7.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.8 kB
Release files / watchfor-0.7.1.tar.gz
| Download URL | watchfor-0.7.1.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
02ff0f9946ac5e2d6b52fe1d8a063119c27d0220716bdab0dfb8d2266e1f399f
|
|
BLAKE2b-256 checksum How to use checksums |
577251f6caa1a1e65fff34047395338e8e7bea83e8ed4d49aac6acbf7bc37817
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / watchfor-0.7.1-py3-none-any.whl
| Download URL | watchfor-0.7.1-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2113196caf05b4178ae32ce471d4c5f320f9e767f5971bf7c34862a7a7c9250a
|
|
BLAKE2b-256 checksum How to use checksums |
d66ee3f04570deb86cd4796b0c884606e4c93d0d1b0d95d6ce1e876417ef57b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|