---
title: "Send the current subscription to the · Agent Wranglers"
url: https://agentwranglers.se/playbook/notifications/push-notifications/refresh-push-subscriptions
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Send the current subscription to the server on every start

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Push notifications](https://agentwranglers.se/playbook/notifications/push-notifications.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- Level: Recommended
- Chapter: [Push notifications](https://agentwranglers.se/playbook/notifications/push-notifications)
- Rule: Read the push subscription or device token each time the app starts, and send it to the server when it changed. Never trust a copy cached on the device.
- How: The Push API fires `pushsubscriptionchange` when a subscription changes outside the app's control. Not every browser fires it, so also call `getSubscription()` on each start and compare the endpoint. Apple says to register for a device token at every launch and never cache it, because restores and reinstalls issue a new one. Firebase asks you to store a timestamp with each registration and update it on every upload. Save with an upsert keyed by endpoint or token, as [Make writes safe to repeat](https://agentwranglers.se/playbook/data/transactions-and-concurrency/idempotent-writes) says.
- Check: Unsubscribe the test browser's subscription by hand and reload the app. Within one start, the server holds the new endpoint and no row for the old one. Restore a test phone from a backup, and the server gets its new token at first launch.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Service worker
self.addEventListener('pushsubscriptionchange', event => {
  event.waitUntil((async () => {
    const fresh = event.newSubscription ?? await self.registration.pushManager.subscribe(
      { userVisibleOnly: true, applicationServerKey: VAPID_PUBLIC_KEY });
    await fetch('/push/subscriptions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ subscription: fresh, replaces: event.oldSubscription?.endpoint }),
    });
  })());
});
```

### Plain text example

```swift
func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02x", $0) }.joined()
    Task { try await api.post("/push/tokens", body: ["token": token]) } // called on every launch, no local cache
}
```

## Sources

- [W3C Push API, the pushsubscriptionchange event](https://www.w3.org/TR/push-api/#the-pushsubscriptionchange-event)
- [Apple, Registering your app with APNs](https://developer.apple.com/documentation/usernotifications/registering-your-app-with-apns)
- [Firebase, Manage FCM registrations](https://firebase.google.com/docs/cloud-messaging/manage-tokens)

## Related rules

- [Make writes safe to repeat](https://agentwranglers.se/playbook/data/transactions-and-concurrency/idempotent-writes) in Data

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/notifications/push-notifications/refresh-push-subscriptions">Agent Wranglers notifications playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Send personal messages only to the person's devices](https://agentwranglers.se/playbook/notifications/push-notifications/personal-push-to-devices)
- [Push notifications](https://agentwranglers.se/playbook/notifications/push-notifications)
