New to Kestra?
Use blueprints to kickstart your first workflows.
Query a Notion database for overdue items, alert Slack with the page links, and log the result for ops and project teams.
A Notion database tracking tasks, deliverables, or reviews has no native rule that pages anyone when an item's due date passes while it is still open; the database view shows every row looking equally current until someone sorts by date and scrolls. This blueprint runs that sort server-side, using Notion's own filter API, and reports the exact items that are overdue, not a guess.
This blueprint was created by Mohit Jeswani.
query_overdue_items (io.kestra.plugin.notion.database.Query) sends a compound
filter (a due-date-before-today check and a status-not-equal-done check, ANDed
together) to Notion's own database query endpoint, so both checks run server-side
instead of this flow paging through every item to check client-side. Read-only; nothing
in Notion is changed. allowFailure: true covers an API or auth error without failing
the flow outright.evaluate (io.kestra.plugin.core.output.OutputValues) reads the matched count directly
from the API response's own size field and collects each matched page's url with a
jq filter.route (io.kestra.plugin.core.flow.If):summary logs the count and severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an expired API token.database.Query used with
a compound filter for a governance check, distinct from this repo's existing Notion
blueprints, which only create and update pages rather than auditing an existing database.Notion's filter API answers one query at a time; it does not keep a schedule, compare the
result count against a tolerance you declare, or notify a Slack channel when overdue items
pile up. Kestra keeps the property names and max_overdue_count as flow inputs, turns the
query into a Slack page with real clickable links, and keeps a full execution history of
every run.
This flow calls the Notion API directly over HTTPS; there is no official local Notion
emulator, so query_overdue_items cannot be exercised against a local Docker container.
NOTION_API_TOKEN: the Notion internal integration token used by query_overdue_items.
In Kestra OSS, provide it as the base64-encoded environment variable
SECRET_NOTION_API_TOKEN.SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
due_date_property_name |
Due Date |
Date property checked against today |
status_property_name |
Status |
Select property checked against done_status_value |
done_status_value |
Done |
Value that means the item is complete |
max_overdue_count |
1 |
Matched-item count that triggers the Slack alert |
{{ outputs.query_overdue_items.rows }}: every matched page as a raw Notion page object
(id, url, properties, last_edited_time).{{ outputs.evaluate.values.overdue_count }} / .overdue_urls: how many items matched and
their page links, semicolon-joined.{{ outputs.evaluate.values.severity }}: OK, SLA_BREACH, or CRITICAL.status_property_name must be a Notion Select-type property; Notion's newer, separate
Status-type property uses a different filter key (status instead of select) and is
not matched by this filter as written. Check your database's property type before relying
on this gate.allowFailure rather than silently matching nothing.pageSize: 100 is the API maximum per page; a database with more than 100 overdue items in
one query only returns the first 100, with hasMore/nextCursor available on the output
for a future paginated extension.NOTION_API_TOKEN and SLACK_WEBHOOK_URL secrets, and share the target database
with your Notion integration.notion_database_id and the property names to match a real database.summary logs a count.done_status_value, rerun, and confirm alert fires with its page link.daily trigger once the inputs reflect your real tracker.notion_database_id values with io.kestra.plugin.core.flow.Loop to
audit more than one tracker in a single scheduled run.select filter key for status to support Notion's newer Status-type property
instead of a Select-type one.io.kestra.plugin.notion.page.Update on each overdue page to set a "flagged"
checkbox property, gated behind an explicit confirm_flag input so updating never runs by
accident.