Slack alerts: add a channel
The alert_settings.slack_channels.create operation: POST /api/v1/alert_settings/slack_channels in the REST API and the alert_settings_slack_channels_create tool in the MCP server.
/api/v1/alert_settings/slack_channelsAdds 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.
At a glance
- REST:
POST /api/v1/alert_settings/slack_channels - MCP tool:
alert_settings_slack_channels_create - Operation ID:
alert_settings.slack_channels.create - Scope: Organization
- Permission:
org:write - Risk tier:
security - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyrequired - Modes: Test and live
- Authentication: API key with the
org:writescope - Since: M7
Request
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | |
webhookUrl | string | Yes | |
minSeverity | one of high, critical | No |
Response
201 Created with a JSON object:
| Field | Type | Description |
|---|---|---|
id | sec_… ID | |
object | "slack_channel" | |
name | string | |
urlHint | string | |
minSeverity | one of high, critical | |
createdAt | date-time | |
createdBy | string | |
lastTest | object or null | |
signingSecret | string |
Examples
Post tax alerts to #tax-alerts
POST /api/v1/alert_settings/slack_channels
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json
{
"name": "#tax-alerts",
"webhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/ExampleOnlyx7Qa",
"minSeverity": "high"
}
Response (201):
{
"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"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | The name or URL is missing or too long. | Fix the fields listed in details.issues and send the request again. |
slack_webhook_url_invalid | 400 | The URL isn't https on a public host (details.reason). | Use the incoming-webhook URL Slack (or a Slack-compatible tool) gave you: https, a public host, no user name or password. details.reason says what is wrong. |
slack_channel_limit_reached | 409 | The organization has 10 channels in this mode. | Remove a channel you no longer use (details.limit is the maximum), then add the new one. |
version_conflict | 409 | The settings changed at the same moment; retry. | Fetch the object again and retry the change. |
permission_denied | 403 | You can't change this organization's settings. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, resource_not_found, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.