pingd docs

Subscribing

There are three ways to receive messages from a topic.

Concepts

A device is any client endpoint that can receive a push: a browser, an iOS app, an Android app (planned), or anything else that owns a push token. A subscription connects one device to one concrete topic.

Pattern subscriptions are not supported.

1. Push (browsers and iOS)

Register a device with a push token, subscribe it to topics, and pingd will deliver pushes through the appropriate channel. This is the only path that works when the receiver is offline / app is closed.

Register the device

POST/devices
Authorization: Bearer <token>

{
  "name": "Vi's iPhone",
  "platform": "ios",
  "pushType": "apns",
  "pushToken": "apns-token-here",
  "deliveryEnabled": true
}

Web Push devices use platform: "web" and pushType: "webpush" with the serialized PushSubscription as pushToken. See Web Push.

Subscribe to topics

POST/devices/:id/subscriptions
Authorization: Bearer <token>
X-Topic-Token: tk_...   # optional

{ "topicName": "alerts.cpu" }

One topic per call. Subscribe to alerts.cpu, alerts.disk, etc. separately. Include X-Topic-Token when read access comes from a share token.

Unsubscribe

DELETE/devices/:id/subscriptions/:topicName
Authorization: Bearer <token>

List subscriptions

GET/devices/:id/subscriptions
Authorization: Bearer <token>

GET/users/:username/subscriptions
Authorization: Bearer <token>

The user-scoped variant returns every subscription across the user's devices, with topic identity attached. The dashboard uses it to rebuild a logged-in user's topic list across refreshes.

2. Live SSE stream

For terminals, dashboards, and long-running scripts:

GET/topics/:name/stream

The response is text/event-stream. Each new message published to the topic is delivered as a single event. Read access uses the same rules as GET /topics/:name.

curl -N http://localhost:7685/topics/alerts/stream \
  -H "Authorization: Bearer $TOKEN"

The CLI wraps this with auto-reconnect:

pingd-cli messages watch --topic alerts
SSE is for live tailing. Reverse proxies need proxy_buffering off and a long read timeout. See Configuration.

3. Polling the message list

For batch jobs and HTTP-only environments:

GET/topics/:name/messages

Returns recent messages in reverse chronological order. Expired messages are filtered. For change-detection, sort by time and remember the last ID you saw.

Anonymous subscribers (guest sessions)

Anonymous device registration is not allowed. Apps that want push without forcing user signup should call POST /auth/guest first to get a guest bearer token, then register a device and subscribe with that token. Guests behave like anonymous callers for topic access: they can use public topics and share tokens, but they do not receive permission grants. See Users & tokens.

Delivery toggle

Devices have a deliveryEnabled flag. Set to false if a device should keep its subscriptions for membership tracking but should not actually receive pushes (useful for read-only mirrors). The default is true.

Logout-time deactivation

When a user logs out from a device, send the device's push token to deactivate it server-side:

DELETE/auth/logout
Authorization: Bearer <token>
X-Push-Token: <push token>

The device is only deactivated if the push token belongs to the current user. Omitting the header revokes the bearer token only.

Subscription access rules

Access sourceWho can subscribe
publicRead=trueAny authenticated user, including guests
Owner or adminAlways allowed
Share tokenAuthenticated caller with a valid ro or rw X-Topic-Token
PermissionNon-guest user with matching ro or rw permission
wo, deny, expired grant, or no read sourceDenied