Skip to content

Cloudflare.Alerting reference

Source: packages/cloudflare/src/Alerting/CustomAlert.ts

A Cloudflare custom alert: a SQL query Cloudflare runs on a schedule, with a trigger that decides when to notify.

The query runs against the SQL API, so it can read Workers logs and traces, HTTP requests, Analytics Engine datasets and the other analytics datasets. Notifications go to the same destinations as a NotificationPolicy (email, webhooks, PagerDuty).

yield* Cloudflare.Alerting.CustomAlert("ErrorSpike", {
query: `SELECT count() AS value FROM logs.workersLogs
WHERE accountTag = '${accountId}' AND level = 'error'`,
trigger: { type: "threshold", operator: ">", value: 100, window: "5m" },
every: "5m",
mechanisms: { email: [{ id: "ops@example.com" }] },
});
yield* Cloudflare.Alerting.CustomAlert("TrafficAnomaly", {
query: `SELECT count() AS value FROM events.httpRequests
WHERE accountTag = '${accountId}'`,
trigger: {
type: "anomaly",
direction: "both",
zScore: 3,
window: "5m",
baselineWindow: "1h",
},
mechanisms: { webhooks: [{ id: webhook.webhookId }] },
});
yield* Cloudflare.Alerting.CustomAlert("Availability", {
query: `SELECT 100 * countIf(httpStatus < 500) / count() AS value
FROM logs.workersLogs WHERE accountTag = '${accountId}'`,
trigger: { type: "slo", target: 99.9, shortWindow: "5m", longWindow: "1h" },
mechanisms: { pagerduty: [{ id: pagerDutyId }] },
});

Source: packages/cloudflare/src/Alerting/NotificationEventSource.ts

Run an Effect for every notification a policy fires.

Call it in the Construction phase of any runtime that receives HTTP (a WebhookHost, such as a Cloudflare Worker). Cloudflare then delivers the policy’s notifications to that runtime: the event source creates a webhook destination at the runtime’s URL and adds it to the policy, so the policy needs no mechanisms of its own.

Open a GitHub issue for each new Worker issue

const policy = yield* Cloudflare.Alerting.NotificationPolicy("IssuePolicy", {
alertType: "workers_observability_real_time_issue",
});
// `text` is Cloudflare's report: a summary line, then details and links.
const createIssue = yield* GitHub.CreateIssue(yield* Repo);
yield* Cloudflare.Alerting.consumeNotifications(policy, (notification) =>
createIssue({
title: notification.text.split("\n")[0],
body: notification.text,
}),
);

Page on a SQL custom alert, with your own secret

const errors = yield* ErrorSpike; // a Cloudflare.Alerting.CustomAlert
yield* Cloudflare.Alerting.consumeNotifications(
errors,
{ secret: yield* Config.Redacted("ALERT_WEBHOOK_SECRET") },
(notification) =>
notification.alertEvent === "ALERT_STATE_EVENT_END"
? pager.resolve(notification.alertCorrelationId)
: pager.trigger(notification.alertCorrelationId, notification.text),
);

Source: packages/cloudflare/src/Alerting/NotificationEventSourceLive.ts Kind: Layer · Provides: Cloudflare.Alerting.NotificationEventSource

Cloudflare.Alerting.consumeNotifications on any WebhookHost.

Deploy-time: creates a NotificationWebhook destination pointing at the host (at a per-policy path) and binds it onto the policy, so the policy notifies the host. The webhook secret (yours, or a generated one) is bound onto the host. Under alchemy dev the host is on localhost, which Cloudflare can’t reach, so no destination is created.

Runtime: claims requests on the policy’s path, rejects any without the secret in cf-webhook-auth, acknowledges Cloudflare’s test message, and runs the handler once per notification.

Source: packages/cloudflare/src/Alerting/NotificationPolicy.ts

A Cloudflare Notifications policy.

A notification policy connects an alert type (the event Cloudflare watches for) to one or more destinations — email addresses, webhook destinations, or PagerDuty services — optionally narrowed by filters.

Email notifications for Universal SSL events

yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
mechanisms: { email: [{ id: "ops@example.com" }] },
});

Disabled policy with a description

yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
enabled: false,
description: "Paused during migration",
mechanisms: { email: [{ id: "ops@example.com" }] },
});
const webhook = yield* Cloudflare.Alerting.NotificationWebhook("AlertsHook", {
url: "https://alerts.example.com/cf",
});
yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
mechanisms: { webhooks: [{ id: webhook.webhookId }] },
});
yield* Cloudflare.Alerting.NotificationPolicy("HealthAlerts", {
alertType: "health_check_status_notification",
mechanisms: { email: [{ id: "ops@example.com" }] },
filters: {
healthCheckId: [healthCheckId],
newHealth: ["Unhealthy"],
},
});

NotificationPolicy: Handling notifications in code

Section titled “NotificationPolicy: Handling notifications in code”

consumeNotifications adds a webhook destination at the consuming runtime, so the policy needs no mechanisms.

const policy = yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
});
// in a Worker's Construction phase, with NotificationEventSourceLive provided
yield* Cloudflare.Alerting.consumeNotifications(policy, (notification) =>
Effect.log(notification.text),
);

Alerts on a SQL query (Cloudflare’s custom_analytics alert type) have their own resource with typed triggers: Cloudflare.Alerting.CustomAlert.

NotificationPolicy: Workers Issues notifications

Section titled “NotificationPolicy: Workers Issues notifications”
const policy = yield* Cloudflare.Alerting.NotificationPolicy("IssuePolicy", {
alertType: "workers_observability_real_time_issue",
mechanisms: { email: [{ id: "ops@example.com" }] },
});
yield* Cloudflare.Workers.IssueAutomation("IssueAlerts", {
policyId: policy.policyId,
afterOccurrences: 5,
});

Source: packages/cloudflare/src/Alerting/Silence.ts

A Cloudflare Notifications silence window.

A silence suppresses notification dispatches for a NotificationPolicy between startTime and endTime — e.g. during a planned maintenance window. The window times are explicit ISO8601 props supplied by you; Cloudflare requires the start time to be within 90 days of now.

Note: the create API returns no id, so the provider resolves the created silence by listing and matching on (policyId, startTime, endTime). Two silences sharing the exact same policy and window are indistinguishable.

const policy = yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
mechanisms: { email: [{ id: "ops@example.com" }] },
});
yield* Cloudflare.Alerting.Silence("MaintenanceWindow", {
policyId: policy.policyId,
startTime: "2026-07-01T00:00:00Z",
endTime: "2026-07-01T04:00:00Z",
});

Window times are mutable — changing them updates the existing silence.

yield* Cloudflare.Alerting.Silence("MaintenanceWindow", {
policyId: policy.policyId,
startTime: "2026-07-01T00:00:00Z",
endTime: "2026-07-01T08:00:00Z",
});

Source: packages/cloudflare/src/Alerting/Webhook.ts

A Cloudflare Notifications webhook destination.

Webhook destinations receive alert notifications dispatched by notification policies. Cloudflare sends a test POST to the URL when the webhook is created or updated, so the endpoint must be live and respond with a 2xx.

NotificationWebhook: Creating a Webhook destination

Section titled “NotificationWebhook: Creating a Webhook destination”

Generic webhook with a generated name

const webhook = yield* Cloudflare.Alerting.NotificationWebhook("AlertsHook", {
url: "https://alerts.example.com/cf",
});

Webhook with an auth secret

The secret is sent in the cf-webhook-auth header on every dispatch.

const webhook = yield* Cloudflare.Alerting.NotificationWebhook("AlertsHook", {
name: "production-alerts",
url: "https://alerts.example.com/cf",
secret: yield* Config.Redacted("WEBHOOK_SECRET"),
});

NotificationWebhook: Using with a Notification policy

Section titled “NotificationWebhook: Using with a Notification policy”
yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
mechanisms: { webhooks: [{ id: webhook.webhookId }] },
});

NotificationWebhook: Looking up an existing webhook

Section titled “NotificationWebhook: Looking up an existing webhook”

NotificationWebhook.lookup references a destination Alchemy doesn’t manage (created in the dashboard or by another stack), found by webhookId or name. It is read during plan/deploy and never created, updated or deleted.

const pager = Cloudflare.Alerting.NotificationWebhook.lookup({ name: "pager" });
yield* Cloudflare.Alerting.NotificationPolicy("SslAlerts", {
alertType: "universal_ssl_event_type",
mechanisms: { webhooks: [{ id: pager.webhookId }] },
});