The Push API enables sending of a push message to a webapp via a push service. An application server can send a push message at any time, even when a webapp or user agent is inactive. The push service ensures reliable and efficient delivery to the user agent. Push messages are delivered to a Service Worker that runs in the origin of the webapp, which can use the information in the message to update local state or display a notification to the user.
This specification is designed for use with the web push protocol, which describes how an application server or user agent interacts with a push service.
The Push API allows a webapp to communicate with a user agent asynchronously. This allows an application server to provide the user agent with time-sensitive information whenever that information becomes known, rather than waiting for a user to open the webapp.
As defined here, push services support delivery of push messages at any time.
In particular, a push message will be delivered to the webapp even if that webapp is not currently active in a browser window: this relates to use cases in which the user may close the webapp, but still benefits from the webapp being able to be restarted when a push message is received. For example, a push message might be used to inform the user of an incoming WebRTC call.
A push message can also be sent when the user agent is temporarily offline. In support of this, the push service stores messages for the user agent until the user agent becomes available. This supports use cases where a webapp learns of changes that occur while a user is offline and ensures that the user agent can be provided with relevant information in a timely fashion. Push messages are stored by the push service until the user agent becomes reachable and the message can be delivered.
The Push API will also ensure reliable delivery of push messages while a user agent is actively using a webapp, for instance if a user is actively using the webapp or the webapp is in active communication with an application server through an active worker, frame, or background window. This is not the primary use case for the Push API. A webapp might choose to use the Push API for infrequent messages to avoid having to maintain constant communications with the application server.
Push messaging is best suited to occasions where there is not already an active communications channel established between user agent and webapp. Sending push messages requires considerably more resources when compared with more direct methods of communication such as fetch() or websockets. Push messages usually have higher latency than direct communications and they can also be subject to restrictions on use. Most push services limit the size and quantity of push messages that can be sent.
This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.
Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]].
The terms current settings object, event handler, event handler event type, fire a simple event, queue a task and trusted event are defined in [[!HTML51]].
        Promise, and
        JSON.parse are
        defined in [[!ECMASCRIPT]].
      
        EventInit,
        DOMException,
        AbortError,
        InvalidStateError,
        InvalidAccessError,
        SecurityError,
        NetworkError,
        event listener,
        and steps for
        constructing events are defined in [[!DOM]].
      
        The terms service
        worker, service worker
        registration, installing
        worker, waiting worker,
        and active
        worker, and the types ServiceWorkerRegistration,
        ServiceWorkerGlobalScope,
        ExtendableEvent,
        ExtendableEventInit,
        extend
        lifetime promises, the Clear
        Registration algorithm, and the Handle
        Functional Event algorithm are defined in [[!SERVICE-WORKERS]].
      
The term secure context is defined in [[!POWERFUL-FEATURES]].
The algorithms utf-8 encode, and utf-8 decode are defined in [[!ENCODING]].
        Blob is defined in
        [[!FILEAPI]].
      
        Any,
        ArrayBuffer,
        BufferSource,
        NotAllowedError,
        and USVString are defined
        in [[!WEBIDL]].
      
The web push protocol [[!WEBPUSH-PROTOCOL]] describes a protocol that enables communication between a user agent or application server and a push service. Alternative protocols could be used in place of this protocol, but this specification assumes the use of this protocol; alternative protocols are expected to provide compatible semantics.
The term webapp refers to a Web application, i.e. an application implemented using Web technologies, and executing within the context of a Web user agent, e.g. a Web browser or other Web runtime environment.
The term application server refers to server-side components of a webapp.
A push message is data sent to a webapp from an application server.
A push message is delivered to the active worker associated with the push subscription to which the message was submitted. If the service worker is not currently running, the worker is started to enable delivery.
A push subscription is a message delivery context established between the user agent and the push service on behalf of a webapp. Each push subscription is associated with a service worker registration and a service worker registration has at most one push subscription.
A push subscription has internal slots for a P-256 ECDH key pair and an authentication secret in accordance with [[!WEBPUSH-ENCRYPTION]]. These slots MUST be populated when creating the push subscription, and MUST remain constant for its lifetime.
When a push subscription is deactivated, both the user agent and the push service MUST delete any stored copies of its details. Subsequent push messages for this push subscription MUST NOT be delivered.
A push subscription is deactivated when its associated service worker registration is unregistered, though a push subscription MAY be deactivated earlier. A push subscription is removed when the clear registration algorithm is run for the service worker registration.
A push subscription has an associated push endpoint. It MUST be the absolute URL exposed by the push service where the application server can send push messages to. A push endpoint MUST uniquely identify the push subscription.
The term push service refers to a system that allows application servers to send push messages to a webapp. A push service serves the push endpoint or endpoints for the push subscriptions it serves.
The term express permission refers to an act by the user, e.g. via user interface or host device platform features, via which the user approves the use of the Push API by the webapp.
        User agents MUST NOT provide Push API access to webapps without the
        express permission of the user. User agents MUST acquire consent for
        permission through a user interface for each call to the subscribe() method,
        unless a previous permission grant has been persisted, or a prearranged trust relationship
        applies. Permissions that are preserved beyond the current browsing session MUST be
        revocable.
      
        The user agent MAY consider the PushSubscriptionOptions when
        acquiring permission or determining the permission status.
      
When a permission is revoked, all push subscriptions created with that permission MUST be deactivated.
When a service worker registration is unregistered, any associated push subscription MUST be deactivated.
The push endpoint of a deactivated push subscription MUST NOT be reused for a new push subscription. This prevents the creation of a persistent identifier that the user cannot remove. This also prevents reuse of the details of one push subscription to send push messages to another push subscription.
User agents MUST implement the Push API to only be available in secure contexts. This provides better protection for the user against man-in-the-middle attacks intended to obtain push subscription data. Browsers may ignore this rule for development purposes only.
A push message is sent from an application server to a webapp as follows:
This overall framework allows application servers to activate a Service Worker in response to events at the application server. Information about those events can be included in the push message, which allows the webapp to react appropriately to those events, potentially without needing to initiate network requests.
The following code and diagram illustrate a hypothetical use of the push API.
// https://example.com/serviceworker.js
this.onpush = function(event) {
  console.log(event.data);
  // From here we can write the data to IndexedDB, send it to any open
  // windows, display a notification, etc.
}
// https://example.com/webapp.js
navigator.serviceWorker.register('serviceworker.js').then(
  function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe().then(
      function(pushSubscription) {
        console.log(pushSubscription.endpoint);
        console.log(pushSubscription.getKey('p256dh'));
        console.log(pushSubscription.getKey('auth'));
        // The push subscription details needed by the application
        // server are now available, and can be sent to it using,
        // for example, an XMLHttpRequest.
      }, function(error) {
        // During development it often helps to log errors to the
        // console. In a production environment it might make sense to
        // also report information about errors back to the
        // application server.
        console.log(error);
      }
    );
  });
       
          
          The fields included in the PushSubscription is all the information needed
          for an application server to send a push message. Push services that are
          compatible with the Push API provide a push endpoint that conforms to the web
          push protocol. These parameters and attributes include:
        
push endpoint of a 
            PushSubscription is a URL that allows an application server to request
            delivery of a push message to a webapp.
          getKey method on a
          PushSubscription is used to retrieve keying material used to encrypt and
          authenticate push messages. Each invocation of the function returns a new
          ArrayBuffer that contains the value of the corresponding key, or
          null if the identified key doesn't exist. Passing a value of
          p256dh retrieves a elliptic curve Diffie-Hellman
          (ECDH) public key associated with the push subscription. Passing a value of
          auth returns an authentication secret that an application server uses in
          authentication of its messages. These keys are used by the application server to
          encrypt and authenticate messages for the push subscription, as described in
          [[!WEBPUSH-ENCRYPTION]].
          
        The Service Worker specification defines a ServiceWorkerRegistration interface
        [[!SERVICE-WORKERS]], which this specification extends.
      
partial interface ServiceWorkerRegistration {
    readonly attribute PushManager pushManager;
};
      
        The pushManager
        attribute exposes a PushManager, which has an associated service
        worker registration represented by the ServiceWorkerRegistration on
        which the attribute is exposed.
      
The PushManager interface defines the operations to access push services.
interface PushManager {
    Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options);
    Promise<PushSubscription?> getSubscription();
    Promise<PushPermissionState> permissionState(optional PushSubscriptionOptionsInit options);
};
      
        The subscribe
        method when invoked MUST run the following steps:
      
Promise.
        DOMException whose name is
        "SecurityError" and terminate these steps.
        options argument, if
        provided, or a PushSubscriptionOptions dictionary with default values.
        applicationServerKey attribute, check that the value is valid (i.e.,
        ensure that it describes a valid point on the P-256 curve). If the
        applicationServerKey value is invalid, reject promise with
        an InvalidAccessError and terminate these steps.
        PushManager's associated
        service worker registration.
        DOMException whose
            name is "InvalidStateError" and terminate these steps.
            DOMException whose name is
            "InvalidStateError" and terminate these steps.
            DOMException whose
        name is "NotAllowedError" and terminate these steps.
        DOMException whose name is "AbortError" and
            terminate these steps.
            options attribute of
            subscription. If any attribute on allOptions contains a different
            value to that stored for subscription, then reject promise with
            an InvalidStateError and terminate these steps. The contents of
            BufferSource values are compared for equality rather than
              references.
            DOMException
        whose name is "AbortError" and terminate these steps.
        options attribute of subscription to be a copy of 
          allOptions.
        getKey method of the PushSubscription with an argument of
        p256dh.
        getKey
        method of the PushSubscription with an argument of
        auth.
        PushSubscription providing the details of the new push
        subscription.
        
        The getSubscription
        method when invoked MUST run the following steps:
      
Promise.
        DOMException
        whose name is "AbortError" and terminate these steps.
        PushSubscription providing the details of the retrieved push
        subscription.
        
        The 
        permissionState method when invoked MUST run the following steps:
      
Promise.
        PushPermissionState) of the
        requesting webapp.
        PushPermissionState providing the push permission status.
        Permission to use the push service can be persistent, that is, it does not need to be reconfirmed for subsequent subscriptions if a valid permission exists.
        If there is a need to ask for permission, it needs to be done by invoking the
        subscribe method.
      
A PushSubscriptionOptionsInit represents additional options associated with a push subscription. The user agent MAY consider these options when requesting express permission from the user. When an option is considered, the user agent SHOULD enforce it on incoming push messages.
These options are optional, and user agents MAY choose to support only a subset of them. A user agent MUST NOT expose options that it does not support.
Once set, options for a push subscription cannot change. A pre-existing push subscription can be unsubscribed to create a push subscription with new options.
dictionary PushSubscriptionOptionsInit {
    boolean userVisibleOnly = false;
    BufferSource? applicationServerKey = null;
};
interface PushSubscriptionOptions {
    readonly attribute boolean userVisibleOnly;
    [SameObject] readonly attribute ArrayBuffer? applicationServerKey;
};
        
          The userVisibleOnly option,
          when set to true, indicates that the push subscription will only be
          used for push messages whose effect is made visible to the user, for example by
          displaying a Web Notification. [[NOTIFICATIONS]]
        
          The applicationServerKey
          option includes an elliptic curve public key for an application server. This is the key
          that the application server will use to authenticate itself when sending push messages to
          this subscription as defined in [[!WEBPUSH-VAPID]]; the push service will reject any push
          message unless the corresponding private key is used to generate an authentication token.
        
          If present, the value of applicationServerKey MUST include a point on
          the P-256 elliptic curve [[!DSS]], encoded in the uncompressed form described in
          [[!X9.62]] Annex A (that is, 65 octets, starting with an 0x04 octet). The
          applicationServerKey MUST be a different value to the one used for
          message encryption [[WEBPUSH-ENCRYPTION]].
        
A PushSubscription object represents a push subscription.
interface PushSubscription {
    readonly attribute USVString endpoint;
    [SameObject] readonly attribute PushSubscriptionOptions options;
    ArrayBuffer? getKey(PushEncryptionKeyName name);
    Promise<boolean> unsubscribe();
    serializer;
};
      
        When getting the endpoint
        attribute, the user agent MUST return the push endpoint associated with the
        push subscription.
      
        The getKey method retrieves keying material that
        can be used for encrypting and authenticating messages. When getKey is
        invoked the following process is followed:
      
name
        argument.
        null.
        ArrayBuffer
        instance.
        p256dh public key is encoded
        using the uncompressed format defined in [[X9.62]] Annex A (that is, a 65 octet sequence
        that starts with a 0x04 octet).
        auth parameter contains an octet sequence used by the user agent to
        authenticate messages sent by an application server.
        
        Keys named p256dh and auth MUST be supported, and
        their values MUST correspond to those necessary for the user agent to decrypt received push
        messages in accordance with [[!WEBPUSH-ENCRYPTION]].
      
        The unsubscribe method when
        invoked MUST run the following steps:
      
Promise.
        false and terminate these steps.
        NetworkError" exception and terminate these steps.
        true.
        
        The serializer for a PushSubscription invokes the following steps:
      
endpoint and whose value
        is the result of converting the endpoint attribute of the
        PushSubscription to a serialized value. The user agent MUST use
        a serialization method that does not contain input-dependent branchs (that is, one that is
        constant time). Note that a URL - as ASCII text - will not ordinarily require special
        treatment.
        PushSubscription, ordered by the name of the key:
          getKey).
            getKey.
            USVString. The user agent MUST use a
            serialization method that does not branch based on the value of b.
            keys and whose value is
        keys.
        
        Note that the options to a PushSubscription are not serialized.
      
          Encryption keys used for push message encryption are provided to a webapp
          through the getKey method or the serializer of
          PushSubscription. Each key is named using a value from the
          PushEncryptionKeyName enumeration.
        
enum PushEncryptionKeyName {
    "p256dh",
    "auth"
};
        
        
          The p256dh value is
          used to retrieve the P-256 ECDH Diffie-Hellman public key described in
          [[!WEBPUSH-ENCRYPTION]].
        
          The auth value is used to
          retrieve the authentication secret described in [[!WEBPUSH-ENCRYPTION]].
        
typedef any JSON;
[Exposed=ServiceWorker]
interface PushMessageData {
    ArrayBuffer arrayBuffer();
    Blob blob();
    JSON json();
    USVString text();
};
      
        PushMessageData objects have an associated bytes (a byte sequence) set on
        creation, which is null if there was no data in the push message.
      
        The arrayBuffer()
        method, when invoked, MUST return an ArrayBuffer whose contents are
        bytes. Exceptions thrown during the creation of the
        ArrayBuffer object are re-thrown.
      
        The blob() method, when
        invoked, MUST return a Blob whose contents are bytes and
        type is not provided.
      
        The json() method, when
        invoked, MUST return the result of invoking the initial value of
        JSON.parse with the result of running utf-8 decode on
        bytes as argument. Re-throw any exceptions thrown by
        JSON.parse.
      
        The text() method, when
        invoked, MUST return the result of running utf-8 decode on bytes.
      
To extract a byte sequence from object, run these steps:
BufferSource
            USVString
            
        The Service Worker specification defines a ServiceWorkerGlobalScope interface
        [[!SERVICE-WORKERS]], which this specification extends.
      
partial interface ServiceWorkerGlobalScope {
    attribute EventHandler onpush;
    attribute EventHandler onpushsubscriptionchange;
};
      
        The onpush attribute is
        an event handler whose corresponding event handler event type is
        push.
      
        The onpushsubscriptionchange
        attribute is an event handler whose corresponding event handler event type is
        pushsubscriptionchange.
      
push event
        The PushEvent interface represents a received push message.
typedef (BufferSource or USVString) PushMessageDataInit;
dictionary PushEventInit : ExtendableEventInit {
    PushMessageDataInit data;
};
[Constructor(DOMString type, optional PushEventInit eventInitDict), Exposed=ServiceWorker]
interface PushEvent : ExtendableEvent {
    readonly attribute PushMessageData? data;
};
        Upon receiving a push message from the push service, the user agent MUST run the following steps:
null.
          push event MUST NOT be fired for a push message that was
                not successfully decrypted using the key pair associated with the push
                subscription.
              PushEvent interface, with the event type push, which
              does not bubble, is not cancelable, and has no default action.
              data attribute of
              e to a new PushMessageData instance with bytes
              set to the binary push message data.
              If the same push message has been delivered to a service worker registration multiple times unsuccessfully, acknowledge the receipt of the push message according to [[!WEBPUSH-PROTOCOL]].
Acknowledging the push message causes the push service to stop delivering the message and to report success to the application server. This prevents the same push message from being retried by the push service indefinitely.
Acknowledging also means that an application server could incorrectly receive a delivery receipt indicating successful delivery of the push message. Therefore, multiple rejections SHOULD be permitted before acknowledging; allowing at least three attempts is recommended.
When a constructor of the PushEvent interface, or of an interface that inherits from the PushEvent interface, is invoked, the usual steps for constructing events are extended to include the following steps:
data member is not present, set the 
            data attribute of the event to null and terminate these steps.
          data" member of eventInitDict.
          data attribute of the event to a new PushMessageData
          instance with bytes set to b.
          pushsubscriptionchange event
        
          The pushsubscriptionchange event indicates that a push subscription
          has been invalidated, or will soon be invalidated. For example, the push service
          MAY set an expiration time. A Service Worker SHOULD attempt to resubscribe while
          handling this event, in order to continue receiving push messages.
        
When new push subscription information becomes available, the user agent MUST run the following steps:
ExtendableEvent interface, with the event type
              pushsubscriptionchange, which does not bubble, is not cancelable, and
              has no default action.
              This algorithm ensures that the Service Worker is able to react to any non-destructive change in a push subscription, such as an automatic refresh, without causing any active push subscription to be terminated prematurely. A Service Worker can request a new push subscription during this process and ensure that no push messages are lost.
enum PushPermissionState {
    "granted",
    "denied",
    "prompt"
};
      | Enumeration | Description | 
|---|---|
| granted | The webapp has permission to use the Push API. | 
| denied | The webapp has been denied permission to use the Push API. | 
| prompt | The webapp needs to ask for permission in order to use the Push API. | 
The editors would like to express their gratitude to the Mozilla and Telefónica Digital teams implementing the Firefox OS Push message solution and specially to Doug Turner, Nikhil Marathe, Fernando R. Sela, Guillermo López, Antonio Amaya, José Manuel Cantera and Albert Crespell, for their technical guidance, implementation work and support.