Query icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Notion Database Overdue Item Compliance Gate

Query a Notion database for overdue items, alert Slack with the page links, and log the result for ops and project teams.

Categories
Business

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.

How it works

  1. 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.
  2. 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.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing currently matches the filter.
    • alert: posts the count and page links to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired API token.

What you get

  • A count that is Notion's own server-side filter match, not a client-side guess computed after paging through the whole database.
  • A clickable page link per overdue item in the Slack alert, so whoever responds lands directly on the real item instead of searching the database view for it.
  • A read-only check with zero risk of updating or archiving a real page.

Who it's for

  • Project and ops leads who run a Notion database as their task or review tracker and want overdue items surfaced on a schedule, not discovered during a standup.
  • Teams evaluating the Notion plugin who want a worked example of 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.

Why orchestrate this with Kestra

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.

Prerequisites

  • A Notion database with a Date-type property and a Select-type property for status, shared with a Notion internal integration.
  • A Notion internal integration token with read access to that database.
  • A Slack incoming webhook URL.

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.

Secrets

  • 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.

Inputs

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

  • {{ 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.

Pitfalls

  • 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.
  • Both property names must match the database's exact display names, including spacing and case; a mismatched name makes Notion reject the filter with an error, surfaced via 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.

Quick start

  1. Add the NOTION_API_TOKEN and SLACK_WEBHOOK_URL secrets, and share the target database with your Notion integration.
  2. Set notion_database_id and the property names to match a real database.
  3. Run the flow manually and confirm summary logs a count.
  4. Set a known item's due date to yesterday and its status to something other than done_status_value, rerun, and confirm alert fires with its page link.
  5. Enable the daily trigger once the inputs reflect your real tracker.

How to extend

  • Loop over several notion_database_id values with io.kestra.plugin.core.flow.Loop to audit more than one tracker in a single scheduled run.
  • Swap the select filter key for status to support Notion's newer Status-type property instead of a Select-type one.
  • Chain 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.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.