REST API for Web Push Notifications and Pushpad API
You can use the REST API to send web push notifications. You can also use it to automate any task that you would normally perform manually in the Pushpad dashboard (e.g. creating a project) or for advanced integrations (e.g. updating the tags associated to the subscriptions).
The REST API includes:
If you only need to send push notifications from your web app, which is the most common use case, you can also use the libraries.
Authentication and global headers
In order to use the REST API you must generate a token in your account settings.
The following headers must be present in every request:
Content-Type: application/json
Accept: application/json
Authorization: Token token="ACCESS_TOKEN"
Root endpoint
All the requests sent to the API must use this prefix:
https://pushpad.xyz/api/v1
Status codes and errors
The response codes from the API follow the standard HTTP semantics.
These are some of the most common status codes that can be returned by the API:
-
Successful 2xx
200 OK
: a generic successful response (e.g. when the resource has been obtained or updated successfully)201 Created
: the resource has been created successfully (e.g. a new notification, a new project, etc.)202 Accepted
: the request has been accepted and will be processed later (e.g. when you delete an entire project, that is not performed immediately)204 No Content
: the request is successful and the response body is empty (e.g. when you cancel a notification or delete a resource)
-
Client Error 4xx
400 Bad Request
: a generic client error (e.g. when a required param is missing or the request body is malformed and cannot be parsed)401 Unauthorized
: an authentication failure (e.g. the token is not present in the request headers or it is invalid)402 Payment Required
: a code for billing issues (e.g. a notification is not sent because an invoice has not been paid for a long time)403 Forbidden
: you don't have permission to perform an action (e.g. the token is valid, but doesn't have access to that project)404 Not Found
: the resource doesn't exist or no longer exists (e.g. a notification is older than 35 days and has been deleted)422 Unprocessable Content
: the most common error when you send a request (e.g. create or update), but the content of the request has some invalid values (e.g. a field is too long, doesn't respect the format, etc.)429 Too Many Requests
: although we try to apply soft limits whenever possible, extremely high or unjustified volumes of requests may be rejected with this code (you can always contact our support)
-
Server Error 5xx
500 Internal Server Error
: an unexpected error or timeout in the processing of the request503 Service Unavailable
: a temporary error due to overload, orchestration or maintenance
The successful status codes are described in more detail below for each endpoint.
Notifications API
POST /projects/PROJECT_ID/notifications
Send a web push notification.
Request
{
"notification": {
"body": "Hello world",
"title": "My Website",
"target_url": "https://example.com",
"icon_url": "https://example.com/assets/icon.png",
"badge_url": "https://example.com/assets/badge.png",
"image_url": "https://example.com/assets/image.png",
"ttl": 600,
"require_interaction": true,
"silent": false,
"urgent": true,
"custom_data": "",
"actions": [
{
"title": "A button",
"target_url": "https://example.com/button-link",
"icon": "https://example.com/assets/button-icon.png",
"action": "myActionName"
}
],
"starred": false,
"send_at": "2016-07-06T10:09:00.000Z",
"custom_metrics": ["metric1", "metric2"]
},
"uids": ["uid0", "uid1", "uidN"],
"tags": ["tag0", "tag1", "tagA && !tagB"]
}
String body
: the main text of the push notification.String title
(optional, defaults to the project name): the title of the push notification.String target_url
(optional, defaults to the project website): the url the user is redirected to when clicks the push notification.String icon_url
(optional, defaults to the project icon): the url of an image that will be used as the notification icon. Suggested size: 192x192px.String badge_url
(optional, defaults to the project badge): the url of a small image (that represents the app or the notification category) that will be displayed when there is not enough space to display the full notification (e.g. Android status bar). Suggested size: 96x96px.String image_url
(optional): the url of an image that will be displayed in the notification content. Suggested size: 800px for the longer side.Integer ttl
(optional, defaults to the project setting which is 1 week by default): the number of seconds after which the notification should be dropped if the device of the user is offline.Boolean require_interaction
(optional, defaults to the project setting): set totrue
in order to prevent browser from automatically closing the notification after a few seconds. Currently this applies only to Chrome on desktop.Boolean silent
(optional, defaults to the project setting): set totrue
if you want to disable the notification sound and vibration.Boolean urgent
(optional, defaults to false): set totrue
for time-sensitive alerts (e.g. incoming phone call) that must wake up devices that are sleeping.Array uids
(optional): the users that should receive this push notification. When the field is omitted ornull
, it is ignored and the push notification is sent to everyone or to the people specified bytags
. When the field is an empty array, the notification will not be sent to anyone.Array tags
(optional): the segments that should receive this push notification (i.e. the browsers that have at least one of these tags associated will receive the notification). If bothuids
andtags
are present, only the browsers that match both the conditions will receive the notification (i.e. a browser must be associated to a user ID listed inuids
and have at least one of those tags). Instead of simple tags, you can pass boolean expressions that use the operators!
,&&
,||
(from highest to lowest precedence) and can include parentheses. If you pass an array of tags and boolean expressions they are interpreted as||
: the example above is equivalent to"tag0 || tag1 || tagA && !tagB"
. When the field is omitted ornull
, it is ignored and the push notification is sent to everyone or to the people specified byuids
. When the field is an empty array, the notification will not be sent to anyone.String custom_data
(optional): an arbitrary string that represents some metadata that you want to attach to the notification. This string is passed as an argument to the Javascript functions binded to the action buttons.-
Array actions
(optional): add some action buttons to the notification. It is an array of JSON objects with the following fields:String title
: the label to display on the action button.String target_url
(optional, defaults to the notificationtarget_url
): the page that opens up when the user clicks the button.String icon
(optional): the URL of a small icon for the action button.String action
(optional): an ID for the action that can be used to trigger a Javascript callback. It must be a string of word characters. You can learn more in the Action buttons section.
Boolean starred
(optional, defaults tofalse
): bookmark the notification to make it easier to find it from the Pushpad dashboard. You can use this feature to highlight some notifications, for example those that have been sent manually.String send_at
(optional, defaults to now): a time when the notification will be sent. You can use this feature to create scheduled notifications that will be sent at a given time in the future. You can read more in the Scheduled notifications section.Array custom_metrics
(optional): aggregate the stats for this notification into the specified buckets (you can add up to 3 buckets for a single notification). Custom metrics are a way to aggregate the stats for all the notifications that belong to a given category. You need to explicitly create the categories from the project settings before using this feature. You can learn more in the Monitoring section.
Response
201 Created
{
"id": 197123,
"scheduled": 5,
"uids": ["uid0", "uid1", "uidN"]
}
Integer id
: the notification id.Integer scheduled
: the number of devices to which the notification will be delivered. It can differ from the size ofuids
since some users may have enabled notifications on more than one device. This field is not available for scheduled notifications.Array uids
(only for requests withuids
): the users that will be actually reached by the notification (i.e. they are subscribed to push notifications). This field is not available for scheduled notifications.String send_at
(only for scheduled notifications): the time when the notification will be sent.
GET /notifications/NOTIFICATION_ID
Get a notification and its stats.
Response
200 OK
{
"id": 200,
"project_id": 123,
"title": "Foo Bar",
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"target_url": "https://example.com",
"icon_url": "https://example.com/assets/icon.png",
"badge_url": "https://example.com/assets/badge.png",
"image_url": "https://example.com/assets/image.png",
"ttl": 604800,
"require_interaction": false,
"silent": false,
"urgent": false,
"custom_data": "",
"custom_metrics": [],
"actions": [],
"starred": false,
"uids": null,
"tags": null,
"send_at": "2016-07-06T10:09:00.000Z",
"created_at": "2016-07-06T10:09:14.834Z",
"scheduled_count": 0,
"successfully_sent_count": 4,
"opened_count": 1
}
The following fields become available some seconds after the sending of the notification, when the deliveries have been fully scheduled:
Integer successfully_sent_count
: the number of notifications that were sent successfully by Pushpad.Integer opened_count
: the number of notifications that were clicked or opened.Integer scheduled_count
: the number of deliveries that are still in the sending queue.
You can read more about stats and their meaning in the Monitoring section.
For future notifications and cancelled notifications the stats are not available. The following fields are returned instead:
Boolean scheduled
: the deliveries have not started yet. You can try to cancel a notification that is in this status.Boolean cancelled
: the notification has been cancelled. A notification can be cancelled on purpose or it can be cancelled by the system (for example if you exceed the usage quota).
Note that notifications are stored on Pushpad for 35 days, then are removed.
GET /projects/PROJECT_ID/notifications
Lists the latest notifications.
Response
200 OK
[
{
"id": 212,
"project_id": 123,
"title": "Foo Bar",
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"target_url": "https://example.com",
"icon_url": "https://example.com/assets/icon.png",
"badge_url": "https://example.com/assets/badge.png",
"image_url": null,
"ttl": 604800,
"require_interaction": false,
"silent": false,
"urgent": false,
"custom_data": "",
"custom_metrics": [],
"actions": [],
"starred": false,
"uids": ["uid0", "uid1", "uidN"],
"tags": null,
"send_at": null,
"created_at": "2016-07-06T10:58:39.222Z",
"scheduled_count": 0,
"successfully_sent_count": 4,
"opened_count": 1
},
{
"id": 211,
"project_id": 123,
"title": "Foo Bar",
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"target_url": "https://example.com",
"icon_url": "https://example.com/assets/icon.png",
"badge_url": "https://example.com/assets/badge.png",
"image_url": "https://example.com/assets/image.png",
"ttl": 604800,
"require_interaction": false,
"silent": false,
"urgent": false,
"custom_data": "",
"custom_metrics": ["metric1", "metric2"],
"actions": [],
"starred": false,
"uids": null,
"tags": ["tag1", "tagA && !tagB"],
"send_at": "2016-07-06T10:09:00.000Z",
"created_at": "2016-07-06T10:58:39.192Z",
"scheduled_count": 400,
"successfully_sent_count": 4,
"opened_count": 1
}
]
You can pass these additional parameters in the query string of the URL:
Integer page
: if you have many notifications they get paginated and you need to retrieve them with multiple requests.
Note that notifications are stored on Pushpad for 35 days, then are removed.
DELETE /notifications/NOTIFICATION_ID/cancel
Cancel a scheduled notification.
Response
204 No Content
Subscriptions API
GET /projects/PROJECT_ID/subscriptions
List the subscriptions.
Response
200 OK
[
{
"id": 1169,
"endpoint": "https://example.com/push/f7Q1Eyf7EyfAb1",
"p256dh": "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
"auth": "cdKMlhgVeSPzCXZ3V7FtgQ==",
"uid": "exampleUid",
"tags": ["exampleTag1", "exampleTag2"],
"last_click_at": "2023-11-03T10:30:00.000Z",
"created_at": "2016-09-06T10:47:05.494Z"
},
{
"id": 1117,
"endpoint": "https://example.com/push/Q19f7EyfAb123u",
"p256dh": "BHhrxvu3G2__igFYiH_C0BTRL5TfLofea1jzpCanSkr7IpBwH7ydYyUHFv1jaD_vEzMVJhXemyG1LgbEjHAXpNY=",
"auth": "Ob3K94ec0XgOF6UgaR8Tbw==",
"uid": null,
"tags": [],
"last_click_at": null,
"created_at": "2016-09-06T10:47:05.494Z"
}
}
Warning: last_click_at
is an experimental feature that was added on November 2023. All the clicks before that date were not recorded and null
is returned.
You can pass these additional parameters in the query string of the URL:
Integer page
: if you have many subscriptions they get paginated and you need to retrieve them with multiple requests.Integer per_page
: the number of subscriptions per page.String[] uids
: filter subscriptions by user ID.String[] tags
: filter subscriptions by tags.
For example you can search for a subscription of myUser1
with myTag1
or myTag2
:
/projects/123/subscriptions?tags[]=myTag1&tags[]=myTag2&uids[]=myUser1
You can also use boolean expressions for tags. For example you can search all the subscriptions that match the expression tag1 && tag2 || !tag3
(remember to URL encode the special characters):
/projects/123/subscriptions?tags=tag1+%26%26+tag2+%7C%7C+%21tag3
If you just need to count the subscriptions that match a given query, you can make a HEAD
request and read the X-Total-Count
header.
GET /projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Show a subscription.
Response
200 OK
{
"id": 1169,
"endpoint": "https://example.com/push/f7Q1Eyf7EyfAb1",
"p256dh": "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
"auth": "cdKMlhgVeSPzCXZ3V7FtgQ==",
"uid": "exampleUid",
"tags": ["exampleTag1", "exampleTag2"],
"last_click_at": "2023-11-03T10:30:00.000Z",
"created_at": "2016-09-06T10:47:05.494Z"
}
POST /projects/PROJECT_ID/subscriptions
Create or import a subscription.
This is not the standard way to collect subscriptions. Usually you collect subscriptions using the Javascript SDK.
Request
{
"endpoint": "https://example.com/push/f7QEy7AAf71fICM:Af71Ey7AAAAf791bEjr",
"p256dh": "BCQVDTlYWdl05lal3lG5SKr3VxTrEWpZErbkxWrzknHrIKFwihDoZpc_2sH6Sh08h-CacUYI-H8gW4jH-uMYZQ4=",
"auth": "cdKMlhgVeSPzCXZ3V7FtgQ==",
"uid": "123",
"tags": ["tag1", "tag2"]
}
String endpoint
: the browser endpoint as described in the W3C Push API.String uid
(optional): an id of your choice that lets you identify the user later and target him with push notifications.String[] tags
(optional): an array of tags of your choice that will be associated to the subscription in order to find or target it later.
Response
201 Created
See GET for the response body.
PUT/PATCH /projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Update a subscription.
Request
{
"uid": "123",
"tags": ["tag1", "tag2"]
}
Response
200 OK
See GET for the response body.
DELETE /projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Delete a subscription.
Response
204 No Content
Projects API
GET /projects
List all projects.
Response
200 OK
[
{
"id": 339,
"sender_id": null,
"name": "Example Project 2",
"website": "https://example.org",
"icon_url": "https://example.org/icon.png",
"badge_url": "https://example.org/badge.png",
"notifications_ttl": 604800,
"notifications_require_interaction": false,
"notifications_silent": false,
"created_at": "2016-07-09T10:58:39.143Z",
"url": "https://pushpad.xyz/projects/339.json"
},
{
"id": 338,
"sender_id": 123,
"name": "Example Project 1",
"website": "https://example.com",
"icon_url": "https://example.com/icon.png",
"badge_url": "https://example.com/badge.png",
"notifications_ttl": 604800,
"notifications_require_interaction": false,
"notifications_silent": false,
"created_at": "2016-07-08T10:58:39.143Z",
"url": "https://pushpad.xyz/projects/338.json"
}
]
GET /projects/PROJECT_ID
Show project details and some stats.
Response
200 OK
{
"id": 361,
"sender_id": 123,
"name": "Example Project",
"website": "https://example.com",
"icon_url": "https://example.com/icon.png",
"badge_url": "https://example.com/badge.png",
"notifications_ttl": 604800,
"notifications_require_interaction": false,
"notifications_silent": false,
"created_at": "2016-07-06T10:58:39.143Z",
"subscriptions_count": 4
}
POST /projects
Create a new project.
Request
{
"sender_id": 123,
"name": "My project",
"website": "https://example.com",
"icon_url": "https://example.com/icon.png",
"badge_url": "https://example.com/badge.png",
"notifications_ttl": 604800,
"notifications_require_interaction": false,
"notifications_silent": false
}
Only the fields sender_id
, name
and website
are required. All the other fields are optional configurations that can be usually omitted.
Response
201 Created
See GET for the response body.
PUT/PATCH /projects/PROJECT_ID
Update project settings.
Request
{
"name": "My project",
"website": "https://example.com",
"icon_url": "https://example.com/icon.png",
"badge_url": "https://example.com/badge.png",
"notifications_ttl": 604800,
"notifications_require_interaction": false,
"notifications_silent": false
}
Response
200 OK
See GET for the response body.
DELETE /projects/PROJECT_ID
Delete a project asynchronously.
Response
202 Accepted
Senders API
GET /senders
List all senders.
Response
200 OK
[
{
"id": 174,
"name": "My sender 2",
"vapid_private_key": "-----BEGIN EC PRIVATE KEY----- ...",
"vapid_public_key": "-----BEGIN PUBLIC KEY----- ...",
"created_at": "2016-07-04T10:58:39.143Z",
"url": "https://pushpad.xyz/senders/174.json"
},
{
"id": 173,
"name": "My sender 1",
"vapid_private_key": "-----BEGIN EC PRIVATE KEY----- ...",
"vapid_public_key": "-----BEGIN PUBLIC KEY----- ...",
"created_at": "2016-07-03T10:58:39.143Z",
"url": "https://pushpad.xyz/senders/173.json"
}
]
GET /senders/SENDER_ID
Show sender settings.
Response
200 OK
{
"id": 182,
"name": "My sender",
"vapid_private_key": "-----BEGIN EC PRIVATE KEY----- ...",
"vapid_public_key": "-----BEGIN PUBLIC KEY----- ...",
"created_at": "2016-07-06T11:28:21.266Z"
}
POST /senders
Create a sender.
Request
{
"name": "My sender"
}
The vapid_private_key
and vapid_public_key
are generated automatically (recommended). However, if you want to import an existing sender, you can include them in the request.
Response
201 Created
See GET for the response body.
PUT/PATCH /senders/SENDER_ID
Update sender settings.
Request
{
"name": "My sender"
}
Response
200 OK
See GET for the response body.
DELETE /senders/SENDER_ID
Delete a sender. You cannot delete a sender if it has associated projects.
Response
204 No Content