curl --request GET \
--url https://{host}/v1/me/notifications \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/v1/me/notifications', 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://{host}/v1/me/notifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://{host}/v1/me/notifications"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": [
{
"type": "notifications",
"id": "9f1c2b7e-4a3d-4f11-8c2a-1b6d5e0f7a92",
"attributes": {
"category": "offers",
"event": "proposal_received",
"title": "€ 12.000 for Submariner Date",
"body": "Amsterdam Watch Co sent you a price. It stands for 48 hours.",
"route": {
"type": "offers",
"event": "proposal_received",
"notificationId": "9f1c2b7e-4a3d-4f11-8c2a-1b6d5e0f7a92",
"conversationId": "16916",
"messageId": "71405",
"watchId": "223897"
},
"unread": true,
"createdAt": "2026-09-26T05:41:12.000000Z",
"readAt": null
}
},
{
"type": "notifications",
"id": "2d8a44c1-9e57-4a02-b3cf-70f1c9d2e845",
"attributes": {
"category": "orders",
"event": "order_shipped",
"title": "Your watch is on its way",
"body": "Order 202600123 has been shipped.",
"route": {
"type": "orders",
"event": "order_shipped",
"notificationId": "2d8a44c1-9e57-4a02-b3cf-70f1c9d2e845",
"orderId": "7921",
"watchId": "222815"
},
"unread": false,
"createdAt": "2026-09-25T13:02:44.000000Z",
"readAt": "2026-09-25T13:40:10.000000Z"
}
}
],
"meta": {
"page": {
"perPage": 25,
"hasMore": false
},
"unread": 1
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}List notifications
Scope: account:read
What the bell on the home screen opens: everything this person has been told, newest
first, cursor-paged. meta.unread is how many are waiting across the whole list rather
than this page, and it is the same number the app icon’s badge carries.
A push is not a record of anything. It arrives or it does not — the phone was off, permission was never granted, the token had gone stale — so this is what keeps. Draw the bell from here, not from what the device happened to receive.
title and body are built when you read them, not when they were sent: they come
back in the language of your Accept-Language. Somebody who switches the app to German
sees last month’s notifications in German. Do not cache them as if they were the record;
event and route are the stable parts.
Route on event and route, never on the words. route.type is the category and the
rest are ids — exactly what the push payload carries, so one routing rule serves both.
The keys, in full: type (the category), event (what happened — the same as the
attribute), notificationId (this entry, so opening a push can mark the right item
read), conversationId, messageId, watchId, orderId, searchId, sellerId. Every
event and the ids it carries are listed in the devices guide, under “What arrives”. Only
the ones an event needs are present, so read them with a default rather than expecting a
shape per event.
searchId, not savedSearchId — the resource is saved-searches and the key is
searchId, which is a wart and a settled one. Naming it after the resource would be
tidier and would mean two names in the wild for a while, which is worse.
filter[unread]=true for what is still waiting, false for what was already read.
curl --request GET \
--url https://{host}/v1/me/notifications \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/v1/me/notifications', 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://{host}/v1/me/notifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://{host}/v1/me/notifications"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"data": [
{
"type": "notifications",
"id": "9f1c2b7e-4a3d-4f11-8c2a-1b6d5e0f7a92",
"attributes": {
"category": "offers",
"event": "proposal_received",
"title": "€ 12.000 for Submariner Date",
"body": "Amsterdam Watch Co sent you a price. It stands for 48 hours.",
"route": {
"type": "offers",
"event": "proposal_received",
"notificationId": "9f1c2b7e-4a3d-4f11-8c2a-1b6d5e0f7a92",
"conversationId": "16916",
"messageId": "71405",
"watchId": "223897"
},
"unread": true,
"createdAt": "2026-09-26T05:41:12.000000Z",
"readAt": null
}
},
{
"type": "notifications",
"id": "2d8a44c1-9e57-4a02-b3cf-70f1c9d2e845",
"attributes": {
"category": "orders",
"event": "order_shipped",
"title": "Your watch is on its way",
"body": "Order 202600123 has been shipped.",
"route": {
"type": "orders",
"event": "order_shipped",
"notificationId": "2d8a44c1-9e57-4a02-b3cf-70f1c9d2e845",
"orderId": "7921",
"watchId": "222815"
},
"unread": false,
"createdAt": "2026-09-25T13:02:44.000000Z",
"readAt": "2026-09-25T13:40:10.000000Z"
}
}
],
"meta": {
"page": {
"perPage": 25,
"hasMore": false
},
"unread": 1
}
}{
"errors": [
{
"status": "404",
"code": "watch_reserved",
"title": "Not Found",
"detail": "<string>",
"meta": {},
"source": {
"pointer": "/data/attributes/reference",
"parameter": "<string>"
}
}
],
"jsonapi": {
"version": "1.0"
}
}Authorizations
Query Parameters
Response
A page of notifications, with meta.unread beside it.