Get started

Zero to paged in minutes.

Pingtower is two halves: a server that turns your log stream into alerts, and an iOS app that gets those alerts to a human — through Silent mode when it has to. The hosted service runs the server half for you — sign up and start ingesting. Want the data plane on your own hardware instead? Download a signed release and self-host.

Start hosted — the recommended path

The hosted service is the fastest way to get paged: no server to run, no upgrades to schedule, and the push pipeline to your phone is ours end to end.

Signups are open, and the service is free while Pingtower is in pre-release (the terms spell out how pricing would arrive). The iOS app isn't on the App Store yet — until it ships, alerts deliver via webhook, Slack, and Telegram, and you drive everything through the API:

curl -s https://api.pingtower.com/v1/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"[email protected]","password":"…"}'
# → {"account":{…},"token":"pts_…"}

curl -s https://api.pingtower.com/v1/tenants \
  -H "Authorization: Bearer pts_…" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Acme"}'
# → {"id":"<tid>","name":"Acme","role":"owner"}

curl -s -X POST https://api.pingtower.com/v1/tenants/<tid>/keys \
  -H "Authorization: Bearer pts_…"
# → {"id":"…","token":"ptk_…"}   # shown once — store it

From there create a project, a source (its pti_ ingest token is what your apps POST with), and a rule — the API reference covers the whole data plane, and the agent guide is written so an AI agent can run the entire setup for you.

Self-host the server

Prefer your alert data on your own box? The server is a single static Go binary — no runtime, no dependencies — and does the whole inbound half locally. Every release is signed with minisign; the table lists the SHA-256 of each binary and of its detached signature.

ArtifactVersionSizeSHA-256
pingtower-linux-amd64ship/2026-W35.9-16-g25fe58e22.6 MBc707aad3d8b0f59e38ba77b1d1e27a9113e77a60b840c6e7396eef56fd406b6c
pingtower-linux-amd64.minisig8cc2be220894dac6ad42554ae8879c63f4d97d08c19a5bd110e1b83b5eb963d5
pingtower-linux-arm64ship/2026-W35.9-16-g25fe58e21.4 MBc6835cf75591de4953823d4ecf97ba0d8f380a38edc96322fce1f8558328b7fb
pingtower-linux-arm64.minisigff3c072789160b73ab735715439a1021b9a15a27b84e37897b56e3ef28d0f072

Verify the download

Check the SHA-256 against the table above, then verify the signature against the Pingtower release public key (pingtower-release.pub):

sha256sum pingtower-linux-amd64   # compare with the table above

minisign -Vm pingtower-linux-amd64 -P RWSgpqQYjQaS4gwdiflj0DUcnY3m1IGdmRoofuHq0OSO44cXI7X3rpjt

The trusted comment printed on success names the artifact, version, and git commit the signature was made for. If either check fails, do not run the binary.

Set it up on a Linux server

The daemon speaks plain HTTP on localhost and expects a reverse proxy (Caddy, nginx) to terminate TLS in front of it. Data lives in one directory of SQLite files.

Install the binary

sudo install -m 0755 pingtower-linux-amd64 /usr/local/bin/pingtower
sudo useradd --system --home /var/lib/pingtower --shell /usr/sbin/nologin pingtower
sudo mkdir -p /var/lib/pingtower
sudo chown pingtower:pingtower /var/lib/pingtower

Create a systemd unit

/etc/systemd/system/pingtower.service:

[Unit]
Description=pingtower
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pingtower
Group=pingtower
ExecStart=/usr/local/bin/pingtower \
  -listen 127.0.0.1:8391 \
  -data-dir /var/lib/pingtower
Restart=on-failure
RestartSec=2
TimeoutStopSec=20
LimitNOFILE=65536
UMask=0077
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=/var/lib/pingtower
ProtectHome=yes
PrivateTmp=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now pingtower
curl -s http://127.0.0.1:8391/healthz

Put TLS in front

With Caddy, one line gets you a certificate and the proxy (/etc/caddy/Caddyfile):

alerts.example.com {
    reverse_proxy 127.0.0.1:8391
}

First account, first tenant

curl -s https://alerts.example.com/v1/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"[email protected]","password":"…"}'

curl -s https://alerts.example.com/v1/tenants \
  -H "Authorization: Bearer pts_…" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Acme"}'

From there, create a source to get an ingest token and start POSTing logs — the API reference covers the whole data plane. Useful flags: -retain-days, -max-logs-per-source, -backup-dir, and -secret-key to seal integration credentials at rest (pingtower -h lists them all).

Ring a phone

A self-hosted server does the whole inbound half — ingest, dedup, rules, escalation, plus webhook, Slack, and Telegram delivery — on your box. Paging a phone through the iOS app additionally needs a pingtower.com account paired to your server (pingtower pair --email [email protected] on the box prints a one-shot code to redeem in the app), because Apple push for the App Store app can only be sent by us. The how it works section and the terms spell out that boundary.