A push notification is a message delivered to a device or browser by an application or website, usually without the recipient actively opening it first. It might announce a new account event, remind someone about an unfinished task, report a delivery update or surface a time-sensitive conversation.

The visible alert is only the final part of a larger system. Reliable push delivery depends on permission, device registration, provider tokens, targeting, a server-side send, platform delivery services and client-side handling. Understanding those stages helps teams design useful notifications and diagnose failures without treating push as a guaranteed real-time transport.

The basic push notification flow

A typical notification follows this sequence:

  • A person installs an app, opens a website or signs in.
  • The client asks for notification permission when it is appropriate.
  • The platform issues a registration token or an equivalent identifier.
  • The client sends that registration information to the application backend.
  • The backend associates the device or browser with a user, tag or other audience data.
  • A product event causes the backend to create a notification.
  • A push service accepts the message and routes it towards the relevant platform endpoint.
  • The device or browser receives the message and the client decides how to display or process it.
  • The application records the result where delivery, invalid tokens or user preferences need to be acted on.

The exact services differ between iOS, Android and Web Push, but the architectural separation is consistent: the client registers a destination, while a trusted server decides what should be sent and when.

What makes up a push notification?

A notification normally has two parts: visible content and delivery metadata.

The visible content includes a title and body. It may also contain a sound, badge, icon, image or action, depending on the platform and the client implementation. A data payload can carry values that help the application open a particular screen or update local state. Data should be treated as input to application logic, not as a place for secrets.

Delivery metadata identifies the destination and controls how the message should be handled. A destination may be one device, a user with several devices, a tag-based audience, a defined segment or all enabled devices. Expiry, priority, collapse behaviour and platform-specific options can also matter, although support and semantics vary by provider and operating system.

A push message is not the same as an in-app message. An in-app message appears while someone is using the application and can be rendered under the product's direct control. A push notification must pass through operating-system or browser rules and can be blocked, delayed, grouped or suppressed.

Permissions, registration and tokens

Permission is a product decision as much as a technical one. Applications should explain the value of notifications before requesting access, then ask at a sensible point in the user's journey. Requesting permission immediately, without context, can produce a poor experience and leaves the product dependent on a decision that may not be easy to reverse.

After permission is granted, the client registers with the relevant platform. That process produces a token or endpoint identifier used to address the installation. The token identifies a delivery destination, not necessarily a permanent device or a person. It can change after an app reinstall, an operating-system event, a security change, a browser change or a change of provider environment.

The client should report the current token to the backend whenever the platform indicates that it has changed. The backend should also associate and disassociate destinations carefully when users sign in, sign out or share a device. A user may have several active destinations, while a single destination may be associated with different users over time.

Client SDKs can reduce the amount of platform-specific code required for device registration, identity, token lifecycle, payload handling and lifecycle events across iOS, Android and Web Push. They do not remove the need to define permission timing, identity rules, preferences and failure handling.

How the server sends a notification

The server should be the source of truth for business events and should keep credentials away from client applications. For a HoneyNotify server-side send, the application makes a POST request to /v1/notifications using a Bearer API key and an Idempotency-Key. A notification requires a title, body and target.

The target determines who should receive the message. It can address a device, user, tag, segment or all enabled devices. Target choice should match the event's meaning. An account-security alert may belong to one user; a release announcement may belong to a segment; a carefully controlled service notice might target all enabled devices.

An idempotency key is important when a request may be retried. Networks can fail after a server has accepted a request but before the caller receives its response. Retrying without an idempotency strategy can create duplicate notifications. Generate a stable key for the same logical send and ensure that different business events do not accidentally reuse it.

The sending service should validate required fields, apply user preferences, record an internal event identifier and handle responses deliberately. Queueing can separate a product transaction from notification delivery, but it introduces another system whose retries, ordering and monitoring must be designed.

Delivery is not the same as display

A successful server response generally means that a provider accepted the request for processing. It does not prove that a person saw the alert. The device may be offline, the token may be invalid, permission may have been revoked, the operating system may defer background work, or the notification may be replaced by newer content.

Treat push as an eventually delivered signalling mechanism rather than a guaranteed command channel. If an action is important, store it on the server and let the application fetch the current state when it opens. A notification should prompt or inform; it should not be the only record of a payment, security change or workflow decision.

Plan separately for foreground and background handling. In the foreground, an application may choose to show an in-app surface instead of a system alert. In the background, the operating system controls more of the presentation and execution rules. Test both paths on real devices and supported browsers, including locked screens, revoked permission, poor connectivity and battery-saving modes.

Implementation considerations

Before building a notification feature, define the following:

  • What user or system event creates the notification?
  • Who is eligible, and how is that eligibility calculated?
  • Which channels and notification categories can the recipient control?
  • What happens if the same event is retried?
  • What does the application do when the recipient taps the notification?
  • How can a person disable, reduce or customise the notifications?
  • Which data is safe to include in the payload?
  • How will invalid tokens, provider errors and delayed delivery be observed?

Use stable application identities rather than treating a token as a user identity. Store token updates with timestamps and platform or environment information where relevant. Keep a clear distinction between an enabled destination, permission status and a person who is eligible for a message.

Make payloads small and purposeful. Include enough information to route the recipient to the relevant experience, but fetch sensitive or changing details from the authenticated application. Avoid putting credentials, private content or irreversible instructions in a notification payload.

Common mistakes

Sending from the client

Embedding a server API key in an app or browser exposes it to anyone who can inspect the client. Keep send credentials on a trusted server and let clients register destinations through an authenticated flow.

Assuming tokens never change

A token that worked yesterday may no longer identify the current installation. Implement token lifecycle handling and remove or disable destinations when the provider reports them as invalid.

Confusing a device with a person

One person can use several devices, and one shared device can have several accounts. Model those relationships explicitly and test sign-in, sign-out and account switching.

Ignoring duplicate sends

Retries, queue redelivery and repeated event processing can all generate duplicates. Use idempotency for server-side requests and an event-level deduplication strategy where the business process requires it.

Treating delivery as proof of engagement

A delivered notification may not be read, and an opened notification may not mean the intended action was completed. Measure and model delivery, opening and subsequent product activity as separate events.

Relying on provider identifiers without checking compatibility

When migrating from another provider, imported OneSignal subscription IDs can remain as device IDs when matching provider tokens later register. However, token rotation or another provider environment can prevent matching. Plan a reconciliation process, retain useful migration metadata and verify the current provider's behaviour before assuming that every imported destination will reconnect automatically.

A practical testing checklist

Test the complete lifecycle rather than only a successful send:

  • Fresh installation and first permission request
  • Permission denied, later changed and permanently restricted states
  • Token creation, token rotation and app reinstall
  • Sign-in, sign-out and switching between accounts
  • Multiple devices attached to one user
  • Foreground, background and terminated application states
  • Offline devices and delayed reconnection
  • Invalid targets and provider rejection responses
  • Retries with the same idempotency key
  • Duplicate business events and queue redelivery
  • Deep links or actions from the notification
  • Notification preferences and unsubscribe behaviour

Log correlation identifiers, target type, request outcome and failure category without recording unnecessary personal data. This gives the support and engineering teams enough information to investigate delivery problems while respecting privacy.

Conclusion

A push notification is the result of a coordinated flow, not simply a message sent to a phone. Permission, registration, changing tokens, identity, targeting, secure server-side requests and client handling all affect the outcome. Build for retries and token changes, make preferences explicit, keep sensitive state on the server and test the full lifecycle. With those foundations in place, push notifications can be a useful extension of a product rather than a fragile source of duplicate or unexplained alerts.