> For the complete documentation index, see [llms.txt](https://docs.api.intratool.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.api.intratool.de/api-reference/notifications.md).

# Notifications

## Introduction

`Notifications` are user-specific records produced by resources with the [Notifications capability](/introduction/resource-capabilities/notifications.md). Each record identifies its recipient, optional target resource, display payload, and seen/read state.

`NotificationSettings` are selectable delivery categories that departments and supported resources can reference. Global trigger and retention behavior is managed through the administration settings endpoints on this page.

The `data.body` field and the `body` of a generic notification use the shared [Rich Text](/introduction/rich-text.md) HTML format.

## Model Definition

**Relations**

| Key          | Relation                            | Type     | Relation Field(s)                  |
| ------------ | ----------------------------------- | -------- | ---------------------------------- |
| `notifiable` | [User](/api-reference/users.md)     | Morph to | `notifiable_type`, `notifiable_id` |
| `targetable` | Resource producing the notification | Morph to | `targetable_type`, `targetable_id` |

`data` contains `title`, `body`, and `url`. Notification type and targetable aliases depend on the producing resource; use the values returned by the API instead of inferring support from an arbitrary polymorphic relation.

## List

List visible `Notifications` for the current authenticated user.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notifications`

**Request Keys**

| Key         | Type      | Default           | Description                                       |
| ----------- | --------- | ----------------- | ------------------------------------------------- |
| `selects`   | `string`  | All fields        | Comma-separated fields to return.                 |
| `relations` | `string`  | Default relations | Pipe-separated relations to include.              |
| `limit`     | `integer` | No limit          | Maximum number of notifications.                  |
| `filter`    | `object`  | No filters        | Filters, for example unread or notification type. |

**Behavior**

Only notifications belonging to the authenticated user are returned.

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notifications', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
[
  {
    "id": "017b276f-65f9-4d00-9789-aa6aa0967203",
    "type": "infoboardPostCreated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 850,
    "data": {
      "title": "New infoboard post by Alex Rivera",
      "body": "<p>Quarterly planning update.</p>",
      "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
    },
    "seen_at": null,
    "read_at": null,
    "created_at": "2026-08-06 09:00:00",
    "updated_at": "2026-08-06 09:00:00"
  },
  {
    "id": "74da02d3-465d-4e96-8d88-5f0ce89f8398",
    "type": "manualEntryUpdated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "manualEntry",
    "targetable_id": 58,
    "data": {
      "title": "Manual entry updated by Morgan Chen",
      "body": "<p>Customer escalation process.</p>",
      "url": "/handbuch/eintrag/j7x2q9m4"
    },
    "seen_at": "2026-08-06 09:30:00",
    "read_at": "2026-08-06 09:35:00",
    "created_at": "2026-08-06 09:20:00",
    "updated_at": "2026-08-06 09:35:00"
  }
]
```

## Count

Count unread `Notifications` for the current authenticated user.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notifications/count`

**Request Keys**

| Key      | Type     | Default    | Description                                                             |
| -------- | -------- | ---------- | ----------------------------------------------------------------------- |
| `filter` | `object` | No filters | Filters applied before counting the authenticated user's notifications. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notifications/count', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'query' => ['filter' => ['read_at' => null]]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
2
```

## List by Targetable Type

List visible `Notifications` for one targetable type.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notifications/type/{targetableType}`

**Route Parameters**

| Parameter        | Type     | Description            |
| ---------------- | -------- | ---------------------- |
| `targetableType` | `string` | Target resource alias. |

**Request Keys**

| Key       | Type      | Default    | Description                       |
| --------- | --------- | ---------- | --------------------------------- |
| `selects` | `string`  | All fields | Comma-separated fields to return. |
| `limit`   | `integer` | No limit   | Maximum number of notifications.  |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notifications/type/infoboardPost', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
[
  {
    "id": "017b276f-65f9-4d00-9789-aa6aa0967203",
    "type": "infoboardPostCreated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 850,
    "data": {
      "title": "New infoboard post by Alex Rivera",
      "body": "<p>Quarterly planning update.</p>",
      "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
    },
    "seen_at": null,
    "read_at": null,
    "created_at": "2026-08-06 09:00:00",
    "updated_at": "2026-08-06 09:00:00"
  },
  {
    "id": "c72410ca-69de-4ed0-a1db-cfa166290a10",
    "type": "infoboardPostUpdated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 851,
    "data": {
      "title": "Infoboard post updated by Morgan Chen",
      "body": "<p>Office relocation schedule.</p>",
      "url": "/infoboard/eintrag/7j35kx92m8a4"
    },
    "seen_at": "2026-08-06 09:40:00",
    "read_at": null,
    "created_at": "2026-08-06 09:25:00",
    "updated_at": "2026-08-06 09:40:00"
  }
]
```

## List by Targetable

List visible `Notifications` for one targetable entity.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notifications/type/{targetableType}/{targetableId}`

**Route Parameters**

| Parameter        | Type             | Description            |
| ---------------- | ---------------- | ---------------------- |
| `targetableType` | `string`         | Target resource alias. |
| `targetableId`   | `string/integer` | Target resource ID.    |

**Request Keys**

| Key       | Type     | Default    | Description                       |
| --------- | -------- | ---------- | --------------------------------- |
| `selects` | `string` | All fields | Comma-separated fields to return. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notifications/type/infoboardPost/850', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
[
  {
    "id": "017b276f-65f9-4d00-9789-aa6aa0967203",
    "type": "infoboardPostCreated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 850,
    "data": {
      "title": "New infoboard post by Alex Rivera",
      "body": "<p>Quarterly planning update.</p>",
      "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
    },
    "seen_at": null,
    "read_at": null,
    "created_at": "2026-08-06 09:00:00",
    "updated_at": "2026-08-06 09:00:00"
  },
  {
    "id": "1149091d-dc31-4730-88da-6fc4c5f3cf02",
    "type": "infoboardPostReadingConfirmationRequired",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 850,
    "data": {
      "title": "Reading confirmation required",
      "body": "<p>Quarterly planning update.</p>",
      "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
    },
    "seen_at": "2026-08-06 09:45:00",
    "read_at": null,
    "created_at": "2026-08-06 09:10:00",
    "updated_at": "2026-08-06 09:45:00"
  }
]
```

## Show

Show one visible `Notification`.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notifications/{notification}`

**Route Parameters**

| Parameter      | Type   | Description                                          |
| -------------- | ------ | ---------------------------------------------------- |
| `notification` | `UUID` | Notification ID belonging to the authenticated user. |

**Request Keys**

| Key         | Type     | Default           | Description                          |
| ----------- | -------- | ----------------- | ------------------------------------ |
| `selects`   | `string` | All fields        | Comma-separated fields to return.    |
| `relations` | `string` | Default relations | Pipe-separated relations to include. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notifications/017b276f-65f9-4d00-9789-aa6aa0967203', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "id": "017b276f-65f9-4d00-9789-aa6aa0967203",
  "type": "infoboardPostCreated",
  "notifiable_type": "user",
  "notifiable_id": 7,
  "targetable_type": "infoboardPost",
  "targetable_id": 850,
  "data": {
    "title": "New infoboard post by Alex Rivera",
    "body": "<p>Quarterly planning update.</p>",
    "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
  },
  "seen_at": null,
  "read_at": null,
  "created_at": "2026-08-06 09:00:00",
  "updated_at": "2026-08-06 09:00:00"
}
```

## Create Generic Notifications

Create generic `Notifications` for selected users.

**Definition**

<mark style="color:yellow;">`POST`</mark> `/api/notifications`

**Request Keys**

| Key              | Type        | Default | Description                                                                             |
| ---------------- | ----------- | ------- | --------------------------------------------------------------------------------------- |
| `title`\*        | `string`    | -       | Display title.                                                                          |
| `body`\*         | `string`    | -       | HTML body.                                                                              |
| `url`\*          | `string`    | -       | Destination URL.                                                                        |
| `department_ids` | `integer[]` | -       | Existing departments whose users receive the notification. Required without `user_ids`. |
| `user_ids`       | `integer[]` | -       | Existing direct recipients. Required without `department_ids`.                          |

Keys with `*` are required.

**Behavior**

Department members and direct users are merged and de-duplicated. Delivery runs asynchronously, so the endpoint confirms dispatch but does not return the generated per-user records.

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('POST', '/api/notifications', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'json' => [
        'title' => 'Maintenance completed',
        'body' => '<p>All services are available again.</p>',
        'url' => '/status/maintenance-2026-08-06',
        'department_ids' => [6, 9],
        'user_ids' => [7, 19]
    ]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": null
}
```

## Update Unread for Current User

Update unread `Notifications` for the current authenticated user.

**Definition**

<mark style="color:blue;">`PUT`</mark> `/api/notifications`

**Request Keys**

| Key       | Type       | Default    | Description                                                       |
| --------- | ---------- | ---------- | ----------------------------------------------------------------- |
| `seen_at` | `datetime` | -          | Required without `read_at`.                                       |
| `read_at` | `datetime` | -          | Required without `seen_at`; also supplies `seen_at` when omitted. |
| `filter`  | `object`   | No filters | Optional filters applied before updating unread records.          |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('PUT', '/api/notifications', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'json' => ['read_at' => '2026-08-06 11:00:00']
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": 2
}
```

## Update by Targetable Type

Update `Notifications` for one targetable type.

**Definition**

<mark style="color:blue;">`PUT`</mark> `/api/notifications/type/{targetableType}`

**Route Parameters**

| Parameter        | Type     | Description            |
| ---------------- | -------- | ---------------------- |
| `targetableType` | `string` | Target resource alias. |

**Request Keys**

| Key       | Type       | Default | Description                                                       |
| --------- | ---------- | ------- | ----------------------------------------------------------------- |
| `seen_at` | `datetime` | -       | Required without `read_at`.                                       |
| `read_at` | `datetime` | -       | Required without `seen_at`; also supplies `seen_at` when omitted. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('PUT', '/api/notifications/type/infoboardPost', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'json' => ['seen_at' => '2026-08-06 11:05:00']
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": 2
}
```

## Update by Targetable

Update `Notifications` for one targetable entity.

**Definition**

<mark style="color:blue;">`PUT`</mark> `/api/notifications/type/{targetableType}/{targetableId}`

**Route Parameters**

| Parameter        | Type             | Description            |
| ---------------- | ---------------- | ---------------------- |
| `targetableType` | `string`         | Target resource alias. |
| `targetableId`   | `string/integer` | Target resource ID.    |

**Request Keys**

| Key       | Type       | Default | Description                                                       |
| --------- | ---------- | ------- | ----------------------------------------------------------------- |
| `seen_at` | `datetime` | -       | Required without `read_at`.                                       |
| `read_at` | `datetime` | -       | Required without `seen_at`; also supplies `seen_at` when omitted. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('PUT', '/api/notifications/type/infoboardPost/850', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'json' => ['read_at' => '2026-08-06 11:10:00']
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": 2
}
```

## Update

Update one existing `Notification`.

**Definition**

<mark style="color:blue;">`PUT`</mark> `/api/notifications/{notification}`

**Route Parameters**

| Parameter      | Type   | Description                                          |
| -------------- | ------ | ---------------------------------------------------- |
| `notification` | `UUID` | Notification ID belonging to the authenticated user. |

**Request Keys**

| Key       | Type       | Default | Description                                                       |
| --------- | ---------- | ------- | ----------------------------------------------------------------- |
| `seen_at` | `datetime` | -       | Required without `read_at`.                                       |
| `read_at` | `datetime` | -       | Required without `seen_at`; also supplies `seen_at` when omitted. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('PUT', '/api/notifications/017b276f-65f9-4d00-9789-aa6aa0967203', [
    'headers' => ['Authorization' => "Bearer {accessToken}"],
    'json' => ['read_at' => '2026-08-06 11:15:00']
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": {
    "id": "017b276f-65f9-4d00-9789-aa6aa0967203",
    "type": "infoboardPostCreated",
    "notifiable_type": "user",
    "notifiable_id": 7,
    "targetable_type": "infoboardPost",
    "targetable_id": 850,
    "data": {
      "title": "New infoboard post by Alex Rivera",
      "body": "<p>Quarterly planning update.</p>",
      "url": "/infoboard/eintrag/kn978r25g376561dqwzem4px"
    },
    "seen_at": "2026-08-06 11:15:00",
    "read_at": "2026-08-06 11:15:00",
    "created_at": "2026-08-06 09:00:00",
    "updated_at": "2026-08-06 11:15:00"
  }
}
```

## List NotificationSettings

List available `NotificationSettings`.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notification-settings`

**Request Keys**

| Key         | Type     | Default           | Description                          |
| ----------- | -------- | ----------------- | ------------------------------------ |
| `selects`   | `string` | All fields        | Comma-separated fields to return.    |
| `relations` | `string` | Default relations | Pipe-separated relations to include. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notification-settings', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
[
  {
    "id": 14,
    "key": "infoboard_post_created",
    "sort_number": 1
  },
  {
    "id": 18,
    "key": "manual_entry_updated",
    "sort_number": 5
  }
]
```

## Show NotificationSetting

Show one `NotificationSetting`.

**Definition**

<mark style="color:green;">`GET`</mark> `/api/notification-settings/{notificationSetting}`

**Route Parameters**

| Parameter             | Type      | Description             |
| --------------------- | --------- | ----------------------- |
| `notificationSetting` | `integer` | NotificationSetting ID. |

**Request Keys**

| Key         | Type     | Default           | Description                          |
| ----------- | -------- | ----------------- | ------------------------------------ |
| `selects`   | `string` | All fields        | Comma-separated fields to return.    |
| `relations` | `string` | Default relations | Pipe-separated relations to include. |

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('GET', '/api/notification-settings/14', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "id": 14,
  "key": "infoboard_post_created",
  "sort_number": 1
}
```

## Admin: Reset

Reset `Notifications` in administration scope.

**Definition**

<mark style="color:red;">`DELETE`</mark> `/api/administration/notifications/reset`

**Behavior**

This permanently deletes every stored notification for the tenant. Notification settings are not changed.

**Example Request**

{% tabs %}
{% tab title="PHP" %}

```php
$client = new GuzzleHttp\Client(['base_uri' => 'https://{tenant}.intratool.de']);
$response = $client->request('DELETE', '/api/administration/notifications/reset', [
    'headers' => ['Authorization' => "Bearer {accessToken}"]
]);
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "status": "success",
  "data": null
}
```
