# How to Automate Notion Database Reports using the API

- Tool: API Automations
- Difficulty: Intermediate
- Fix time: 30-60 minutes
- Compatibility: Free — internal Notion integration with Read content, Insert content, and Update content capabilities
- Last updated: May 2026

## TL;DR

Automate weekly Notion database reports by querying rows with POST /v1/data_sources/{id}/query (cursor-paginated, 100 rows max per page), aggregating numeric properties in code, and writing the formatted summary back as a new Notion page via POST /v1/pages with PATCH /v1/blocks/{id}/children to append rich-text blocks. The critical constraint is 3 requests/second — a 500-row database with a 20-block report can chain 15+ requests.

## Best practices

- Always include Notion-Version: 2025-09-03 as a constant in your headers — never rely on the API defaulting to a version
- Paginate all database queries — never assume all rows fit in the first response, even for small databases
- Rich text is always an array of objects, not a string — define a helper function to construct rich text blocks to avoid repetition
- Batch block appends in groups of 100 and add 350ms delays between batches
- Store the report page URL from the POST /v1/pages response and log it — makes it easy to find reports without searching Notion
- Handle null property values defensively with optional chaining or null coalescing — any Notion property can be empty
- Run the automation on a schedule (cron) and send the report URL to your team via Slack or email so they know when new reports are available

## Frequently asked questions

### Why does Notion's API not aggregate values for me?

The Notion API returns raw row data only — there is no built-in SUM, AVG, or COUNT endpoint. All aggregation must happen in your code after fetching rows. The only exception is the rollup property type, which Notion calculates within the UI, but rollup values still require separate API pagination to fully retrieve.

### How do I handle databases with more than 100 rows?

Use cursor-based pagination. After each POST /v1/data_sources/{id}/query response, check the has_more boolean. If true, take the next_cursor value and include it as start_cursor in your next request. Repeat until has_more is false. There is no limit to the number of pages you can fetch — just respect the 3 req/s rate limit with delays between page requests.

### What is the difference between POST /v1/pages (children) and PATCH /v1/blocks/{id}/children?

POST /v1/pages accepts a children array to add initial blocks at page creation time, limited to 100 blocks. PATCH /v1/blocks/{page_id}/children appends additional blocks to an existing page or block after creation, also limited to 100 per request. For reports with more than 100 blocks, use PATCH in multiple batches after creating the page.

### Why does my rich text content get rejected with a validation_error?

Rich text in Notion is always an array of rich text objects, never a plain string. The correct structure is: [{"type": "text", "text": {"content": "your text"}}]. The most common mistake is passing a string directly: {"rich_text": "my text"} — this always fails. Define a helper function that wraps strings in the correct structure.

### Is the Notion API free?

Yes, the Notion API is free with no paid tier. The rate limit (3 req/s) is the same regardless of your Notion plan. You can run unlimited automations as long as you stay within the rate limit.

### Can I create a table block for the report instead of a bullet list?

Yes. Notion's table block has type 'table' with has_column_header and table_width fields, and child 'table_row' blocks with cells as arrays of rich text arrays. The structure is more complex than paragraph or list blocks — refer to developers.notion.com/reference/block#table for the exact schema. For most reports, a bulleted list or paragraph blocks are simpler and sufficient.

### What happens when I hit the 3 req/s rate limit?

Notion returns HTTP 429 with body {"object":"error","status":429,"code":"rate_limited"} and a Retry-After header in seconds. Read the Retry-After value and sleep for that duration before retrying. To prevent hitting the limit, add 350ms delays between all sequential API calls in your automation.

### Can RapidDev build a custom Notion reporting automation for my team?

Yes. RapidDev has built 600+ apps including multi-database Notion reporting pipelines, executive dashboards, and automated CRM report generators. We can build a fully managed solution tailored to your database schema. Visit rapidevelopers.com for a free consultation.

---

Source: https://www.rapidevelopers.com/api-automations/how-to-automate-notion-database-reports-using-the-api
© RapidDev — https://www.rapidevelopers.com/api-automations/how-to-automate-notion-database-reports-using-the-api
