Skip to main content

Documentation

Complete guide to setting up website monitoring with PingZen. API documentation, code examples, and best practices.

External Checkers & Multi-Location Monitoring

PingZen currently operates two probes of its own: Moscow (Yandex Cloud, ru-central1; default) and Novosibirsk (bare-metal datacenter). If you need coverage from a region we do not host yet — Turkey, Bulgaria, Netherlands, Iran, anywhere else — you can add your own external checker: a VM you provide (minimum 2 vCPU / 2 GB RAM) on which we deploy our lightweight Docker agent. It joins the dashboard as a new selectable check location.

How It Works

Every monitor is assigned to one or more probes — the central Moscow probe, your external probes, or any combination. Each assigned probe runs the check on its own schedule and reports the result back over an authenticated WebSocket. When you assign 2+ probes the monitor switches to multi-probe consensus mode (any_fails / majority_fail / all_fail) so you control how regional disagreements roll up to the headline status.

  1. You provide a VM and SSH access; we install the PingZen checker agent on it (single Docker container)
  2. The agent connects to pingzen.dev over WebSocket and registers itself with your workspace
  3. Each monitor you create is assigned to one or more probes — pick the locations when creating or editing the monitor
  4. Every assigned probe runs the check at the configured interval and streams the result back independently
  5. Per-probe results are aggregated into the monitor status using your chosen rule — alerts, incidents, and dashboard cards reflect the aggregate

Supported Protocols on External Checkers

PingZen supports 23 protocols in total, but external checkers currently run a subset of 13. The remaining protocols run only on the central Moscow probe.

Runs on external checkers

HTTPHTTPSTCPUDPICMPPingDNSSSLWHOISWSWSSSOCKS5MTProxy

Central probe only

SMTPIMAPPOP3FTPFTPSDNSBLPageSpeedAPI CheckTransactiongRPC

If your mix includes protocols from the right column, those monitors will keep running from Moscow — only the left-column monitors can be placed on your external checkers.

Checking the Same Endpoint from Multiple Locations

To monitor one endpoint from several locations at once, create one monitor per location, each assigned to a different probe. Each monitor is independent — it has its own uptime history, response-time chart, incidents, and alert rules. The example below assumes you have set up three self-hosted external checkers; replace the labels with your own locations.

Example: monitoring api.example.com from 3 locations

Create three monitors pointing at the same URL, each assigned to a different probe:

  • • api.example.com -> probe: Turkey (your checker)
  • • api.example.com -> probe: Bulgaria (your checker)
  • • api.example.com -> probe: Netherlands (your checker)

On the dashboard you see three cards — one per region. If Turkey goes down while Bulgaria and Netherlands stay UP, only the Turkey monitor fires an alert, and it is labelled with its probe location so you know exactly where the failure is.

What If One Location Fails and Others Work Fine?

That is exactly the scenario multi-location monitoring is designed to expose. Each monitor runs independently on its own probe, so a regional outage (bad ISP route, country-level censorship, localized CDN failure) is caught by the monitor in the affected region, while monitors in other regions keep reporting UP. The Turkey/Bulgaria/Netherlands example below assumes you have those locations as self-hosted external checkers — PingZen itself currently hosts only Moscow and Novosibirsk.

DOWN

Turkey

Probe in Turkey reports 3 consecutive failures. Monitor transitions to DOWN. Alert fires with "checked from: Turkey" label.

UP

Bulgaria

Probe in Bulgaria keeps reporting successful checks. Monitor stays UP. No alert fires.

UP

Netherlands

Probe in Netherlands also reports UP. Monitor stays UP. You can see the outage is Turkey-specific.

This pattern makes geo-specific outages obvious. You will see one red card (Turkey) next to two green cards (Bulgaria, Netherlands), and the alert tells you which region failed — perfect for diagnosing CDN routing issues, ISP blocks, or regional censorship.

Avoiding False Alerts: Confirmation Logic

Single network blips happen constantly. PingZen uses consecutive-check confirmation to filter them out — a single failed check never triggers an alert on its own.

DOWN confirmation

A monitor requires 3 consecutive failed checks before it is marked DOWN and fires an alert (configurable, range 1-10). A one-off timeout or packet loss gets absorbed silently.

UP recovery

A DOWN monitor requires 2 consecutive successful checks before it flips back to UP (configurable). This avoids flapping when a service is recovering unevenly.

Per-probe independence

Each monitor confirmation counter is tracked independently per its assigned probe. Failures in Turkey do not affect the Bulgaria monitor counter.

DEGRADED / WARNING

Soft states (slow response, partial success) update immediately without confirmation — they are informational and do not page you.

Probe Statuses

Each probe itself has a health status shown on the dashboard, based on heartbeats and event-loop metrics reported by the agent every 30 seconds.

StatusMeaning
PENDINGProbe is registered but has not yet connected. Normal during first-time setup.
ONLINEProbe is connected, heartbeats arriving on time, running checks normally.
DEGRADEDProbe is connected but showing signs of strain — high event-loop lag, elevated check error rate, or file-descriptor pressure. Checks still run but reliability is reduced.
OFFLINENo heartbeat received for 90 seconds. Monitors assigned to this probe are not running until it reconnects.

Probe Types

When you register a probe, you choose its type so the dashboard can display it correctly and other users know what kind of connectivity the checks represent.

Datacenter

Cloud VM (AWS, Yandex Cloud, Hetzner, DigitalOcean). Clean BGP routes, fast egress, stable IP. Best for baseline uptime monitoring.

Residential

VPS with residential ISP IP or similar. Represents what regular users experience — useful for detecting ISP-level blocking.

Home

Running on a home machine or NAS. Useful for checking how a service looks from a specific household/network.

Adding Your Own External Checker

An external checker is a probe deployed on your own VM. Minimum VM requirement: 2 vCPU / 2 GB RAM / 25 GB disk with Docker and outbound HTTPS access to pingzen.dev. We do not deploy on smaller VMs. The setup is concierge-style — you provide the VM, we deploy the agent. The container itself typically uses 150-400 MB RAM depending on monitor count and requires no inbound ports.

  1. Contact us via Telegram (@rassadaRB) with your location details (city, country, cloud provider), expected monitor count, and SSH access to the VM (user + key)
  2. We generate a probe API key (pzp_…) on our side
  3. We SSH into your VM and deploy the PingZen checker container (see reference command below — you do not need to run it yourself)
  4. Once the probe connects it appears ONLINE in your dashboard (usually within a minute)
  5. You assign monitors to the new probe — individually when creating/editing, or in bulk from the monitor list

Reference: the command we run on your VM

docker run -d --name pingzen-checker \
  --restart unless-stopped \
  --cap-add NET_RAW \
  -e PINGZEN_URL=https://pingzen.dev \
  -e PROBE_KEY=pzp_YOUR_KEY_HERE \
  -e PROBE_REGION="Istanbul, TR" \
  -e PROBE_COUNTRY_NAME="Turkey" \
  -e PROBE_PROVIDER="Hetzner" \
  -e PROBE_TYPE=datacenter \
  ilyakong/pingzen-checker:0.3.2

Shown for transparency so you know exactly what is being deployed on your VM. The agent needs CAP_NET_RAW for ICMP ping checks. No inbound firewall rules are required — all traffic is a single outbound WebSocket to pingzen.dev. Self-service probe registration via the dashboard UI is planned; for now the deployment is a manual, owner-driven process.

Capacity Reference (Estimated)

The numbers below are estimates derived from the scheduler configuration (max_concurrent = 100 concurrent checks, hard cap = 1200 monitors per probe), not from formal benchmarks. Real throughput depends on the VM size, network path, and the target services. Treat them as planning guidance and measure under your actual load:

ProtocolMonitors per probe @ 60s (estimate)Notes
ICMP / Pingup to ~1200Hard cap hit first. Uses subprocess ping (4 packets) — ~20 subprocess spawns/sec at the cap.
TCP portup to ~1200Hard cap hit first. Pure async open_connection — lightest protocol in practice.
HTTP / HTTPSup to ~1200Hard cap hit first. httpx with TLS, redirects, body match — heavier than TCP but still async.
SSL certificate~400-600Bottleneck is a dedicated 10-worker thread pool (ssl_checker.py:_MAX_WORKERS). Raising it requires a code change, not config.
DNSup to ~1200Hard cap hit first. Async resolution via dnspython.

At a 300-second interval these numbers roughly double in practical load but the hard 1200 cap still applies. To exceed 1200 monitors from one location, register multiple probes on separate VMs — they run completely independently. Your account plan has its own monitor limit (see Pricing) which is enforced on top of probe capacity.

Private External Checkers

Self-host a checker on your own machine to monitor private resources — intranet HTTP services, AWS VPC endpoints, RFC1918 hosts, services that block public probes. The probe connects outbound to PingZen via WebSocket — no inbound firewall rules required.

Requirements

  • Plan: PRO (3 probes), BUSINESS (10), or ENTERPRISE (50). Not available on FREE.
  • Linux or macOS host with Docker 20.10+ and docker compose
  • Outbound 443/TCP to pingzen.dev (no inbound ports open)
  • An API key from your account: avatar (bottom-left of the sidebar) → API Keys → New (the pz_… value)

Install

  1. Generate an API key: click your avatar (bottom-left of the sidebar) → API Keys → New API Key, then copy the pz_… value (shown once — save it now).
  2. Save the compose snippet below as compose.yml on the machine inside your private network.
  3. Replace PROBE_KEY with your pz_… value and PROBE_NAME with a label (e.g. “Office LAN”, “AWS-VPC-prod”).
  4. Run: docker compose up -d
  5. Verify it connected — see Verify section below.
services:
  pingzen-checker:
    image: ilyakong/pingzen-checker:0.3.2
    restart: unless-stopped
    cap_add: [NET_RAW]
    environment:
      PINGZEN_URL: https://pingzen.dev
      PROBE_KEY: pz_your_api_key_here
      PROBE_NAME: "Office LAN"
      PROBE_TYPE: home          # home | datacenter (optional)
      PROBE_REGION: "Office, RU" # optional

cap_add: [NET_RAW] is required for ICMP / Ping protocol checks. Drop it if you only monitor HTTP/HTTPS/TCP and prefer a tighter capability set.

Configuration

Environment variables understood by the checker image. PROBE_NAME and the optional metadata fields are visible only on YOUR dashboard — they are redacted from alerts delivered to external channels (Discord, Slack, webhook, email).

ENVRequiredDescription
PINGZEN_URLAlways https://pingzen.dev
PROBE_KEYYour pz_... API key. Scopes the probe to one workspace.
PROBE_NAMEDisplay label, 1–100 chars. Use anything you find useful (e.g. "Office LAN", "AWS-VPC-prod"). Visible only to your workspace; never leaks to external alert channels.
PROBE_TYPEhome | datacenter — controls the badge shown in the probe picker.
PROBE_REGIONFree-form geo label, e.g. "Helsinki, FI". Used only on your own dashboard.

Verify the probe is connected

After docker compose up -d, the probe should register within ~5 seconds.

  1. Run: docker compose logs pingzen-checker --tail 20 — look for “Probe registered: id=N name=<your label>”.
  2. Open pingzen.dev → Monitors → Create. Your private probe appears in the “Check from” dropdown with a Private badge.
  3. Pick a target URL on your private network (e.g. http://10.0.0.5/health), select your probe, click Test Connection — you should see UP within ~1 second.

Privacy & data flow

Check results travel from the probe to PingZen and are stored in our database. Per-check fields (URL, status, response_time, error_message) are visible to every member of your workspace. Alert payloads to external channels (Discord, Slack, webhook, email, MS Teams, Mattermost, PagerDuty) are redacted — your PROBE_NAME is replaced with the anonymous label “Private probe #N” before send. Prometheus metrics use a region label that for private probes is reduced to country code (or the literal “private”) so internal naming never reaches scrape clients.

Troubleshooting

Probe doesn’t appear in the picker after docker compose up -d.

First, check the container logs: docker compose logs pingzen-checker --tail 50. Common causes: (a) PROBE_KEY is invalid or revoked — generate a fresh one. (b) Outbound 443 to pingzen.dev is blocked — test from the same host: curl -v https://pingzen.dev/api/v1/health (must return JSON, not connection refused). © Plan limit hit — FREE has 0 private probes; PRO=3, BUSINESS=10, ENTERPRISE=50. The handshake error code 4001 with reason quota_exceeded confirms this.

Probe registers but checks always show DOWN with “connection refused”.

The probe is online but cannot reach the target URL from inside its own network. Verify from the probe host: docker compose exec pingzen-checker curl -v <your URL>. Common causes: target service is on a different LAN segment, firewall rule blocking probe → target traffic, or the URL uses a hostname the probe cannot resolve.

Probe disconnects every few minutes (“ws_disconnected” in logs).

Usually corporate proxy or NAT firewall idling the WebSocket. The checker uses keepalive pings every 30s; if your network drops idle TCP after <30s, the connection thrashes. Workarounds: shorten the network’s idle timeout, or run the probe on a host outside the proxied path.

I revoked the API key but the probe is still online.

WebSocket auth is checked at handshake only. Existing sessions stay alive until the next disconnect. To force-disconnect: docker compose down on the probe host (or wait for the next natural reconnect — the new handshake will be rejected).

I destroyed my old probe container and started a new one — the old offline row still shows up in the list.

If the new container runs with the same PROBE_NAME, the backend re-attaches the existing row (no duplicates). With a different PROBE_NAME a new row is created, and the old offline row is auto-deleted on the next register of any of your private probes — provided no monitor is still attached to it. If monitors are still attached (you intended to migrate but haven’t yet), the row is preserved on purpose: re-assign those monitors to the new probe in MonitorForm and the old row will vanish on the following register. With no action on your side, the daily reaper sweeps orphan offline rows within 24 hours.

Limitations

  • Corporate HTTPS_PROXY is not yet supported — outbound 443 must go directly to pingzen.dev.
  • PageSpeed protocol requires Lighthouse and is not bundled into the checker image.
  • Tested on Linux/amd64 and Linux/arm64; macOS via Docker Desktop also works. Windows containers are not supported.
  • Only HTTP-style targets are reachable from a private probe — DNSBL probes against IP reputation lists must use the public regional probes.

Frequently Asked Questions

Do you check from all probes at the same time for one monitor?

Yes. Multi-probe monitors run the same check from every assigned probe in parallel. The aggregation rule you pick when creating the monitor decides how per-probe states combine: any_fails (strictest — page on the first failed probe), majority_fail (filters single-region noise), or all_fail (most lenient — only page when every probe agrees). The dashboard card shows a per-probe dot row, and incidents carry an affected_probes timeline so you can see exactly which regions tripped and recovered. Per-plan caps: FREE=1, PRO=3, BUSINESS=10, ENTERPRISE=50 probes per monitor.

What happens to my monitors if my probe goes offline?

Monitors assigned to an offline probe stop running until the probe reconnects. Their status in the dashboard shows the last known result with a “probe offline” indicator. Other probes and the central Moscow probe are unaffected.

Can I use probes from countries that PingZen itself cannot reach (e.g. Iran, China)?

Yes — that is the main reason to self-host a probe. The probe connects outbound from inside that region, so you get authentic geo-visibility. You still need the probe VM itself to have outbound HTTPS access to pingzen.dev (some restrictive networks may block Cloudflare; test with curl https://pingzen.dev/api/v1/health from the VM first).

Is the probe traffic encrypted?

Yes — the agent connects to pingzen.dev over WSS (WebSocket over TLS). The probe API key authenticates the connection and is scoped to a single workspace.

Can multiple users share my probe?

A probe is scoped to one workspace. You can mark it public, in which case monitors from other workspaces can be assigned to it too — useful if you want to contribute probe capacity to the community in exchange for expanded plan limits. Contact us if you are interested.

Does this affect my account plan limits?

No. Your plan (Free, Pro, Business, Enterprise) dictates the maximum number of monitors your account can create — that limit is independent of how many external checkers you run. Self-hosting a checker adds regional check locations but does not automatically lift your monitor quota. If you want an expanded quota in exchange for contributing probe capacity, contact us.

What’s next

On the roadmap: (1) self-service probe registration directly from the dashboard so you don’t copy-paste the API key by hand, (2) corporate HTTPS_PROXY support so probes can run behind enterprise gateways, (3) Lighthouse-bundled image for PageSpeed monitoring from private locations. Have a specific use case? Reach out — we prioritize based on customer demand.

Common Questions

What protocols can I monitor?

PingZen supports 23 protocols: HTTP/HTTPS, WebSocket (WS/WSS), TCP, UDP, ICMP Ping, gRPC, DNS, WHOIS, SSL certificates, Email (SMTP/IMAP/POP3), FTP/FTPS, DNSBL, PageSpeed, SOCKS5, MTProxy, API Check, and Transaction. You can monitor websites, APIs, servers, databases, and any network service.

How fast can I get alerts?

Telegram alerts are delivered within 1-2 seconds of detection. Slack and Discord notifications arrive almost instantly. You can configure multiple alert channels for redundancy.

Can I organize monitors by project?

Yes! PingZen supports workspaces, which let you organize monitors by project, environment, or team. Each workspace can have its own alert configurations and team members.

Is there an API for automation?

Absolutely. PingZen provides a full REST API with OpenAPI documentation. You can create, update, and delete monitors programmatically.

How do status pages work?

Status pages are public, branded pages showing your services' uptime. You can display real-time status and allow customers to subscribe for updates.

What happens if I reach my monitor limit?

We'll notify you when approaching your limit. You can pause some monitors or contact us for increased capacity. We never stop monitoring without warning, ensuring your critical services stay protected.

Ready to stop missing downtime?

Join thousands of teams who trust PingZen. Setup takes 30 seconds.