# Get notifications

> GET /v1/notifications · Settings and configurations API

Source: https://developer.kustomer.com/api/settings-and-configurations/get-notifications

```http
GET https://{orgname}.api.kustomerapp.com/v1/notifications
Authorization: Bearer <API key>
```

## Authorization

Any API key or signed-in user. No specific role is required; any valid credential works.

Retrieves all user in-app notifications.

## About Notifications

Notifications are the alerts Kustomer sends a user about activity they care about, such as a conversation being assigned to them or a teammate mentioning them in a note. Each user chooses which events notify them in the app and by email, and admins choose who receives org-wide alerts about problems such as a disconnected channel.

When something happens in Kustomer that a user has asked to hear about, Kustomer creates an in-app notification for that user, sends an email, or both. In-app notifications appear in the notifications list in the agent desktop. Each one belongs to a single user, starts as `unread`, and is removed automatically after seven days. These endpoints always act on the signed-in user: an API key sees the notifications of its own user, not everyone's.

#### In-app notifications

Each notification has a `name`, the event that triggered it (such as `kustomer.conversation.firstmessagein`), a `status` of `read` or `unread`, and `event`, a copy of the event with the object it is about, such as the message and links to its conversation and customer. The list is newest first and paginated with `page` and `pageSize`. `meta.unread` gives the number of unread notifications, which is handy for a badge. A user is never notified twice about the same event for the same reason.

#### Notification preferences

Each user has one preferences record with an entry per notification type, such as `notify_kustomer_conversation_assign`, `notify_kustomer_note_mention` or `notify_kustomer_conversation_unsnooze`. Each entry sets two channels:

| Channel | Values |
| --- | --- |
| `web` | `always` or `never`: whether to show an in-app notification. |
| `email` | `always`, `loggedout` (only while the user is signed out of Kustomer) or `never`. |

Types ending in `_by_app`, such as `notify_kustomer_conversation_messagein_by_app`, hold the same pair for each channel app (for example `postmark` and `gmail` for email, `chat`, `facebook`, `twilio` for SMS, or `form`), so a user can, for example, hear about new chat messages but not new emails. A user who has never changed anything gets Kustomer's defaults: assignments and note mentions notify them, and new incoming messages don't.

#### Org alert recipients

Separate from personal preferences, the notifications logs settings hold one list per org: `emails`, up to five addresses that receive an email when Kustomer detects a problem that affects the whole org, such as a Facebook or Gmail connection failing to authenticate. If the list is empty, these alerts go to the org owner.

#### Which endpoint to use

| To | Call |
| --- | --- |
| List the signed-in user's notifications and unread count | [`GET /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications) |
| Mark all of them as read or unread | [`PUT /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/update-notifications) with `status` |
| Clear all of them | [`DELETE /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/delete-notifications) |
| Read or change the signed-in user's preferences | [`GET`](https://developer.kustomer.com/api/settings-and-configurations/get-notification-settings-for-current-user) or [`PUT /v1/notifications/users/current/settings`](https://developer.kustomer.com/api/settings-and-configurations/update-notification-settings-for-current-user) |
| Read or change who receives org alerts | [`GET`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications-logs-settings) or [`PUT /v1/notifications/logs/settings`](https://developer.kustomer.com/api/settings-and-configurations/update-notifications-logs-settings) |

`PUT /v1/notifications` and `DELETE /v1/notifications` act on every notification the user has, and both return `204` with no body. When you update preferences, send only the types you want to change; the others keep their current values. A `PUT` to the org alert settings replaces the whole `emails` list and requires an admin role with permission to manage settings.

Related: [Users](https://developer.kustomer.com/api/access-management#users), [Settings](https://developer.kustomer.com/api/settings-and-configurations#settings), [Event catalog](https://developer.kustomer.com/docs/events/event-catalog)

### Recipes

#### 1. Show an unread badge and mark everything read

Mirror a user's Kustomer notifications in another tool, such as an internal portal, with an unread count and a "mark all read" button.

**Step 1.** [`GET /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications.md). Read the unread count from `meta.unread`. These endpoints act on the user behind the token, so use credentials for the user whose notifications you're showing, such as an OAuth session from `kusty auth login`, not an integration's own API key.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/notifications?pageSize=1" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  | jq '.meta.unread'
```

**Step 2.** [`GET /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications.md). List the notifications, newest first, with the conversation each one is about. `name` says why the user was notified.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/notifications?pageSize=50" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/notifications --all \
  | jq -r '[.data.attributes.status, .data.attributes.name, .data.attributes.event.data.relationships.conversation.data.id] | @tsv'
```

**Step 3.** [`PUT /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/update-notifications.md). When the user clicks "mark all read", set every notification's `status` to `read`. The call returns `204` with no body and applies to all of the user's notifications; there's no way to mark just one.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/notifications" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"status": "read"}'
```

```bash title="kusty"
kusty api PUT /v1/notifications --field status=read
```

#### 2. Stop email for one kind of notification

Turn off emails about, for example, snoozed conversations waking up, while keeping the in-app alert.

**Step 1.** [`GET /v1/notifications/users/current/settings`](https://developer.kustomer.com/api/settings-and-configurations/get-notification-settings-for-current-user.md). Read the signed-in user's current preferences. A notification's `name` maps to a preference key by adding `notify_` and replacing dots with underscores, so `kustomer.conversation.unsnooze` is `notify_kustomer_conversation_unsnooze`.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/notifications/users/current/settings" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/notifications/users/current/settings \
  --fields attributes.notify_kustomer_conversation_unsnooze
```

**Step 2.** [`PUT /v1/notifications/users/current/settings`](https://developer.kustomer.com/api/settings-and-configurations/update-notification-settings-for-current-user.md). Send only the type you're changing, with both `web` and `email`; the other types keep their values. `loggedout` instead of `never` would email the user only while they're signed out.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/notifications/users/current/settings" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"notify_kustomer_conversation_unsnooze": {"web": "always", "email": "never"}}'
```

```bash title="kusty"
kusty api PUT /v1/notifications/users/current/settings \
  --field notify_kustomer_conversation_unsnooze.web=always \
  --field notify_kustomer_conversation_unsnooze.email=never
```

> Types ending in `_by_app` hold a `web` and `email` pair for each channel app instead of a single pair. Read the current value first and send back the whole object with your change.

#### 3. Send org alerts to an on-call mailbox

Make sure problems that affect the whole org, such as a channel connection failing, reach the team that can fix them and not only the org owner.

**Step 1.** [`GET /v1/notifications/logs/settings`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications-logs-settings.md). Read the current recipients. An empty list means alerts go to the org owner.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/notifications/logs/settings" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/notifications/logs/settings | jq -c '.data.attributes.emails' > emails.json
```

**Step 2.** [`PUT /v1/notifications/logs/settings`](https://developer.kustomer.com/api/settings-and-configurations/update-notifications-logs-settings.md). Send the complete list with the new address added. The `PUT` replaces the whole list, so leaving out an existing address removes it, and the list can hold at most five addresses. Changing it needs an admin with permission to manage settings.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/notifications/logs/settings" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"emails": ["owner@example.com", "oncall@example.com"]}'
```

```bash title="kusty"
EMAILS=$(jq -c '. + ["oncall@example.com"] | unique' emails.json)
kusty api PUT /v1/notifications/logs/settings --field "emails:=$EMAILS"
```

### Example object

A real record from [`GET /v1/notifications`](https://developer.kustomer.com/api/settings-and-configurations/get-notifications.md):

```json
{
  "type": "notification",
  "id": "5dee39be295b55001a5e85b8",
  "attributes": {
    "name": "kustomer.conversation.firstmessagein",
    "status": "unread",
    "event": {
      "_meta": {
        "id": "5dee39be7358c5001a8f1456",
        "publishedAt": "2019-12-09T12:10:38.086Z"
      },
      "sourceType": "workflow",
      "sourceId": "57504f64da8d8b1c009defbd",
      "client": "workflow",
      "isSync": null,
      "persist": true,
      "changes": null,
      "createdAt": "2019-12-09T12:10:37.738Z",
      "data": {
        "links": {
          "related": "/v1/postmark/messages/5dee39bca0497287148fe688",
          "self": "/v1/messages/5dee39bca0497287148fe688"
        },
        "relationships": {
          "conversation": {
            "data": {
              "id": "5dee39bdc0551e001c01d3c3",
              "type": "conversation"
            },
            "links": {
              "self": "/v1/conversations/5dee39bdc0551e001c01d3c3"
            }
          },
          "customer": {
            "data": {
              "id": "59a984968859d10010ad88bb",
              "type": "customers"
            },
            "links": {
              "self": "/v1/customers/59a984968859d10010ad88bb"
            }
          },
          "redactedBy": null,
          "deletedBy": null,
          "modifiedBy": null,
          "createdBy": null,
          "org": {
            "data": {
              "id": "57504f64d76808100089eb44",
              "type": "org"
            },
            "links": {
              "self": "/v1/orgs/57504f64d76808100089eb44"
            }
          }
        },
        "attributes": {
          "firstCompany": null,
          "rev": 1,
          "lang": null,
          "source": null,
          "createdByTeams": [],
          "importedAt": null,
          "redacted": false,
          "redactedAt": null,
          "deletedAt": null,
          "deleted": null,
          "modifiedAt": null,
          "updatedAt": "2019-12-09T12:10:37.719Z",
          "createdAt": "2019-12-09T12:10:37.719Z",
          "sentAt": "2019-12-09T12:10:19.000Z",
          "auto": false,
          "errorAt": null,
          "error": null,
          "assignedUsers": [],
          "assignedTeams": [],
          "responseBusinessTime": null,
          "responseTime": null,
          "status": "received",
          "custom": null,
          "meta": {
            "recipient": {
              "mailboxHash": "",
              "email": "support@jeremy.mail.kustomerapp.com"
            },
            "cc": [],
            "to": [
              {
                "email": "support@jeremy.mail.kustomerapp.com"
              }
            ],
            "from": "jeremy@kustomer.com",
            "subject": "test"
          },
          "sentiment": null,
          "subject": null,
          "preview": "test\r\n\r\n-- \r\nJeremy Suriel\r\nCo-founder / CTO\r\nKustomer\r\n@jeremysuriel",
          "location": null,
          "directionType": "initial-in",
          "direction": "in",
          "size": 0,
          "app": "postmark",
          "channel": "email",
          "externalId": "<CADBFQxShzY9OCHYk4J5ms2U02F=ZdHjn4=ebgMXzAdrQsBf9tA@mail.gmail.com>"
        },
        "id": "5dee39bca0497287148fe688",
        "type": "message"
      },
      "orgName": null,
      "partition": "57504f64d76808100089eb44",
      "name": "kustomer.message.create",
      "id": "5dee39bdc0551e001c01d3ca",
      "org": "57504f64d76808100089eb44"
    },
    "createdAt": "2019-12-09T12:10:38.236Z",
    "updatedAt": "2019-12-09T12:10:38.236Z"
  },
  "relationships": {
    "org": {
      "data": {
        "type": "org",
        "id": "57504f64d76808100089eb44"
      },
      "links": {
        "self": "/v1/orgs/57504f64d76808100089eb44"
      }
    },
    "user": {
      "data": {
        "type": "user",
        "id": "57504f644c80120f00f3c378"
      },
      "links": {
        "self": "/v1/users/57504f644c80120f00f3c378"
      }
    }
  }
}
```

Fields:

- `attributes.name` (string): Why the user was notified, such as `kustomer.conversation.firstmessagein` or `kustomer.note.mention`. The matching preference is `notify_` plus the name with dots replaced by underscores, for example `notify_kustomer_note_mention`.
- `attributes.status` (string): `read` or `unread`. New notifications start `unread`. Through the API you can only change all of a user's notifications at once, with `PUT /v1/notifications`.
- `attributes.event` (object): A copy of the event that caused the notification, as it was at the time. Notifications are removed after seven days, so store anything you need from it.
- `attributes.event.createdAt` (string): When the event happened.
- `attributes.event.data` (object): The object the event is about, such as a message, in the same format the API returns it.
- `attributes.event.data.relationships.conversation` (object): The conversation the object belongs to, useful for linking the notification to it in your own tool.
- `attributes.event.data.relationships.customer` (object): The customer the object belongs to.
- `attributes.event.data.type` (string): The kind of object in `event.data`, such as `message`, `conversation` or `note`.
- `attributes.event.name` (string): The underlying event, such as `kustomer.message.create`. It's often more general than the notification's `name`, which says why this user in particular was told about it.
- `relationships.user` (object): The user the notification is for, which is always the user behind the token making the request.

### Relationships

- Points to **Users** via `relationships.user`: The user a notification is for. Each user only sees their own notifications and preferences, so read them with that user's credentials rather than an integration's API key.

### Permissions

Fewest roles for a read-only integration: `org.permission.notification.read`, `org.permission.setting.read`. For every endpoint: `org.permission.notification.delete`, `org.permission.notification.read`, `org.permission.setting.read`, `org.permission.setting.update`.

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | no | Page number of results to return. |
| `pageSize` | integer | no | Number of results to return per page. |

## Responses

### 200

OK

- `meta` (object, required)
  - `pageSize` (integer, required)
  - `page` (integer, required)
  - `total` (integer, required)
  - `totalPages` (integer, required)
  - `unread` (integer, required)
- `links` (object, required)
  - `self` (string, required)
  - `first` (string, required)
  - `prev` (string, required, nullable)
  - `next` (string, required, nullable)
  - `last` (string, required)
- `data` (array<object>, required)
  - `type` (string, required)
  - `id` (string, required)
  - `attributes` (object, required)
    - `name` (string, required)
    - `status` (string, required)
    - `event` (object, required)
    - `createdAt` (string, required)
    - `updatedAt` (string, required)
  - `relationships` (object, required)
    - `org` (object, required)
    - `user` (object, required)

```json
{
  "meta": {
    "pageSize": 100,
    "page": 1,
    "total": 1,
    "totalPages": 1,
    "unread": 1
  },
  "links": {
    "self": "/v1/notifications?page=1&pageSize=100&client-request-id=f46f2419-fabc-4b4f-8c5b-1e8aa9378e75",
    "first": "/v1/notifications?page=1&pageSize=100&client-request-id=f46f2419-fabc-4b4f-8c5b-1e8aa9378e75",
    "prev": null,
    "next": null,
    "last": "/v1/notifications?page=1&pageSize=100&client-request-id=f46f2419-fabc-4b4f-8c5b-1e8aa9378e75"
  },
  "data": [
    {
      "type": "notification",
      "id": "5dee39be295b55001a5e85b8",
      "attributes": {
        "name": "kustomer.conversation.firstmessagein",
        "status": "unread",
        "event": {
          "_meta": {
            "id": "5dee39be7358c5001a8f1456",
            "publishedAt": "2019-12-09T12:10:38.086Z"
          },
          "sourceType": "workflow",
          "sourceId": "57504f64da8d8b1c009defbd",
          "client": "workflow",
          "isSync": null,
          "persist": true,
          "changes": null,
          "createdAt": "2019-12-09T12:10:37.738Z",
          "data": {
            "links": {
              "related": "/v1/postmark/messages/5dee39bca0497287148fe688",
              "self": "/v1/messages/5dee39bca0497287148fe688"
            },
            "relationships": {
              "conversation": {
                "data": {
                  "id": "5dee39bdc0551e001c01d3c3",
                  "type": "conversation"
                },
                "links": {
                  "self": "/v1/conversations/5dee39bdc0551e001c01d3c3"
                }
              },
              "customer": {
                "data": {
                  "id": "59a984968859d10010ad88bb",
                  "type": "customers"
                },
                "links": {
                  "self": "/v1/customers/59a984968859d10010ad88bb"
                }
              },
              "redactedBy": null,
              "deletedBy": null,
              "modifiedBy": null,
              "createdBy": null,
              "org": {
                "data": {
                  "id": "57504f64d76808100089eb44",
                  "type": "org"
                },
                "links": {
                  "self": "/v1/orgs/57504f64d76808100089eb44"
                }
              }
            },
            "attributes": {
              "firstCompany": null,
              "rev": 1,
              "lang": null,
              "source": null,
              "createdByTeams": [],
              "importedAt": null,
              "redacted": false,
              "redactedAt": null,
              "deletedAt": null,
              "deleted": null,
              "modifiedAt": null,
              "updatedAt": "2019-12-09T12:10:37.719Z",
              "createdAt": "2019-12-09T12:10:37.719Z",
              "sentAt": "2019-12-09T12:10:19.000Z",
              "auto": false,
              "errorAt": null,
              "error": null,
              "assignedUsers": [],
              "assignedTeams": [],
              "responseBusinessTime": null,
              "responseTime": null,
              "status": "received",
              "custom": null,
              "meta": {
                "recipient": {
                  "mailboxHash": "",
                  "email": "support@jeremy.mail.kustomerapp.com"
                },
                "cc": [],
                "to": [
                  {
                    "email": "support@jeremy.mail.kustomerapp.com"
                  }
                ],
                "from": "jeremy@kustomer.com",
                "subject": "test"
              },
              "sentiment": null,
              "subject": null,
              "preview": "test\r\n\r\n-- \r\nJeremy Suriel\r\nCo-founder / CTO\r\nKustomer\r\n@jeremysuriel",
              "location": null,
              "directionType": "initial-in",
              "direction": "in",
              "size": 0,
              "app": "postmark",
              "channel": "email",
              "externalId": "<CADBFQxShzY9OCHYk4J5ms2U02F=ZdHjn4=ebgMXzAdrQsBf9tA@mail.gmail.com>"
            },
            "id": "5dee39bca0497287148fe688",
            "type": "message"
          },
          "orgName": null,
          "partition": "57504f64d76808100089eb44",
          "name": "kustomer.message.create",
          "id": "5dee39bdc0551e001c01d3ca",
          "org": "57504f64d76808100089eb44"
        },
        "createdAt": "2019-12-09T12:10:38.236Z",
        "updatedAt": "2019-12-09T12:10:38.236Z"
      },
      "relationships": {
        "org": {
          "data": {
            "type": "org",
            "id": "57504f64d76808100089eb44"
          },
          "links": {
            "self": "/v1/orgs/57504f64d76808100089eb44"
          }
        },
        "user": {
          "data": {
            "type": "user",
            "id": "57504f644c80120f00f3c378"
          },
          "links": {
            "self": "/v1/users/57504f644c80120f00f3c378"
          }
        }
      }
    }
  ]
}
```

### 401

Unauthorized

### 403

Forbidden

## Example request

```bash
curl --request GET \
  --url 'https://api.kustomerapp.com/v1/notifications' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```
