Pushover Subscription API

Pushover Subscriptions are an easy way to collect Pushover user keys for an application to broadcast notifications to a bunch of users without any administration.

TL;DR

  1. Create a subscription for your Pushover application and choose whether to automatically add subscribed users to a Delivery Group, or to redirect back to a URL for a web subscription flow.
  2. The subscription request is initiated by clicking on a link to your subscription URL that was sent to the user
  3. Pushover displays a dialog to the user showing information about your application and asked to confirm the subscription
  4. Once the user confirms the subscription:
    1. For group-based subscriptions, the user's new dynamic user key is added to your group list on our servers and any new notifications sent to your group's key will be delivered to the new user; you're all done!
    2. For web-based subscriptions, the user is redirected back to your website to the URL contained in the success parameter you attached to the URL in step 2; you should store the pushover_user_key parameter you receive and associate it with the current user
  5. Send messages using our message API and for the user parameter, send your group's key (if using group-based subscriptions) or your new subscribed user's key (which we sent as pushover_user_key in step 4)

Create a Pushover Subscription

To get started with Pushover Subscriptions, view your application and click "Edit Subscription Settings". Fill out the required fields and a subscription key and URL will be created based on your application's name.

For applications that broadcast the same notifications to all subscribed users (such as news sites or blog updates), we recommend opting for a Group-based subscription. With this type of subscription, no further action is needed on your part to manage users. You can then direct users to the subscription URL that we provide and everything will be handled on our end.

For private applications or those sending individual notifications to users (such as a forum sending private messages to users, or a network monitoring system), you will need to choose a URL-based subscription. With this type of subscription, you must store the user's key in your database and associate it with the current user. See below for more information.

User Subscription Initiation

For group-based subscriptions, users can initiate the subscription process just by navigating to your subscription URL (found in your app's settings). Users can find your subscription by clicking on a link that you send them in an e-mail, or by scanning a QR code, or any other mechanism. Once the user visits your subscription URL and confirms the request, they will be automatically added to your group and the process is complete.

For web-based subscriptions, the process is a bit more complicated because we need to direct the user back to your website after subscribing and pass along their new Pushover user key. The details of this process can be found below.

For both subscription types, we have some buttons you can use to initiate a subscription process for your user.

Web-Based Subscription Process

For applications sending private notifications, the web-based subscription process will typically start on your own website. Your website will need to display a link or button somewhere that users can click on to initiate the subscription process. When the user clicks on the link/button, they should be directed to your application's subscription URL with the success parameter pointing back to your website.

After subscribing, the user will be redirected back to the URL you specified as the success parameter, and we will include a pushover_user_key parameter with the user's new key.

If the user decides not to subscribe, they will be redirected back to a URL you specify as the failure parameter, or your subscription's base URL if not supplied. If an already-subscribed user chooses to unsubscribe, they will be redirected back to your success URL with a blank pushover_user_key parameter, the pushover_unsubscribed parameter set to 1, and the pushover_unsubscribed_user_key parameter set to the user's now-deleted key.

Example

To illustrate how this process works, we'll work with a fictitious website called Forum that operates at https://forum.example.com/. Once users are logged into the Forum, they can view their user settings page at https://forum.example.com/settings and enable Pushover settings by clicking on a button. Once users are subscribed, we want them redirected back to https://forum.example.com/settings/enable_pushover where we will read the new Pushover user key, save it, and display a confirmation message to the user.

To start, we'll create a Pushover application and get an API token. Then, create a subscription by clicking on "Edit Subscription Settings" and choose a web-based subscription type with a base URL of https://forum.example.com/. After creating the subscription, a subscription URL will be shown:

https://pushover.net/subscribe/Forum-f504h08fhlasdfj

Since we want users redirected back to https://forum.example.com/settings/enable_pushover after subscribing, that URL must be URL-encoded and appended as the success parameter to the subscription URL above. If the user decides not to subscribe, we want to redirect them back to https://forum.example.com/settings, so we will include that as the failure parameter.

To improve security, before redirecting the user to the Pushover subscription page, we're going to store a random piece of data in the user's session (m5St1Fe67ly5d6). We'll then append that to our success URL and later verify that we got it back. Our success URL now looks like https://forum.example.com/settings/enable_pushover?rand=m5St1Fe67ly5d6, which we URL encode and append to our subscribe URL along with our failure parameter:

https://pushover.net/subscribe/Forum-f504h08fhlasdfj?success=https%3A%2F%2Fforum.example.com%2Fsettings%2Fenable_pushover%3Frand%3Dm5St1Fe67ly5d6&failure=https%3A%2F%2Fforum.example.com%2Fsettings

Note that because the subscription was initially created with a base URL of https://forum.example.com/, any success and failure URL parameters that you supply must start with that. If the success URL is missing or contains a URL that does not begin with the subscription's base URL, we will display an error and abort the subscription process as a security measure to prevent users from being redirected back to a rogue website. If the failure URL is not supplied, we will redirect the user back to the base URL upon denying a subscription request.

Continuing in our example, the user is now on the Pushover website at your application's subscription URL. The user confirms the subscription and they are redirected back to your success URL, including the user's new Pushover key as a parameter:

https://forum.example.com/settings/enable_pushover?rand=m5St1Fe67ly5d6&pushover_user_key=sPfjsD2fGzEd9TR52DU31Hv4A61Vvk

Once the user arrives back at the /settings/enable_pushover URL on your website, your application can verify that the random token received in the URL is what was stored in the user's session (see security below for more information) and then look for the pushover_user_key parameter and associate it to the current user's account.

If the pushover_user_key parameter is blank, the user was previously subscribed and has chosen to unsubscribe (a pushover_unsubscribed parameter set to 1 will also be included). You should clear any saved Pushover user key for this user.

Website Buttons

We've provided some example HTML/CSS for use on your website when directing the user to your subscription URL to subscribe or manage their subscription if already subscribed. Both should use the URL of your subscription (passing any parameters as detailed above).

<style type="text/css">
.pushover_button {
    box-sizing:border-box !important;display:inline-block;background-color:#eee !important;background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAycHgiIGhlaWdodD0iNjAycHgiIHZlcnNpb249IjEuMSIgdmlld0JveD0iNTcgNTcgNjAyIDYwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1OC45NjQgNTguODg4KSIgb3BhY2l0eT0iLjkxIj48ZWxsaXBzZSB0cmFuc2Zvcm09Im1hdHJpeCgtLjY3NDU3IC43MzgyMSAtLjczODIxIC0uNjc0NTcgNTU2LjgzIDI0MS42MSkiIGN4PSIyMTYuMzEiIGN5PSIxNTIuMDgiIHJ4PSIyOTYuODYiIHJ5PSIyOTYuODYiIGZpbGw9IiMyNDlkZjEiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLXdpZHRoPSIwIi8+PHBhdGggZD0ibTI4MC45NSAxNzIuNTFsNzQuNDgtOS44LTcyLjUyIDE2My42NmMxMi43NC0wLjk4IDI1LjIzMy01LjMwNyAzNy40OC0xMi45OCAxMi4yNTMtNy42OCAyMy41MjctMTcuMzE3IDMzLjgyLTI4LjkxIDEwLjI4Ny0xMS42IDE5LjE4Ny0yNC41MDMgMjYuNy0zOC43MSA3LjUxMy0xNC4yMTMgMTIuOTAzLTI4LjE4IDE2LjE3LTQxLjkgMS45Ni04LjQ5MyAyLjg2LTE2LjY2IDIuNy0yNC41LTAuMTY3LTcuODQtMi4yMS0xNC43LTYuMTMtMjAuNThzLTkuODgzLTEwLjYxNy0xNy44OS0xNC4yMWMtOC0zLjU5My0xOC44Ni01LjM5LTMyLjU4LTUuMzktMTYuMDA3IDAtMzEuNzcgMi42MTMtNDcuMjkgNy44NC0xNS41MTMgNS4yMjctMjkuODg3IDEyLjgyMy00My4xMiAyMi43OS0xMy4yMjcgOS45Ni0yNC43NCAyMi4zNzMtMzQuNTQgMzcuMjQtOS44IDE0Ljg2LTE2LjgyMyAzMS43NjMtMjEuMDcgNTAuNzEtMS42MzMgNi4yMDctMi42MTMgMTEuMTg3LTIuOTQgMTQuOTQtMC4zMjcgMy43Ni0wLjQwNyA2Ljg2My0wLjI0IDkuMzEgMC4xNiAyLjQ1MyAwLjQ4MyA0LjMzMyAwLjk3IDUuNjQgMC40OTMgMS4zMDcgMC45MDMgMi42MTMgMS4yMyAzLjkyLTE2LjY2IDAtMjguODMtMy4zNS0zNi41MS0xMC4wNS03LjY3My02LjY5My05LjU1LTE4LjM3LTUuNjMtMzUuMDMgMy45Mi0xNy4zMTMgMTIuODIzLTMzLjgxIDI2LjcxLTQ5LjQ5IDEzLjg4LTE1LjY4IDMwLjM3My0yOS40ODMgNDkuNDgtNDEuNDEgMTkuMTEzLTExLjkyIDQwLjAyLTIxLjM5IDYyLjcyLTI4LjQxIDIyLjcwNy03LjAyNyA0NC44NC0xMC41NCA2Ni40LTEwLjU0IDE4Ljk0NyAwIDM0Ljg3IDIuNjkzIDQ3Ljc3IDguMDggMTIuOTA3IDUuMzkzIDIyLjk1MyAxMi41IDMwLjE0IDIxLjMyczExLjY3NyAxOS4xMSAxMy40NyAzMC44N2MxLjggMTEuNzYgMS4yMyAyNC4wMS0xLjcxIDM2Ljc1LTMuNTkzIDE1LjM1My0xMC4zNzMgMzAuNzktMjAuMzQgNDYuMzEtOS45NiAxNS41MTMtMjIuNDUzIDI5LjU2LTM3LjQ4IDQyLjE0LTE1LjAyNyAxMi41NzMtMzIuMjYgMjIuNzgtNTEuNyAzMC42Mi0xOS40MzMgNy44NC00MC4wOTMgMTEuNzYtNjEuOTggMTEuNzZoLTIuNDVsLTYyLjIzIDEzOS42NWgtNzAuNTZsMTM4LjY3LTMxMS42NHoiIGZpbGw9IiNmZmYiIHN0eWxlPSJ3aGl0ZS1zcGFjZTpwcmUiLz48L2c+PC9zdmc+) 3px 3px no-repeat;background-size:15px 15px;border-bottom:2px solid rgba(22,22,22,0.25) !important;border-right:2px solid rgba(22,22,22,0.25) !important;box-shadow: 0pt 2px 0pt rgba(255, 255, 255, 0.2) inset, 0pt 2px 0px rgba(0, 0, 0, 0.05) !important;border-radius:3px !important;color:#333 !important;display:inline-block !important;font:11px/18px "Helvetica Neue",Arial,sans-serif !important;font-weight:bold !important;cursor:pointer !important;height:22px !important;padding:1px 6px 20px 22px!important;overflow:hidden !important;text-decoration:none !important;vertical-align:middle !important;height:22px !important;
}
</style>

<a class="pushover_button" href="https://pushover.net/subscribe/YOUR_SUBSCRIPTION_CODE">
  Subscribe With Pushover
</a>

This would create a styled link that looks like a button:

Web-Based Security

The example shown above uses a random token mechanism to avoid a potential security problem: because we are redirecting users to a predictable success URL, it is possible for an attacker to force a user to access that URL with a custom pushover_user_key that the attacker controls. Without any validation, your application would just store that Pushover user key on the user's account and begin sending private notifications meant for the user to the attacker.

To avoid this security problem, you could store a random piece of data in the user's session on your website before sending them to the subscription URL. This piece of data would be something that only that particular user would be able to access and an attacker would not. Then, by appending it to your success URL in a way that your application can later check for, we pass it through upon redirection and your application can verify that the random token we passed through matches what is in the user's session. If the verification failed, your application would not store the received pushover_user_key (and probably notify someone about a security breach attempt).

Because this process of generating random data, adding it to the user's session, and verifying it from the URL is highly dependent upon how your website is built, we leave this up to you to implement. As an example using PHP, your Pushover button could call the following code to create a random token, add it to the user's session, and then redirect the user to your subscription URL:

<?php

$_SESSION["pushover_rand"] = bin2hex(openssl_random_pseudo_bytes(20));

header("Location: https://pushover.net/subscribe/Forum-f504h08fhlasdfj"
    . "?success=" . urlencode("https://forum.example.com/settings/enable_pushover?rand=" . $_SESSION["pushover_rand"])
    . "&failure=" . urlencode("https://forum.example.com/settings"));

?>

Then the code at /settings/enable_pushover would verify that the supplied random token in the URL matches the session token before saving pushover_user_key:

<?php

if (empty($_SESSION["pushover_rand"]))
    die("no random token in session");

if (empty($_REQUEST["rand"]) || $_REQUEST["rand"] !== $_SESSION["pushover_rand"])
    die("no random token passed through pushover, possible security problem");

// verification passed, it's now ok to save $_REQUEST["pushover_user_key"]
...
?>

User Key Migration

Applications that formerly collected Pushover user keys are encouraged to migrate to subscription keys. This API call takes an application token, a subscription code, and a user key and creates a subscription for the user. Upon receiving a successful API response, you can discard the user's key and save the received subscribed_user_key in place of it.

To migrate your users, send one POST request for each user (HTTP keep-alive supported to send multiple requests over the same connection) to:

https://api.pushover.net/1/subscriptions/migrate.json

Include the following parameters:

  • token (required) - your application's API token
  • subscription (required) - your subscription's code
  • user (required) - the user's Pushover user key
  • device_name (optional) - a user's device name that the subscription should be limited to
  • sound (optional) - a user's preferred default sound

Upon success, you will receive a status code of 1 and a subscribed_user_key parameter to save in place of the user's original key.

{"status":1,"subscribed_user_key":"sPfjsD2fGzEd9TR52DU31Hv4A61Vvk","request":"647d2300-702c-4b38-8b2f-d56326ae460b"}