# Alert settings tools

> MCP tools for Alert settings: alert_settings_get, alert_settings_slack_channels_create, alert_settings_slack_channels_delete, alert_settings_slack_channels_test, alert_settings_update.

- `alert_settings_get`: Get the alert settings
- `alert_settings_slack_channels_create`: Slack alerts: add a channel
- `alert_settings_slack_channels_delete`: Slack alerts: remove a channel
- `alert_settings_slack_channels_test`: Slack alerts: send a test message
- `alert_settings_update`: Update the alert settings

## `alert_settings_get`

**Get the alert settings.** Operation [`alert_settings.get`](https://ownrecord.io/docs/reference/alert-settings-get.md) · Organization level · permission `org:read` · risk tier `read` · since M7

Returns how the organization's alerts are delivered in the mode of the request. Every alert is in the
console inbox. Critical alerts are always emailed to the members whose role handles them (e.g. tax managers
and owners for registration alerts) and posted to every Slack channel; `email.high` says whether high alerts
are emailed too (`immediate`, the default, or `off`), and each Slack channel's `minSeverity` whether it gets
high alerts. Info alerts stay in the inbox.

Slack channels show their name and a hint of the webhook URL; the URL itself is never shown again.

Annotations: `readOnlyHint: true` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Arguments

This tool takes no arguments.

- **Read-only:** changes nothing; `idempotency_key` is ignored.

### Errors

- [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied): You can't read this organization's settings.

### Example

**High alerts emailed, one Slack channel**

Arguments:

```json
{}
```

Result `output`:

```json
{
  "object": "alert_settings",
  "livemode": true,
  "email": {
    "high": "immediate"
  },
  "slackChannels": [
    {
      "id": "sec_01m4ttwd3veh9apbewxheq5xad",
      "object": "slack_channel",
      "name": "#tax-alerts",
      "urlHint": "hooks.slack.com …x7Qa",
      "minSeverity": "high",
      "createdAt": "2026-10-13T12:00:00.000Z",
      "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "lastTest": null
    }
  ],
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "version": 2
}
```

## `alert_settings_slack_channels_create`

**Slack alerts: add a channel.** Operation [`alert_settings.slack_channels.create`](https://ownrecord.io/docs/reference/alert-settings-slack-channels-create.md) · Organization level · permission `org:write` · risk tier `security` · since M7

Adds a Slack incoming webhook (or any Slack-compatible one) to the organization's alerts in the mode of the
request. Critical alerts are posted to every channel; high alerts to channels whose `minSeverity` is `high`
(the default). Info alerts stay in the inbox.

The webhook URL is stored encrypted and never shown again (`urlHint` shows its host and last characters).
Every message is signed like a webhook (`Ownrecord-Signature`, spec §26) with the channel's own
`signingSecret`, returned once here, so a relay in front of Slack can check that it came from Ownrecord.
URLs must be https on a public host (spec §6.8). Test the channel with
`alert_settings.slack_channels.test`. At most 10 channels per mode.

Needs `org:write` (owners and admins). Security tier: it sends alert messages outside Ownrecord.

Annotations: `readOnlyHint: false` · `destructiveHint: false` · `idempotentHint: false` · `openWorldHint: false`

### Arguments

| Argument          | Type                      | Required | Description                                                                                                                                                                                              |
| ----------------- | ------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`            | string                    | yes      | (1–80 characters)                                                                                                                                                                                        |
| `webhookUrl`      | string                    | yes      | (1–2048 characters)                                                                                                                                                                                      |
| `minSeverity`     | one of `high`, `critical` | no       | (default `"high"`)                                                                                                                                                                                       |
| `idempotency_key` | string                    | no       | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's `idempotency_key`. (1–255 characters) |
| `dry_run`         | boolean                   | no       | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default `false`)                                                                                 |

- **Idempotency:** the result returns the `idempotency_key` used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
- **Dry run:** supported. `dry_run: true` checks permissions and rules and computes the result, then rolls everything back.

### Errors

- [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed): The name or URL is missing or too long.
- [`slack_webhook_url_invalid`](https://ownrecord.io/docs/reference/errors.md#slack_webhook_url_invalid): The URL isn't https on a public host (`details.reason`).
- [`slack_channel_limit_reached`](https://ownrecord.io/docs/reference/errors.md#slack_channel_limit_reached): The organization has 10 channels in this mode.
- [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict): The settings changed at the same moment; retry.
- [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied): You can't change this organization's settings.

### Example

**Post tax alerts to #tax-alerts**

Arguments:

```json
{
  "name": "#tax-alerts",
  "webhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/ExampleOnlyx7Qa",
  "minSeverity": "high",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
```

Result `output`:

```json
{
  "id": "sec_01m4ttwd3veh9apbewxheq5xad",
  "object": "slack_channel",
  "name": "#tax-alerts",
  "urlHint": "hooks.slack.com …x7Qa",
  "minSeverity": "high",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "lastTest": null,
  "signingSecret": "whsec_ExampleOnlyNotARealSigningSecret0000000"
}
```

## `alert_settings_slack_channels_delete`

**Slack alerts: remove a channel.** Operation [`alert_settings.slack_channels.delete`](https://ownrecord.io/docs/reference/alert-settings-slack-channels-delete.md) · Organization level · permission `org:write` · risk tier `write` · since M7

Removes a Slack channel from the organization's alerts in the mode of the request and deletes its stored
webhook URL and signing secret. Alerts already posted stay in Slack. Returns the alert settings.

Needs `org:write` (owners and admins).

Annotations: `readOnlyHint: false` · `destructiveHint: true` · `idempotentHint: false` · `openWorldHint: false`

### Arguments

| Argument          | Type         | Required | Description                                                                                                                                                                                              |
| ----------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`              | ID (`sec_…`) | yes      | –                                                                                                                                                                                                        |
| `idempotency_key` | string       | no       | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's `idempotency_key`. (1–255 characters) |
| `dry_run`         | boolean      | no       | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default `false`)                                                                                 |

- **Idempotency:** the result returns the `idempotency_key` used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
- **Dry run:** supported. `dry_run: true` checks permissions and rules and computes the result, then rolls everything back.

### Errors

- [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found): The alert settings of this mode have no such channel.
- [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict): The settings changed at the same moment; retry.
- [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied): You can't change this organization's settings.

### Example

**Remove the only channel**

Arguments:

```json
{
  "id": "sec_01m4ttwd3veh9apbewxheq5xad",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
```

Result `output`:

```json
{
  "object": "alert_settings",
  "livemode": true,
  "email": {
    "high": "immediate"
  },
  "slackChannels": [],
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "version": 3
}
```

## `alert_settings_slack_channels_test`

**Slack alerts: send a test message.** Operation [`alert_settings.slack_channels.test`](https://ownrecord.io/docs/reference/alert-settings-slack-channels-test.md) · Organization level · permission `org:write` · risk tier `write` · since M7

Posts a test message to one of the organization's Slack channels (in the mode of the request) and records
whether the webhook accepted it (`lastTest`). A refused or unreachable webhook is a result (`ok: false`
with what went wrong), not an error. A dry run posts nothing and returns a simulated result.

Needs `org:write` (owners and admins).

Annotations: `readOnlyHint: false` · `destructiveHint: false` · `idempotentHint: false` · `openWorldHint: true`

### Arguments

| Argument          | Type         | Required | Description                                                                                                                                                                                              |
| ----------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`              | ID (`sec_…`) | yes      | –                                                                                                                                                                                                        |
| `idempotency_key` | string       | no       | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's `idempotency_key`. (1–255 characters) |
| `dry_run`         | boolean      | no       | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default `false`)                                                                                 |

- **Idempotency:** the result returns the `idempotency_key` used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
- **Dry run:** supported. `dry_run: true` checks permissions and rules and computes the result, then rolls everything back.

### Errors

- [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found): The alert settings of this mode have no such channel.
- [`upstream_timeout`](https://ownrecord.io/docs/reference/errors.md#upstream_timeout): The test took too long to run; try again.
- [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict): The settings changed at the same moment; retry.
- [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied): You can't change this organization's settings.

### Example

**The webhook accepted the message**

Arguments:

```json
{
  "id": "sec_01m4ttwd3veh9apbewxheq5xad",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
```

Result `output`:

```json
{
  "id": "sec_01m4ttwd3veh9apbewxheq5xad",
  "object": "slack_channel",
  "name": "#tax-alerts",
  "urlHint": "hooks.slack.com …x7Qa",
  "minSeverity": "high",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "lastTest": {
    "ok": true,
    "status": 200,
    "message": "The webhook accepted the test message.",
    "at": "2026-10-13T12:30:00.000Z"
  }
}
```

## `alert_settings_update`

**Update the alert settings.** Operation [`alert_settings.update`](https://ownrecord.io/docs/reference/alert-settings-update.md) · Organization level · permission `org:write` · risk tier `write` · since M7

Sets whether high alerts are emailed in the mode of the request: `immediate` (the default) emails them to
the members whose role handles them as they are raised; `off` keeps them in the inbox (and the Slack
channels that take high alerts). Critical alerts are always emailed. Pass `expectedVersion` (the settings'
`version`, 0 while the defaults apply) to refuse the change if someone else changed the settings meanwhile.

Needs `org:write` (owners and admins).

Annotations: `readOnlyHint: false` · `destructiveHint: false` · `idempotentHint: true` · `openWorldHint: false`

### Arguments

| Argument          | Type    | Required | Description                                                                                                                                                                                              |
| ----------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `email`           | object  | yes      | –                                                                                                                                                                                                        |
| `expectedVersion` | integer | no       | (0–9007199254740991)                                                                                                                                                                                     |
| `idempotency_key` | string  | no       | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's `idempotency_key`. (1–255 characters) |
| `dry_run`         | boolean | no       | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default `false`)                                                                                 |

- **Idempotency:** the result returns the `idempotency_key` used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
- **Dry run:** supported. `dry_run: true` checks permissions and rules and computes the result, then rolls everything back.

### Errors

- [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed): `email.high` isn't `immediate` or `off`.
- [`version_conflict`](https://ownrecord.io/docs/reference/errors.md#version_conflict): The settings changed since `expectedVersion`; reload and retry.
- [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied): You can't change this organization's settings.

### Example

**Keep high alerts out of email**

Arguments:

```json
{
  "email": {
    "high": "off"
  },
  "expectedVersion": 2,
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
```

Result `output`:

```json
{
  "object": "alert_settings",
  "livemode": true,
  "email": {
    "high": "off"
  },
  "slackChannels": [
    {
      "id": "sec_01m4ttwd3veh9apbewxheq5xad",
      "object": "slack_channel",
      "name": "#tax-alerts",
      "urlHint": "hooks.slack.com …x7Qa",
      "minSeverity": "high",
      "createdAt": "2026-10-13T12:00:00.000Z",
      "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "lastTest": null
    }
  ],
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "version": 3
}
```
