pingd docs

FAQ

Why did you build this?

Because I can! It started as a fun side project, so I decided to build a notification relay from scratch and play with push protocols, NATS-style permissions, templating, retry queues, all of it.

After running it for a while it's matured into something I actually rely on, and somewhere along the way it picked up a bit of personality.

Okay but why would I use it?

A few things pingd does well:

Is it really free?

Yes. No paid tier hiding the good parts. If you self-host, your only cost is the box you run it on.

Is there a hosted version?

Yes! pingd.dev (COMMING SOON!), if you just want to try it or don't feel like running your own. But pingd is meant to be self-hosted. That's the default story!

Why not just use Slack / Discord / PagerDuty?

Use them if they work for you. pingd is for when you want self-hosting, one boring relay between many publishers and many devices, and access control beyond a shared channel webhook. If "post to a Slack channel" already solves your problem, keep doing that.

Can I use Postgres instead of SQLite?

Not yet, maybe later for heavier deployments. For most self-hosted use cases, a single SQLite file with regular backups is enough.

Can I publish without authenticating?

There are three ways to publish, in order of openness:

See Permissions for the full ACL rules.

Can I subscribe without an account?

Anonymous clients can't subscribe for push, but they can watch a topic over SSE using a share token. To actually receive push, you need a guest or authenticated account. Guest accounts work without signup. See Subscribing.

How do I rotate the admin password?

Three ways:

The ADMIN_PASSWORD env var only seeds the very first user on a fresh database. Changing it later does nothing.

Why isn't my iOS device getting pushes?

Common causes:

Check GET /messages/:id/deliveries after publishing. Each delivery row has status, retryCount, and timestamps.

Can I subscribe to wildcards?

No. Subscriptions are concrete (alerts.disk, not alerts.*). Wildcards exist at the permission layer only. They grant access to a pattern, but you still subscribe to each topic by name.

What happens when I delete a topic?

It's a hard delete and it cascades. Gone with the topic:

Permission grants are pattern-based, not topic-id references, so a grant like rw on alerts.* survives the deletion of alerts.disk. If you re-create a topic with the same name, those grants apply again immediately.

How do I back up everything?

Back up $PINGD_DATA_DIR. It contains the SQLite database and the CLI token config. The simple option is to stop pingd, copy the data directory, then start it again. For online backups, use SQLite's .backup command against the database file.

Can I contribute?

Yes please! The repo is on GitHub. Bug reports, feature ideas, and PRs are all welcome.

For anything beyond a small fix, opening an issue first helps so we can talk through the shape before you spend time on it. Build and test commands are in the README.

One small note: the codebase is hand-written and that's part of why working on it is fun. AI-assisted PRs are absolutely welcome, just mention it in the description so reviewers have the context.