Playbook: business alerts from a scheduled notebook
Turn a scheduled Deepnote notebook into an alert for business conditions such as a revenue drop or a stalled pipeline, with the numbers in the message and a link to the analysis, without a separate alerting tool
Most alerting tools watch servers. The alerts a business team wants are different: sign-ups fell 30% against last week, a large customer stopped using the product, refunds spiked in one country. The logic for these already lives in SQL and Python, which is what a Deepnote notebook runs.
This playbook shows two ways to turn a scheduled notebook into an alert, and how to choose between them.
What you'll combine
| Feature | Role in this playbook |
|---|---|
| SQL blocks and Python | The condition |
| Scheduling | Checks the condition every hour or every day |
| Schedule notifications | Simple alerts through Slack or email |
| Environment variables | Store the webhook or bot token for richer alerts |
| Slack or Telegram | Where alerts arrive |
| Run snapshots | The data each alert was based on |
| Data app projects | Where people go to investigate |
Option 1 (recommended): send the message from the notebook
For alerts people act on, send the message yourself, with the numbers and a link, and let the run succeed.
- Create an incoming webhook for the Slack channel, or a Telegram bot.
- Store the webhook URL or bot token in an environment variables integration and connect it to the project.
- End the notebook with a block that posts only when the condition is met:
import os
import requests
# No sign-ups last week means there's no baseline to compare against
drop = 1 - this_week / last_week if last_week else 0.0
if drop > 0.3:
requests.post(
os.environ["SLACK_ALERTS_WEBHOOK"],
json={
"text": (
f":warning: Sign-ups fell {drop:.0%} week over week ({this_week} vs {last_week}).\n"
"Breakdown by channel: <link from Copy link to app>"
)
},
timeout=30,
).raise_for_status()
Keep a schedule failure notification as well, sent to the people who maintain the notebook. Business alerts then go to the business channel, and broken runs go to the maintainers, with auto-pause protecting both.
Option 2: raise an error and use schedule notifications
With auto-pause on, the default threshold of three alerts in a row pauses the schedule, though a frequent schedule isn't paused before about an hour of failures. Only the schedule's owner gets an email about the pause, so the people who receive the alerts aren't told that it stopped. Use this option only if you turn auto-pause off or raise its threshold.
It needs no code beyond the check. End the notebook with a block that raises when the condition is met:
# No sign-ups last week means there's no baseline to compare against
drop = 1 - this_week / last_week if last_week else 0.0
if drop > 0.3:
raise RuntimeError(f"Sign-ups fell {drop:.0%} week over week ({this_week} vs {last_week})")
Schedule the notebook and add a failure notification for a Slack channel or for email recipients from your workspace. When the condition is met, the run fails and the notification goes out.
This works well for a small team, but has three limits:
- The message is generic. A failure notification says that a scheduled job failed for the project and links to the notebook. It doesn't include your error message, so people have to click through to see the numbers.
- Alerts and errors look the same. A real error, such as an expired credential, produces the same notification as the business condition.
- Repeated alerts pause the schedule. Every raise counts as a failure. If auto-pause is on, which is the default for schedules created in Deepnote, three alerts in a row pause the schedule, though not before about an hour of failures for a frequent schedule, and only its owner is told. For this pattern, turn auto-pause off or raise its threshold.
Make alerts worth reading
- Include the numbers and the comparison in the message, so people can judge it without clicking.
- Link to an app, not the notebook. Build a data app that breaks the number down, with its own notebook, and put its link in the alert. Don't build it on the alert notebook: every viewer's run executes the whole notebook, so it would run the alert block again and could send a second alert. To open the app on the right slice, ask the agent to fill its inputs from the link, such as
?country=DE. - Compare like with like. Compare against the same weekday last week or a trailing average rather than yesterday, to avoid alerting on every weekend.
- Run at the right frequency. Hourly checks are available on Team and Enterprise, but not during a Team trial. Checking more often than hourly needs Enterprise.
- Keep the evidence. Every scheduled run creates a run snapshot, so you can see what the data looked like when an alert fired.
Security
- The webhook URL or bot token is a secret. Keep it in an environment variables integration, which stores it encrypted, rather than in a code block.
- The scheduled run executes as the schedule's owner. If they leave the workspace, the schedule pauses until someone else saves it and becomes its owner. A paused alert is silent, and the pause doesn't trigger a failure notification: the pause email goes only to the owner and, unless the project is private, the workspace admins. Agree who takes the schedule over before its owner leaves, and have the admins watch for pause emails.
Plan requirements
- Scheduling: Pro, Team and Enterprise. Hourly and custom cron schedules need Team or Enterprise.
- Schedules more frequent than hourly: Enterprise.
Variations
- Customer health: alert the account owner's channel when a top-50 account's weekly active users fall by half.
- Operations: alert when the backlog of unshipped orders older than 48 hours exceeds a threshold, with the oldest orders listed in the message.
- Finance: alert when daily refunds in any country exceed three times their 30-day average.