Pushover REST API

Pushover uses a simple REST API to receive messages from your application and send them to devices running our device clients. To simplify the user registration process and usage of our API, there are no complicated out-of-band authentication mechanisms or per-call signing libraries required, such as OAuth. HTTP libraries available in just about every language, or even from the command line, can be used without any custom modules or extra dependencies needed. See our FAQ for examples in different programming languages.


  1. Register your application, set its name and upload an icon, and get an API token in return.
  2. POST an HTTPS request to https://api.pushover.net/1/messages.json with the following parameters:
    • token (required) - your application's API token
    • user (required) - the user/group key (not e-mail address) of your user (or you), viewable when logged into our dashboard
    • message (required) - your message
    Some optional parameters may be included:
    • device - your user's device name to send the message directly to that device, rather than all of the user's devices
    • title - your message's title, otherwise your app's name is used
    • url - a supplementary URL to show with your message
    • url_title - a title for your supplementary URL, otherwise just the URL is shown
    • priority - send as -1 to always send as a quiet notification, 1 to display as high-priority and bypass the user's quiet hours, or 2 to also require confirmation from the user
    • timestamp - a Unix timestamp of your message's date and time to display to the user, rather than the time your message is received by our API
    • sound - the name of one of the sounds supported by device clients to override the user's default sound choice

That's it. Make sure your application is friendly to our API servers and you're all set. For more information on each parameter, keep reading or jump to a section at the left.

Need help using our API or found an error in the documentation? Drop us a line.

Application Registration

To get started pushing notifications from your application, plugin, web service, server, or anything else, you'll first need to register it (a free process) to get an API token. When registering an app, you'll be able to set its name which will be used as a default title for messages, as well as upload an icon that will appear with each message on device clients. Each application from which you are pushing notifications with should be registered separately and each will get its own monthly quota.

Example Application API Token:  KzGDORePK8gMaC0QOYAMyEEuzJnyUi

Application tokens are case-sensitive, 30 characters long, and may contain the character set [A-Za-z0-9]. All API calls made on behalf of your application must include this token.

Note: If you are creating a client-side library, application, or open source project that will be redistributed and installed by end-users, you may want to require each of your users to register their own application rather than including your own API token with the software. See our FAQ for more inforamtion.

Users, Groups, and Devices

Once you have an API token for your application, you'll need the user key and optional device name for each user to which you are pushing notifications. If a device name is not specified for a user, or the specified device name is no longer enabled/valid, notifications will be sent to all active devices for that user to avoid losing messages.

Instead of a user key, a user may supply a group key. Group keys look identical to user keys and from your application's perspective, you do not need to distinguish between them. When sending notifications to a group key, all active users listed in the group will have the notification delivered to them and the response will look the same.

As with application API tokens, user keys should be considered private and not disclosed to 3rd parties. Users should be able to update their identifiers and/or device names with your application or service.

Example User Identifier:  uQiRzpo4DXghDmr9QzzfQu27cmVRsG

Example Group Identifier:  gznej3rKEVAvPUxu9vvNnqpmZpokzF

Example User Device Name:  droid2

User and group identifiers are 30 characters long, case-sensitive, and may contain the character set [A-Za-z0-9]. Device names are optional, may be up to 25 characters long, and will contain the character set [A-Za-z0-9_-].

As an optional step, your application may verify user or group identifiers after they have been submitted to you. This will ensure that a user has copied his or her identifier properly, that the account is valid, and that there is at least one active device on the account.

Pushing Messages

Messages must contain a message parameter that contains the message body and an optional title parameter. If the title is not specified, the application's name will be shown by default. HTTP and HTTPS URLs included in messages will be automatically parsed by the device clients and shown as clickable links. To include a clickable link outside of your message body, see the supplemental URL section.

In this example, we will use the application token, user key, and device name above to push a message about a completed process.

Using an HTTP library available in your application's language, construct a POST request (not a GET request) to the following URL:


The .json suffix requests that the response be in JSON format. https://api.pushover.net/1/messages.xml may be used instead to receive an XML response. Note that this does not affect how you send your parameters to our server (which should be in the standard percent-encoding format), only how our server responds. We do not support receiving JSON or XML-encoded parameters.

HTTPS is required for all API calls, and for security purposes, your application should enable your HTTP library's SSL verification. The POST method is required be used for the API call to push messages.

Include the token, user, device (optional), title (optional), and message parameters in the body of the request as standard key-value pairs. Continuing with our example, these parameters would be:

token = KzGDORePKggMaC0QOYAMyEEuzJnyUi

user = e9e1495ec75826de5983cd1abc8031

device = droid4

title = Backup finished - SQL1

message = Backup of database "example" finished in 16 minutes.

Those parameters would look like this when POSTed as a URL-encoded (also known as percent-encoded) request:

POST /1/messages.json
Host: api.pushover.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 180


That message would appear like this in the Pushover client on an Android device:


Specifying a Message Time

Messages are stored on the Pushover servers with a timestamp of when they were initially received through the API. This timestamp is shown to the user, and messages are listed in order of their timestamps. In most cases, this default timestamp is acceptable.

In some cases, such as when messages have been queued on a remote server before reaching the Pushover servers, or delivered to Pushover out of order, this default timestamping may cause a confusing order of messages when viewed on the user's device. For these scenarios, your app may send messages to the API with the timestamp parameter set to the Unix timestamp of the original message. For example, sending timestamp=1331249662 would deliver the message with a time of March 8, 2011 17:34:22 CST (but shown relative to the local device's timezone).


Message Priority

By default, messages have normal priority (a priority of 0). Messages may be sent with a different priority that affects how the message is presented to the user. Please use your best judgement when specifying a message priority as overusing high-priority messages will be annoying to users. Specifying a message priority does not affect queueing or routing priority and only affects how device clients display them.

Low Priority (-1)

If the priority parameter is sent with a value of -1, messages will be considered low priority. Low priority messages will always be delivered as though they were during a user's quiet hours, and will not play sound or trigger vibration. On iOS, these messages will only increase the application's badge number. On Android, the message will appear in the notification bar but without sound or vibration.

Tip: To have your message still display on both clients and still trigger vibration, but no sound, do not specify a priority but instead set the sound parameter to none.

Normal Priority (0)

Messages sent without a priority parameter, or sent with the parameter set to 0, have the default priority. These messages trigger sound, vibration, and display an alert according to the user's device settings. On iOS, the message will display at the top of the screen or as a modal dialog, as well as in the notification center. On Android, the message will scroll at the top of the screen and appear in the notification center.

If a user has quiet hours set and your message is received during those times, your message will be delivered as though it had a priority of 0.

High Priority (1)

Messages sent with a priority of 1 are high priority messages that bypass a user's quiet hours. These messages will always play a sound and vibrate (if the user's device is configured to) regardless of the delivery time. High-priority should only be used when necessary and appropriate.

High-priority messages are highlighted in red in the device clients.


Emergency Priority (2)

Emergency-priority notifications are similar to high-priority notifications, but they are repeated until the notification is acknowledged by the user. These are designed for dispatching and on-call situations where it is critical that a notification be repeatedly shown to the user (or all users of the group that the message was sent to) until it is acknowledged. Applications sending emergency notifications are issued a receipt that can be used to get the status of a notification and find out whether it was acknowledged, or automatically receive a callback when the user has acknowledged the notification.

To send an emergency-priority notification, the priority parameter must be set to 2 and the retry and expire parameters must be supplied.

The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user. In a situation where your user might be in a noisy environment or sleeping, retrying the notification (with sound and vibration) will help get his or her attention. This parameter must have a value of at least 30 seconds between retries.

The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds). If the notification has not been acknowledged in expire seconds, it will be marked as expired and will stop being sent to the user. Note that the notification is still shown to the user after it is expired, but it will not prompt the user for acknowledgement. This parameter must have a maximum value of at most 86400 seconds (24 hours).

For example, sending a retry parameter of 60 and an expire parameter of 3600 will cause your notification to be retried every 60 seconds for 1 hour.

The optional callback parameter may be supplied with a publicly-accessible URL that our servers will send a request to when the user has acknowledged your notification.

When your application sends an emergency-priority notification, our API will respond with a receipt value that can be used to get information about whether the notification has been acknowledged. See our receipts and callbacks section for more information.

Supplementary URLs

The Pushover device clients automatically turn URLs found in message bodies into clickable links that open in the device's browser (or whichever application is configured to handle them). It may be desirable to include a supplementary URL that is not included in the message text, but available for the user to click on. This URL will be passed directly to the device client, with a URL title of the supplied title (defaulting to the URL itself if no title given). Supplementary URLs can be useful for presenting long URLs in a notification as well as interacting with 3rd party applications.

For example, if a Pushover application were sending Twitter messages to a user, a supplementary URL may be sent that includes the actual link to the message that would open in the user's browser (e.g., http://twitter.com/user/status/12345) or a URL that will perform some action in another application installed on the device (e.g., twitter://status?id=12345). The message displayed in the Pushover client would be the actual contents of the Twitter message (with any URLs originally contained in it automatically turned into links), but the supplementary link will be shown underneath it as an option available to the user when the message is highlighted. An example request to our API might have the following parameters:

token = KzGDORePKggMaC0QOYAMyEEuzJnyUi

user = e9e1495ec75826de5983cd1abc8031

message = This is a Twitter pic http://twitpic.com/blah

title = Direct message from @someuser

url = twitter://direct_message?screen_name=someuser

url_title = Reply to @someuser

This message would appear in a Pushover device client like so:


When the user taps on the notification in Pushover to expand it, the URL will be shown below it with the supplied url_title parameter, titled "Reply to @someuser", which when clicked, will launch a Twitter application that is set to handle the URL twitter://direct_message link?screen_name=someuser.


While there are some standard URL schemes like tel: and sms: that will be handled by iOS and Android the same way, others like the twitter:// scheme used above are highly specific to the platform and other applications installed on the device. A list of common URL schemes supported by applications on iOS can be found at handleopenurl.com, and a list handled natively by Android can be found on developer.android.com. Since Pushover users may be on different platforms and have different 3rd party applications installed, it is not recommended to use app-specific URL schemes as supplementary URLs in public plugins, websites, and apps.

Due to limitations of the iOS push notification service, supplementary URLs are not able to be shown with push notifications. Notifications in the Notification Center will only show the title and message. The user must tap on the notification or otherwise open the Pushover client, which will perform a sync with our servers, in order to download the attached supplementary URL. Since these URLs are supplementary, they should not be used as the primary content of your notification. If your notification is just a URL, include it in the message body instead.

Notification Sounds

Users can choose from 21 different default sounds to play when receiving notifications, rather than our standard Pushover tone. Applications can override a user's default tone choice on a per-notification basis.

When sending notifications through the Pushover API, the sound parameter may be set to one of the following:

  • pushover - Pushover (default)
  • bike - Bike
  • bugle - Bugle
  • cashregister - Cash Register
  • classical - Classical
  • cosmic - Cosmic
  • falling - Falling
  • gamelan - Gamelan
  • incoming - Incoming
  • intermission - Intermission
  • magic - Magic
  • mechanical - Mechanical
  • pianobar - Piano Bar
  • siren - Siren
  • spacealarm - Space Alarm
  • tugboat - Tug Boat
  • alien - Alien Alarm (long)
  • climb - Climb (long)
  • persistent - Persistent (long)
  • echo - Pushover Echo (long)
  • updown - Up Down (long)
  • none - None (silent)

If no sound parameter is specified, the user's default tone will play. If the user has not chosen a custom sound, the standard Pushover sound will play.

In most cases, applications choosing to override the default sound should offer the user the option to pick a sound from the list above. Rather than hard-coding the list of sounds (since more may be added in the future), an API call may be made to retrieve the list of current sounds and their descriptions by sending a GET request to:

https://api.pushover.net/1/sounds.json?token=(your app token)

Include your application's token as the token parameter. This API call returns a sounds hash with each key being the actual sound parameter to store for the user and send to our API, with its value describing the sound.

Note: In addition to the list of sounds from our API, your application must provide a blank option to the user that will not send the sound parameter to our API (or send it with a blank value). This will allow the user's default tone to play, rather than being overridden by your application.

Response Format

If your POST request to our API was valid, you will receive an HTTP 200 (OK) status, with a JSON object (or XML stanza if you specified a URL ending in .xml) containing a status code of 1.


If any input was invalid, you will receive an HTTP 4xx status, with a JSON object or XML node containing a status code of something other than 1, and an errors array detailing which parameters were invalid.

{"user":"invalid","errors":["user identifier is invalid"],

If you sent a priority=2 notification, you will also receive a receipt parameter in your response that can be used with our receipts API.

The request parameter returned from all API calls is a randomly-generated unique token that we have associated with your request. If you need to contact us about a question or problem with our API, please include this request parameter that our API returned so we can look up your original request in our logs.


Messages are currently limited to 512 characters, including a title. Supplementary URLs are limited to 512 characters, and URL titles to 100 characters.

Applications are currently limited to sending 7,500 messages per month, where one message is defined as a successful messages API call to one user, regardless of the number of devices on that user's account. Messages sent to group keys are counted as one message for each user in the group.

If your application needs a higher message limit, please see our FAQ for pricing information. For open source applications, see our question about distribution of your API token.

Once message limits have been reached, requests will be rejected with a 429 HTTP status code. Message limits are reset at 00:00:00 Central Time on the 1st of each month. Per-day usage statistics can be viewed on each application's page, as well as through HTTP headers returned in each API call to the messages endpoint showing your app's monthly message limit (plus any additional purchased capacity), the number of messages sent this month, and the Unix timestamp of when the count will reset.

X-Limit-App-Limit: 7500
X-Limit-App-Remaining: 7496
X-Limit-App-Reset: 1393653600

For security purposes, once a message is verified to have been delivered to a device (which happens after the client on the device is opened and a sync over HTTPS is performed, not just after the message is delivered to Apple/Google carrier servers), the message is deleted from the Pushover servers. Messages not verified to have been received will be deleted after 21 days of being sent to carrier servers. Messages are delivered to and stored on each device separately and are not viewable from the Pushover website or any other device, unless those messages have also been pushed to those devices through the API.

User/Group Verification

As an optional step in collecting user keys for users of your application, you may verify those keys to ensure that a user has copied them properly, that the account is valid, and that there is at least one active device on the account. User and group identifiers may be verified by POSTing an HTTPS request to:


Include your application's token as the token parameter, the user's or group's identifier as the user parameter, and an optional device parameter. If the device parameter is supplied, the verification will apply to that user and device. If the parameter is not supplied, a user will be validated if there is at least one active device on the account.

The validate call returns a response with status set to 1 if the user is valid, in addition to a devices array containing the names of the user's active devices. If the user and/or device is not valid, status will be set to 0, optionally with a parameter detailing a specific error.

Receipts and Callbacks

Applications sending emergency-priority notifications will receive a receipt parameter from our API when a notification has been queued. This parameter is a case-sensitive, 30 character string containing the character set [A-Za-z0-9]. This receipt can be used to periodically poll our receipts API to get the status of your notification, up to 1 week after your notification has been received.

Submit a GET request (no faster than once every 5 seconds) to:

https://api.pushover.net/1/receipts/(your receipt).json?token=(your app token)

Include the receipt in the URL and your application's token as the token parameter. If the receipt is valid, our API will respond with some integer-valued parameters about your notification:

status = 1 (indicating your receipt request was successful)

acknowledged = 1 (1 or 0 whether the user has acknowledged the notification)

acknowledged_at = 1360019238 (a Unix timestamp of when the user acknowledged, or 0)

acknowledged_by = (user key) (the user key of the user that first acknowledged the notification)

last_delivered_at = 1360001238 (a Unix timestamp of when the notification was last retried, or 0)

expired = 1 (1 or 0 whether the expiration date has passed)

expires_at = 1360019290 (a Unix timestamp of when the notification will stop being retried)

called_back = 1 (1 or 0 whether our server has called back to your callback URL if any)

called_back_at = 1360019239 (a Unix timestamp of when our server called back, or 0)

Callback URLs

Rather than periodically polling our receipts API, you may also include a callback parameter when submitting your emergency notification. This must be a URL (HTTP or HTTPS) that is reachable from the Internet that our servers will call out to as soon as the notification has been acknowledged. If a callback URL exists, we will submit a POST request to the URL with the following parameters:

receipt = (your receipt ID)

acknowledged = 1

acknowledged_at = 1360019238 (a Unix timestamp of when the notification was acknowledged)

acknowledged_by = (user key) (the user key of the user that first acknowledged the notification)

If our API servers do not receive a successful (2xx) HTTP response from your callback URL, we will retry again in one minute.

Being Friendly to our API

When creating an application that will use our API, please consider that your message may not go through for various reasons. We might be having temporary technical difficulties, your application might have exceeded its monthly quota, or the user you are sending to may have deactivated his or her account.

The key to being friendly to our API is to pay attention to how it responds:

  • If we issue a 200 HTTP response and the status parameter in the JSON/XML body is 1, your notification has been received and queued. Well done.
  • If we issue a 4xx HTTP response, or the status parameter is not 1, your input was invalid. Either your application is over its quota, your token is invalid, a user is no longer active, etc. Parse the JSON/XML response, noting the errors array if present, and take the appropriate response for your type of message. The important part is that repeating your same request will not work, no matter how many times you retry it. Your input needs to be changed or you should stop retrying.
  • If we issue a 500 or any other HTTP response, you were unable to connect to our API, or you did not get a reply, it means we are having temporary problems. You can repeat your same request again, but no sooner than 5 seconds from your last request.

Your application should implement basic rate limiting. Do not send more than 2 concurrent HTTP requests (TCP connections) to our API, or we may do rate limiting on our side which may cause timeouts and refused connections for your IP. To speed up multiple requests, you may send each request in sequence over the same TCP connection using HTTP keep-alive to avoid the overhead of a new TCP connection and SSL negotiation. Do not retry the same request more than once every 5 seconds. If we're having temporary difficulties, flooding our servers with repeated requests will just make the problem worse for everyone.

If your application fails to act in a sane manner and ends up flooding our servers, we will be forced to block your IP and/or disable your application and you should feel bad.