# Notifications

> Source: https://truto.one/docs/guides/observability/notifications/

Add a notification destination and Truto posts to a Slack channel or sends email when your API traffic starts failing, an API token expires or goes stale, a webhook is deactivated, or the monthly usage report is ready.

:::skip-reading{cli="truto notification-destinations list" skill="truto"}
:::

## Before you start

- **One environment per destination.** A destination belongs to one environment and is notified about that environment only. With an API token, the destination is created in the token's environment.
- **Slack.** Create a Slack [incoming webhook](https://slack.com/marketplace/A0F7XDUAZ-incoming-webhooks) for the channel you want alerts in and copy its URL.

## 1. Add a destination

### From the console

1. Open **Settings → Notifications** (`app.truto.one/settings/notifications`) and pick the environment.
2. Click **Add Destination**.
3. Fill in the modal:
   - **Label** — a name for the destination, for example `Engineering alerts`.
   - **Type** — **Slack** or **Email**. The type can't be changed after the destination is created.
   - For Slack: **Webhook URL**, and optionally **Ignored Status Codes** (see [API errors](#event-types)).
   - For email: **To**, and optionally **CC**, **BCC**, and **Subject Prefix**. Separate addresses with commas.
   - **Active** — whether the destination receives notifications.
   - **Event Types** — which events to receive. **All events** is checked by default.
4. Click **Create**.

### From the API

`POST /notification-destination` creates a destination.

| Field | Type | Meaning |
| --- | --- | --- |
| `type` | string | `slack` or `email`. Required. |
| `config` | object | The type's settings. Required. See below. |
| `label` | string | Name for the destination. |
| `event_types` | string[] | Events to receive. Omitted or empty means `["all"]`. See [Event types](#event-types). |
| `is_active` | boolean | Whether the destination receives notifications. Defaults to `true`. |

**Slack `config`**

| Field | Required | Meaning |
| --- | --- | --- |
| `webhook_url` | Yes | The Slack incoming webhook URL. Write-only: reads return `********`. |
| `ignored_status_codes` | No | HTTP status codes (`400`–`599`) to leave out of [API errors](#event-types) digests, for example `[401, 404]`. |

**Email `config`**

| Field | Required | Meaning |
| --- | --- | --- |
| `to` | Yes | Recipient addresses. |
| `cc` | No | CC addresses. |
| `bcc` | No | BCC addresses. |
| `subject_prefix` | No | Put in front of every subject line. Defaults to `[Truto]`. |

:::code-tabs

```bash label="cURL"
curl -X POST https://api.truto.one/notification-destination \
  -H "Authorization: Bearer <API token>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "slack",
    "label": "Engineering alerts",
    "config": {
      "webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX",
      "ignored_status_codes": [401, 404]
    },
    "event_types": ["api_errors", "api_token_events"]
  }'
```

```bash label="CLI"
truto notification-destinations create --body '{
  "type": "slack",
  "label": "Engineering alerts",
  "config": {
    "webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX",
    "ignored_status_codes": [401, 404]
  },
  "event_types": ["api_errors", "api_token_events"]
}'
```

:::

```json
{
  "id": "3b7e2c1a-9f4d-4e8b-a2c6-1d5f7e9a0b34",
  "type": "slack",
  "label": "Engineering alerts",
  "config": {
    "webhook_url": "********",
    "ignored_status_codes": [401, 404]
  },
  "is_active": true,
  "environment_id": "ac15abdc-b38e-47d0-97a2-69194017c199",
  "event_types": ["api_errors", "api_token_events"],
  "created_at": "2026-11-02T10:20:11.000Z",
  "updated_at": "2026-11-02T10:20:11.000Z"
}
```

An email destination looks like this:

```json
{
  "type": "email",
  "label": "On-call inbox",
  "config": {
    "to": ["oncall@example.com"],
    "cc": ["platform@example.com"],
    "subject_prefix": "[Truto prod]"
  },
  "event_types": ["all"]
}
```

## 2. Send a test notification

`POST /notification-destination/test` sends a test message to one destination, whatever event types it subscribes to. In the console, open the destination's menu and click **Send test notification**.

:::code-tabs

```bash label="cURL"
curl -X POST https://api.truto.one/notification-destination/test \
  -H "Authorization: Bearer <API token>" \
  -H "Content-Type: application/json" \
  -d '{ "id": "<destination_id>" }'
```

```bash label="CLI"
truto notification-destinations test --id <destination_id>
```

:::

The endpoint answers `{"success": true}` once the test has been sent. It doesn't report whether Slack or the mail server accepted it, so check the channel or inbox. In Slack the message reads `Event: test` with the environment and time; by email the subject is `[Truto] Test Notification` (or your prefix).

## Event types

| Value | Console label | When it's sent |
| --- | --- | --- |
| `all` | All events | Every event below. |
| `api_errors` | API errors | A digest of the environment's failed requests from the past 24 hours: Truto API responses with a `4xx` or `5xx` status (except `429`) and sync job run errors, grouped by integrated account, integration and status code, up to 200 rows. A pair of account and status code that was already reported in the last 48 hours is left out. When there were no errors, the digest says so. |
| `api_token_events` | API token events | An API token in the environment expired and was deleted; the message names the token, the environment and who created it. Also a daily digest of active tokens with no use in the last 30 days, with a link to review them in **Settings → API Tokens**. |
| `api_usage` | API usage report | Monthly, on the 1st: the environment's API calls for the previous calendar month, with the top integrated accounts, integrations and tenants. Not sent for a month with no calls. |
| `webhook_deactivated` | Webhook deactivated | Truto deactivated one of your webhooks. The message names the webhook ID, target URL, environment and event types. |

`ignored_status_codes` applies to the `api_errors` digest. The codes from every Slack destination subscribed to API errors in the environment are combined, so ignoring a code on one destination removes it from the environment's digest for all of them.

:::callout{type="info"}
When someone joins your team as an admin, or is made an admin, Truto subscribes them to `api_token_events` by email in every environment whose name contains `production`. It creates one email destination per admin and environment, labelled `auto:api-token-alerts:<user id>`. Edit or delete it like any other destination.
:::

## Changing a destination

`PATCH /notification-destination/:id` updates a destination. `DELETE /notification-destination/:id` deletes it. `GET /notification-destination` lists the environment's destinations and `GET /notification-destination/:id` reads one.

- `config` replaces the stored config, except the secret fields: a Slack `webhook_url`, or email `to`, `cc` and `bcc`. A secret you leave out, or send back as `********`, is kept. Send `null` to clear one.
- `event_types` replaces the subscribed list when it has at least one entry. An empty list leaves the subscriptions unchanged; send `["all"]` to receive everything again.
- `is_active: false` pauses the destination without deleting it.

:::code-tabs

```bash label="cURL"
curl -X PATCH https://api.truto.one/notification-destination/<destination_id> \
  -H "Authorization: Bearer <API token>" \
  -H "Content-Type: application/json" \
  -d '{ "event_types": ["all"], "config": { "ignored_status_codes": [] } }'
```

```bash label="CLI"
truto notification-destinations update <destination_id> \
  --body '{"event_types":["all"],"config":{"ignored_status_codes":[]}}'
```

:::

## Next

Notifications summarise; for every individual request and sync job event, stream the raw logs to Datadog, Splunk or another tool with [Log forwarding](/docs/guides/observability/log-forwarding). To be told about events in your own app rather than in Slack, use [webhooks](/docs/guides/webhooks/creating-a-webhook-through-api).
