Pult

Services without the agent

Not everything lives on your server. In the dashboard, under Services → Connections, you can give Pult a key to your hosting, database, App Store Connect, Cloudflare or GitHub Actions. Pult reads their state with your key and shows it next to your servers: in the Overview, in the app, in Telegram and on the project's status page.

Keys

We check a key as soon as you add it: if the service rejects it or the key lacks permissions, Pult tells you exactly what's missing and saves nothing. A saved key is encrypted (AES-256-GCM), and no one can show it again, not even us. Pult only reads: it sends read requests only, changes nothing and starts nothing. If the key is revoked later, you get a "no longer accepts the key" alert.

Where a service can issue read-only keys (Fly.io, Heroku, DigitalOcean, Hetzner Cloud, Cloudflare, GitHub), the instructions below say how to make one. Railway, Vercel, Netlify, Render, Supabase and Neon don't have such keys: their key gives full access, and Pult limits itself. If that's unacceptable to you, stay with outside checks.

How often: at your plan's interval (Free every 3 minutes, Indie every minute), but no more often than once a minute; Heroku every 2 minutes, App Store Connect every 5 minutes. A new deploy that is still building doesn't change the state: the old one still works. One stuck for more than 30 minutes counts as degraded. Data older than three intervals is shown grey, not green.

A hosting project, app or domain goes into the Pult project with the same name (Railway "plio" and the domain plio.app go into the project "Plio"), otherwise into a new project with that name. You can change this in Services, with the "Project in Pult" field next to each one.

Hosting and clouds

Railway

Key: railway.com → Account Settings → Tokens: an account or team token sees every project; or Project Settings → Tokens: one project and one environment.
Permissions: Railway doesn't issue read-only tokens; Pult only reads.

What you see: for each service in each environment, the latest deploy: deployed, building, deploy failed, crashed. A failed deploy or a crashed service is an alert. On a separate line, Railway's own status page. Temporary environments for pull requests are not shown. Connect →

Vercel

Key: vercel.com → Account Settings → Tokens → Create, Scope: the account or team with your projects. For a team, also the Team ID: Team Settings → General → Team ID.
Permissions: Vercel doesn't issue read-only tokens; Pult only reads.

What you see: the latest production deploy of each project (up to 50): deployed, failed (an alert) or building; cancelled ones are grey. On a separate line, Vercel's status page. Connect →

Netlify

Key: app.netlify.com → User settings → Applications → Personal access tokens → New access token.
Permissions: Netlify tokens can't be limited; Pult only reads.

What you see: the latest production deploy of each site (up to 50): published, failed (an alert) or building. On a separate line, Netlify's status page. Connect →

Render

Key: dashboard.render.com → Account Settings → API Keys → Create API Key.
Permissions: a Render key sees all of the owner's workspaces and can't be limited; Pult only reads.

What you see: each service (up to 50, without previews), grouped by Render project: the latest deploy is live, or the build, update or pre-deploy command failed (an alert). A service suspended by Render itself (billing, constant crashes) is an alert; one you suspended is grey. On a separate line, Render's status page. Connect →

Fly.io

Key: in a terminal, fly tokens create readonly -o <organization>; paste the whole line, including "FlyV1". The organization is the slug from fly orgs list; empty means personal.
Permissions: readonly: a read-only token.

What you see: each app in the organization (up to 50) and its machines: running, sleeping, stopped or crashed, and their health checks. A crashed machine is an alert; all machines stopped without autostart, or a failing health check, is degraded; machines Fly put to sleep for lack of requests are normal. On a separate line, Fly.io's status page. Connect →

Heroku

Key: in a terminal, heroku authorizations:create --scope read --description Pult, the Token line. The key from Account Settings → API Key works too, but it gives full access.
Permissions: --scope read: read-only.

What you see: each app (up to 30): processes running, sleeping or crashed, the latest release and maintenance mode. A crashed process or a failed release is an alert, maintenance mode is degraded, sleeping eco dynos are normal. We read every 2 minutes, since Heroku counts requests. On a separate line, the Heroku platform's status. Connect →

DigitalOcean

Key: cloud.digitalocean.com → Account → API → Tokens → Generate New Token.
Permissions: Scopes: Read Only (or custom: droplet:read, app:read, database:read).

What you see: droplets (running; off is an alert), App Platform apps (the latest deploy: live, failed is an alert, building) and managed databases (online or not). On a separate line, status.digitalocean.com. Connect →

Hetzner Cloud

Key: Hetzner Cloud Console → your project → Security → API Tokens → Generate API Token. One token, one project.
Permissions: Read.

What you see: each server in the project: running, off or stopping (an alert), starting. There is no line for Hetzner itself: status.hetzner.com has no state a machine can read, and we don't guess. Connect →

Databases

Supabase

Key: supabase.com/dashboard/account/tokens → Generate new token.
Permissions: Supabase doesn't issue read-only tokens; Pult only reads.

What you see: each project (up to 30): running, paused (degraded: it doesn't answer until restored) or starting, and whether the database, REST, Auth, Storage and Realtime answer. The database or REST not answering is an alert, another service is degraded. On a separate line, status.supabase.com. Connect →

Neon

Key: console.neon.tech → Account settings → API keys → Create new API key (or Organization settings → API keys for an organization key).
Permissions: Neon has no read-only keys; Pult only reads.

What you see: the compute of each branch (up to 30 projects): active or idle, both normal, since Neon suspends idle computes and wakes them on the first request; disabled is an alert; a failed latest operation is degraded. On a separate line, neonstatus.com. Connect →

Apps and domains

App Store Connect

Key: App Store Connect → Users and Access → Integrations → App Store Connect API → Team Keys → "+". You need three things: the Key ID, the Issuer ID (above the list of keys) and the contents of the .p8 file, which can be downloaded only once.
Permissions: the Developer role.

What you see: for each app, the latest version on each platform (in review, approved, ready for sale, rejected) and the latest build. An Apple rejection or an invalid build is an alert; the other steps (submitted, in review, approved) are events in the feed without a notification. We read every 5 minutes: App Store states change over hours. Connect →

Cloudflare

Key: dash.cloudflare.com → My Profile → API Tokens → Create Token → Create Custom Token, for the domains you need. The "Domain" field can be left empty: then Pult watches every zone the token sees.
Permissions: Zone → Zone → Read and Zone → Analytics → Read: read-only.

What you see: for each domain, the zone's state (active, not yet moved to Cloudflare, moved away) and the share of 5xx errors at Cloudflare's edge over the last 15 minutes: from 5% it's degraded, from 25% it's down (if there were more than 50 requests in that time). On a separate line, Cloudflare's own status page. Connect →

Email forwarding, if you also give the token Zone → Email Routing Rules → Read (and Account → Email Routing Addresses → Read, to see the addresses): for each domain with Email Routing, whether forwarding is on, how many rules there are and what happens to other mail, and whether the destination addresses are verified. Cloudflare saying "misconfigured" (the MX records were changed) is an alert; an unverified address or no rules at all is degraded. Without these permissions the line simply isn't there, with no error.

Builds

GitHub Actions

Key: github.com → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token; Repository access: the repositories you need. The "Repositories" field can be left empty: then Pult takes up to 30 repositories that were pushed to most recently.
Permissions: Repository permissions → Actions: Read-only (Metadata: Read-only is added automatically). A classic token with the repo scope works too, but it can also write.

What you see: the latest run of each workflow on the default branch: passed, failed (an alert) or running. On a separate line, the Actions component on githubstatus.com. We reread the list of repositories once an hour, and GitHub doesn't count unchanged runs against the rate limit; when the token has fewer than 500 requests per hour left, Pult waits. Connect →

Your domain's email

No key needed. In Services, or at the "Outside checks" step, enter a domain (the part after @), and every 5 minutes Pult will look at its email the way another mail server sees it. We never send a single message. On your plan, it counts as one outside check. Add →

  • MX: the domain has mail servers, and each has an address. No MX is a "mail isn't accepted" alert. Pult names the provider itself: Cloudflare Email Routing, Proton, Google Workspace, Microsoft 365, Zoho, Fastmail…
  • SMTP: the best of them answers on port 25 with a 220 greeting (Pult waits for the greeting and says goodbye without sending anything). None answering is an alert; only a backup answering is degraded. If port 25 is closed on Pult's side (it happens in clouds), the line says "not checked", not "down".
  • SPF and DMARC: one SPF record ending in ~all or -all, and a DMARC policy. No SPF or DMARC, or a DMARC that only monitors (p=none), is advice, not a failure: a yellow line in Services, without notifications and without turning the project yellow. +all (anyone may send as the domain) is an alert.
  • DKIM: if the provider has a known selector (Proton, Google, Microsoft 365, Fastmail), Pult checks the key is in place.
  • Domain registration: the expiry date from the registry (RDAP): 30 days before, a yellow line in the feed; 7 days before and after, an alert. Some country domains don't publish the date, and the line says so.
  • We check a failure once more through another DNS (1.1.1.1, then 8.8.8.8) before reporting it: one lost DNS query is not an alert.
  • On the project's public status page, there is one "Mail" line: whether it accepts mail or not (MX and SMTP). SPF, DMARC, domain expiry and server names are for you only.

What your product depends on

No key needed. In Services, mark the services your product relies on: GitHub, Supabase, OpenAI, SendGrid and more than 40 others: hosting and clouds, databases, payments, email, AI, development and team tools. Pult reads their public status pages every 3 minutes and tells you when the outage is theirs, not yours: "Supabase: degraded since 14:05". On your plan, all providers together count as one connection. Choose →

  • An outage or a major incident at a provider is an alert, just like a failure on your server, followed by a message when it's over.
  • Minor incidents and planned maintenance are just a line in the feed, without notifications.
  • For large providers, you can choose part of the service: an AWS or Google Cloud region, individual services. Until you choose, AWS, Google Cloud and Apple Developer show at most as "minor incident": an outage in one of dozens of regions or services usually doesn't affect you, and a daily alert would teach you not to read it.
  • A page that hasn't answered for more than 10 minutes is a grey "unknown" line, never green on old data.
  • Providers are not shown on your product's public status pages: if their outage really hit your product, your product's own checks will show it.