> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cronho.st/llms.txt
> Use this file to discover all available pages before exploring further.

# Notifications

> Create notification channels and choose which outcomes alert you per schedule

# Notifications

Notifications have two parts:

1. **Channels** are reusable destinations (email, Slack, Discord, Telegram)
   that receive alerts. They belong to your account.
2. **Schedule preferences** decide which outcomes (`failure`, `success`, both,
   or none) notify you for a given schedule and which channels receive them.

A channel must be **verified** before it can be attached to a schedule.

<Note>
  Available channel types and notification options depend on your plan. Requests
  that exceed a plan limit return a `PLAN_LIMIT_EXCEEDED` error.
</Note>

## Channels

### List channels

```typescript theme={null}
const channels = await cronhost.listNotificationChannels();
```

**Returns:** `Promise<NotificationChannel[]>` (secrets are never included)

### Create a channel

The `config` shape depends on `type`.

```typescript theme={null}
// Email
const email = await cronhost.createNotificationChannel({
  type: "email",
  label: "On-call inbox",
  config: { to: "oncall@example.com" },
});

// Slack or Discord (incoming webhook, must be https)
const slack = await cronhost.createNotificationChannel({
  type: "slack",
  label: "Ops alerts",
  config: { webhookUrl: "https://hooks.slack.com/services/T000/B000/XXXX" },
});

// Telegram (chatId is discovered during verification)
const telegram = await cronhost.createNotificationChannel({
  type: "telegram",
  label: "Telegram bot",
  config: { botToken: "123456:ABC-DEF" },
});
```

**Returns:** `Promise<NotificationChannel>` (unverified until you verify it)

### Verify a channel

Sends a test notification and marks the channel verified on success.

```typescript theme={null}
const verified = await cronhost.verifyNotificationChannel(slack.id);
console.log(verified.verified); // true
```

**Returns:** `Promise<NotificationChannel>`

### Get, update, and delete

```typescript theme={null}
const channel = await cronhost.getNotificationChannel(slack.id);

// The type is immutable; update the label and/or config.
const updated = await cronhost.updateNotificationChannel(slack.id, {
  label: "Renamed alerts",
  config: { webhookUrl: "https://hooks.slack.com/services/T000/B111/YYYY" },
});

await cronhost.deleteNotificationChannel(slack.id);
```

The channel `type` is immutable. Changing the delivery destination (for example
a new webhook URL or email address) resets the channel to unverified, so call
`verifyNotificationChannel` again before it can send. A label-only change keeps
its verified status.

Deleting a channel automatically detaches it from any schedule preferences that
referenced it.

## Schedule preferences

### Get a schedule's preference

```typescript theme={null}
const pref = await cronhost.getScheduleNotifications("schedule-123");
console.log(pref.notifyOn); // "none" | "success" | "failure" | "both"
console.log(pref.channels); // attached channel refs
```

**Returns:** `Promise<ScheduleNotificationPreference>` (unset schedules return
`notifyOn: "none"` with no channels)

### Set a schedule's preference

```typescript theme={null}
await cronhost.setScheduleNotifications("schedule-123", {
  notifyOn: "failure",
  channelIds: [slack.id],
});
```

**Returns:** `Promise<ScheduleNotificationPreference>`

Rules enforced by the API:

* `channelIds` is required (non-empty) when `notifyOn` is not `"none"`.
* Every channel id must reference a **verified** channel you own.
* `success` and `both` require at least one **webhook** channel (Slack,
  Discord, or Telegram); email is not delivered per success.
* Some `notifyOn` values are gated by plan.

The returned preference may include a non-blocking `warning` (for example, when
enabling per-success notifications on a very high-frequency schedule).

## Example: alert on failures

```typescript theme={null}
import { Cronhost } from "cronhost";

const cronhost = new Cronhost({ apiKey: "your-api-key" });

async function setupFailureAlerts(scheduleId: string) {
  // 1. Create a channel and verify it.
  const channel = await cronhost.createNotificationChannel({
    type: "slack",
    label: "Ops alerts",
    config: { webhookUrl: process.env.SLACK_WEBHOOK_URL! },
  });
  await cronhost.verifyNotificationChannel(channel.id);

  // 2. Attach it to the schedule for failure alerts.
  await cronhost.setScheduleNotifications(scheduleId, {
    notifyOn: "failure",
    channelIds: [channel.id],
  });
}
```
