curl --request POST \
--url https://api.ctrl-hub.com/v3/notifications/push-tokens \
--header 'Content-Type: application/vnd.api+json' \
--header 'X-Session-Token: <api-key>' \
--data '
{
"data": {
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
}
'import requests
url = "https://api.ctrl-hub.com/v3/notifications/push-tokens"
payload = { "data": {
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
} }
headers = {
"X-Session-Token": "<api-key>",
"Content-Type": "application/vnd.api+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Session-Token': '<api-key>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: {
type: 'push-tokens',
attributes: {
token: '740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad',
kind: 'alert',
device_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
}
}
})
};
fetch('https://api.ctrl-hub.com/v3/notifications/push-tokens', 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.ctrl-hub.com/v3/notifications/push-tokens",
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([
'data' => [
'type' => 'push-tokens',
'attributes' => [
'token' => '740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad',
'kind' => 'alert',
'device_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/vnd.api+json",
"X-Session-Token: <api-key>"
],
]);
$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.ctrl-hub.com/v3/notifications/push-tokens"
payload := strings.NewReader("{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Session-Token", "<api-key>")
req.Header.Add("Content-Type", "application/vnd.api+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.ctrl-hub.com/v3/notifications/push-tokens")
.header("X-Session-Token", "<api-key>")
.header("Content-Type", "application/vnd.api+json")
.body("{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ctrl-hub.com/v3/notifications/push-tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Session-Token"] = '<api-key>'
request["Content-Type"] = 'application/vnd.api+json'
request.body = "{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"platform": "ios",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
},
"meta": {
"created_at": "2023-11-07T05:31:56Z",
"last_seen_at": "2023-11-07T05:31:56Z"
}
},
"jsonapi": {
"version": "1.0"
}
}{
"id": "98ca4a78-b66f-4234-9719-aaf832ee6669",
"status": "400",
"title": "A validation error was encountered",
"source": {
"parameter": "include"
},
"meta": {
"resource": "wrong_value"
}
}{
"id": "05fc9c8d-73b9-4697-9337-57f7a567a48f",
"status": "401",
"title": "You are not authorised to access this resource",
"detail": "In order to access this resource, you need the 'admin' role.",
"code": "AUTH.001"
}{
"id": "fe9d9a69-f0a7-4fdc-bb2c-176027f316c5",
"status": "500",
"title": "Internal Server Error",
"detail": "An unexpected error occurred on the server."
}Register a device for push notifications
Registers the signed-in user’s device to be sent push notifications, with the device’s own push
token: the APNs device token as hex on iOS, or the FCM registration token on Android. mono sends to
Apple and Google with it directly. The mobile app calls it after sign-in, and again whenever its token
changes. A token that doesn’t look like one for its platform is a 400 (CH.012.302).
Each token has a kind and the device_id the app made for its installation. A device holds one
token of each kind, so registering a token deletes the device’s other token of the same kind, which
the platform has replaced. alert, the app’s own notifications, is the only kind for now.
Registering a token the caller already holds refreshes it and answers with the same record. A token held by another user moves to the caller, because a phone can change hands. Either way the answer is a 201 with the token as stored.
Only a user can register a device. A service account or agent is refused (CH.012.304). No
permission is needed: the token belongs to the caller.
curl --request POST \
--url https://api.ctrl-hub.com/v3/notifications/push-tokens \
--header 'Content-Type: application/vnd.api+json' \
--header 'X-Session-Token: <api-key>' \
--data '
{
"data": {
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
}
'import requests
url = "https://api.ctrl-hub.com/v3/notifications/push-tokens"
payload = { "data": {
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
} }
headers = {
"X-Session-Token": "<api-key>",
"Content-Type": "application/vnd.api+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Session-Token': '<api-key>', 'Content-Type': 'application/vnd.api+json'},
body: JSON.stringify({
data: {
type: 'push-tokens',
attributes: {
token: '740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad',
kind: 'alert',
device_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
}
}
})
};
fetch('https://api.ctrl-hub.com/v3/notifications/push-tokens', 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.ctrl-hub.com/v3/notifications/push-tokens",
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([
'data' => [
'type' => 'push-tokens',
'attributes' => [
'token' => '740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad',
'kind' => 'alert',
'device_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/vnd.api+json",
"X-Session-Token: <api-key>"
],
]);
$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.ctrl-hub.com/v3/notifications/push-tokens"
payload := strings.NewReader("{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Session-Token", "<api-key>")
req.Header.Add("Content-Type", "application/vnd.api+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.ctrl-hub.com/v3/notifications/push-tokens")
.header("X-Session-Token", "<api-key>")
.header("Content-Type", "application/vnd.api+json")
.body("{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ctrl-hub.com/v3/notifications/push-tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Session-Token"] = '<api-key>'
request["Content-Type"] = 'application/vnd.api+json'
request.body = "{\n \"data\": {\n \"type\": \"push-tokens\",\n \"attributes\": {\n \"token\": \"740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad\",\n \"kind\": \"alert\",\n \"device_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "push-tokens",
"attributes": {
"token": "740f4707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bb78ad",
"platform": "ios",
"kind": "alert",
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
},
"meta": {
"created_at": "2023-11-07T05:31:56Z",
"last_seen_at": "2023-11-07T05:31:56Z"
}
},
"jsonapi": {
"version": "1.0"
}
}{
"id": "98ca4a78-b66f-4234-9719-aaf832ee6669",
"status": "400",
"title": "A validation error was encountered",
"source": {
"parameter": "include"
},
"meta": {
"resource": "wrong_value"
}
}{
"id": "05fc9c8d-73b9-4697-9337-57f7a567a48f",
"status": "401",
"title": "You are not authorised to access this resource",
"detail": "In order to access this resource, you need the 'admin' role.",
"code": "AUTH.001"
}{
"id": "fe9d9a69-f0a7-4fdc-bb2c-176027f316c5",
"status": "500",
"title": "Internal Server Error",
"detail": "An unexpected error occurred on the server."
}Authorizations
Body
The device to send push notifications to.
Response
A push token.