Mobile Push Tokens
Register and remove iOS push tokens bound to mobile API key identities.
Mobile Push Tokens API
These endpoints are available only when using a mobile-scoped API key.
The mobile identity is derived from the API-key context. A caller cannot select another user by query parameter or request body.
List notifications
mobile_notifications:readPath, query, and header parameters
pagesizestatustypesourceResponses
Notifications for the mobile user bound to the key.
{
"status": "fetch",
"page": 1,
"size": 20,
"count": 1,
"max_pages": 1,
"unread_count": 1,
"elements": [
{
"id": "NOTIFICATION_ID",
"status": "unread",
"type": "billing"
}
]
}Key is not mobile-scoped or its user is no longer enabled.
{
"error": "Mobile API key required for this endpoint"
}Request examples
curl --request GET 'https://api.hub.donutwork.com/2026-02-01/mobile/notifications.json' \
--header 'Authorization: Bearer YOUR_API_KEY'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/mobile/notifications.json', {
method: 'GET',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
},
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/mobile/notifications.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
],
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Mark a notification as read
mobile_notifications:writePath, query, and header parameters
notificationIdRequiredResponses
Notification marked read and current unread count returned.
{
"status": "success",
"notification_id": "NOTIFICATION_ID",
"unread_count": 0
}Notification is absent or does not belong to this mobile user.
{
"error": "Notification not found."
}Key is not valid for an enabled mobile user.
{
"error": "Mobile API key required for this endpoint"
}Request examples
curl --request POST 'https://api.hub.donutwork.com/2026-02-01/mobile/notifications/NOTIFICATIONID/read.json' \
--header 'Authorization: Bearer YOUR_API_KEY'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/mobile/notifications/NOTIFICATIONID/read.json', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
},
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/mobile/notifications/NOTIFICATIONID/read.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
],
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Save Device Push Token
mobile_push:writePath, query, and header parameters
No path, query, or additional header parameters.
Request Body
{
"device": {
"device_id": "ios_device_001",
"push_token": "f6ad7d6f0a3b82d91fd89e88d4d4c6f3e0f9a7f6",
"platform": "ios",
"app_version": "1.2.3",
"environment": "production"
}
}device.device_idRequireddevice.push_tokenRequireddevice.platformdevice.app_versiondevice.environmentResponses
Push token saved or updated.
{
"status": "success",
"message": "Push token saved",
"device": {
"device_id": "ios_device_001",
"platform": "ios",
"environment": "production"
}
}API key is not mobile-scoped.
{
"error": "Mobile API key required for this endpoint"
}Request examples
curl --request POST 'https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"device": {
"device_id": "ios_device_001",
"push_token": "f6ad7d6f0a3b82d91fd89e88d4d4c6f3e0f9a7f6",
"platform": "ios",
"app_version": "1.2.3",
"environment": "production"
}
}'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"device": {
"device_id": "ios_device_001",
"push_token": "f6ad7d6f0a3b82d91fd89e88d4d4c6f3e0f9a7f6",
"platform": "ios",
"app_version": "1.2.3",
"environment": "production"
}
}),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{
"device": {
"device_id": "ios_device_001",
"push_token": "f6ad7d6f0a3b82d91fd89e88d4d4c6f3e0f9a7f6",
"platform": "ios",
"app_version": "1.2.3",
"environment": "production"
}
}',
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Delete Device Push Token
mobile_push:writePath, query, and header parameters
device_idRequest Body
{
"device": {
"device_id": "ios_device_001"
}
}device.device_idResponses
Push token deleted or already absent.
{
"status": "success",
"message": "Push token removed",
"deleted": true,
"device_id": "ios_device_001"
}Device identifier missing or invalid.
{
"error": "Missing required field: device_id"
}Request examples
curl --request DELETE 'https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"device": {
"device_id": "ios_device_001"
}
}'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json', {
method: 'DELETE',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"device": {
"device_id": "ios_device_001"
}
}),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/mobile/push-token.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{
"device": {
"device_id": "ios_device_001"
}
}',
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.