Register Device
curl --request POST \
--url https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices \
--header 'Content-Type: application/json' \
--data '
{
"platform": "<string>",
"token": "<string>",
"subscription": {
"endpoint": "<string>",
"keys.p256dh": "<string>",
"keys.auth": "<string>"
}
}
'import requests
url = "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices"
payload = {
"platform": "<string>",
"token": "<string>",
"subscription": {
"endpoint": "<string>",
"keys.p256dh": "<string>",
"keys.auth": "<string>"
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
platform: '<string>',
token: '<string>',
subscription: {endpoint: '<string>', 'keys.p256dh': '<string>', 'keys.auth': '<string>'}
})
};
fetch('https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'platform' => '<string>',
'token' => '<string>',
'subscription' => [
'endpoint' => '<string>',
'keys.p256dh' => '<string>',
'keys.auth' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices"
payload := strings.NewReader("{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices")
.header("Content-Type", "application/json")
.body("{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_bodyPush Notification Endpoints
Register Device
Register a device to receive push notifications for the authenticated user
POST
/
:projectId
/
api
/
v7
/
push-notifications
/
devices
Register Device
curl --request POST \
--url https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices \
--header 'Content-Type: application/json' \
--data '
{
"platform": "<string>",
"token": "<string>",
"subscription": {
"endpoint": "<string>",
"keys.p256dh": "<string>",
"keys.auth": "<string>"
}
}
'import requests
url = "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices"
payload = {
"platform": "<string>",
"token": "<string>",
"subscription": {
"endpoint": "<string>",
"keys.p256dh": "<string>",
"keys.auth": "<string>"
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
platform: '<string>',
token: '<string>',
subscription: {endpoint: '<string>', 'keys.p256dh': '<string>', 'keys.auth': '<string>'}
})
};
fetch('https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'platform' => '<string>',
'token' => '<string>',
'subscription' => [
'endpoint' => '<string>',
'keys.p256dh' => '<string>',
'keys.auth' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices"
payload := strings.NewReader("{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices")
.header("Content-Type", "application/json")
.body("{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sublay.io/api/v6/:projectId/api/v7/push-notifications/devices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform\": \"<string>\",\n \"token\": \"<string>\",\n \"subscription\": {\n \"endpoint\": \"<string>\",\n \"keys.p256dh\": \"<string>\",\n \"keys.auth\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_bodyRegisters a push device for the currently authenticated user. Re-registering the same physical device updates the existing record instead of creating a duplicate. If the device was previously registered by a different user (e.g. a shared device), it is reassigned to the calling user.
Requires end-user authentication (
Returned when no valid end-user token is present, or when a service/master key is used (impersonation is not allowed on this endpoint).
Returned when
Returned when the
Authorization: Bearer <accessToken>). Service and master keys are explicitly rejected — this endpoint has no impersonation path by design (see Security note).
Requires the push bundle.
Body Parameters
string
required
The device platform. One of
"ios", "android", or "web".string
The APNs or FCM device token. Required when
platform is "ios" or "android".object
The Web Push subscription object. Required when
platform is "web".Response
Returns200 with an empty body on success.
Error Responses
Unauthorized — 401
Unauthorized — 401
{ "error": "Unauthorized", "code": "push-device/unauthorized" }
Invalid Body — 400
Invalid Body — 400
{ "error": "...", "code": "push-device/invalid-body" }
platform is unrecognized, or when the required token / subscription field is missing for the given platform.Bundle Not Installed — 403
Bundle Not Installed — 403
{ "error": "...", "code": "database/tables-not-available" }
push bundle is not installed for this project.Security note
Unlike most other write endpoints, this endpoint does not accept auserId body parameter and cannot be called with a service key. Allowing a backend to register an arbitrary token for an arbitrary user would let it redirect that user’s push notifications to an attacker-controlled device. Registration must always come from the end user’s own session.

