Notion Api

Automate and integrate Notion API workflows for pages, databases, and content

Notion API is a community skill for integrating with the Notion workspace platform through its REST API, covering database queries, page creation, content blocks, property updates, and automation workflows for Notion workspace management.

What Is This?

Overview

Notion API provides patterns for programmatically managing content in Notion workspaces. It covers database querying with filter and sort parameters for retrieving structured records, page creation with rich content blocks including text, headings, and lists, property updates for modifying database entries with typed fields like select, date, and relation, and block manipulation for appending and rearranging page content. The skill enables developers to build integrations that synchronize Notion data with external systems, automate content workflows, and build dashboards backed by Notion databases.

Who Should Use This

This skill serves developers building integrations between Notion and external tools like CRMs or project trackers, teams automating repetitive Notion workflows such as status updates, and product builders using Notion databases as a backend for internal tools.

Why Use It?

Problems It Solves

Manually updating Notion databases with data from external systems is time-consuming for recurring tasks. Building page content programmatically requires understanding the block structure Notion uses internally. Querying Notion databases with complex filters needs proper API parameter construction. Synchronizing data between Notion and external platforms demands structured integration patterns.

Core Highlights

Database client queries Notion databases with typed filters and pagination handling. Page builder constructs rich content from structured block definitions. Property manager updates database entries with validation for field types. Search endpoint finds pages and databases across the workspace by title.

How to Use It?

Basic Usage

import requests
import os

class NotionClient:
    def __init__(self):
        self.token = os.environ[
            "NOTION_API_KEY"]
        self.base = (
            "https://api.notion.com/v1")
        self.headers = {
            "Authorization":
                f"Bearer {self.token}",
            "Content-Type":
                "application/json",
            "Notion-Version": "2022-06-28"}

    def query_database(
            self, database_id: str,
            filter_obj: dict = None
            ) -> list:
        url = (f"{self.base}/databases/"
               f"{database_id}/query")
        payload = {}
        if filter_obj:
            payload["filter"] = filter_obj
        resp = requests.post(
            url, json=payload,
            headers=self.headers)
        return resp.json()["results"]

    def create_page(
            self, database_id: str,
            properties: dict) -> dict:
        url = f"{self.base}/pages"
        payload = {
            "parent": {"database_id":
                        database_id},
            "properties": properties}
        resp = requests.post(
            url, json=payload,
            headers=self.headers)
        return resp.json()

client = NotionClient()
tasks = client.query_database(
    "db_id_here",
    {"property": "Status",
     "select": {"equals": "Active"}})
print(f"Active tasks: {len(tasks)}")

Real-World Examples

import requests
import os
from datetime import datetime

class NotionSyncManager:
    def __init__(self, client):
        self.client = client

    def sync_records(
            self, database_id: str,
            records: list[dict]) -> dict:
        created, updated = 0, 0
        existing = self.client\
            .query_database(database_id)
        existing_map = {}
        for page in existing:
            title_prop = page["properties"]\
                .get("Name", {})
            title_list = title_prop.get(
                "title", [])
            if title_list:
                name = title_list[0][
                    "plain_text"]
                existing_map[name] = (
                    page["id"])
        for record in records:
            props = self._build_properties(
                record)
            if record["name"] in (
                    existing_map):
                self._update_page(
                    existing_map[
                        record["name"]],
                    props)
                updated += 1
            else:
                self.client.create_page(
                    database_id, props)
                created += 1
        return {"created": created,
                "updated": updated}

    def _build_properties(
            self, record: dict) -> dict:
        return {
            "Name": {"title": [{
                "text": {"content":
                    record["name"]}}]},
            "Status": {"select": {
                "name":
                    record.get("status",
                               "New")}}}

    def _update_page(
            self, page_id: str,
            properties: dict) -> None:
        url = (f"{self.client.base}"
               f"/pages/{page_id}")
        requests.patch(
            url,
            json={"properties": properties},
            headers=self.client.headers)

sync = NotionSyncManager(client)
result = sync.sync_records("db_id", [
    {"name": "Task A", "status": "Done"},
    {"name": "Task B", "status": "Active"}])
print(f"Synced: {result}")

Advanced Tips

Implement cursor-based pagination for database queries that return more than 100 results per request. Use the Notion search endpoint to find databases by title before querying them by ID. Cache database schema information to validate property types before constructing update payloads.

When to Use It?

Use Cases

Build a CRM sync tool that mirrors customer records between Notion databases and Salesforce. Create an automated reporting pipeline that generates weekly summary pages from project tracker databases. Implement a content publishing workflow that creates blog posts from Notion pages exported to a static site generator.

Related Topics

Notion workspace automation, REST API integration, content management systems, data synchronization, and productivity tools.

Important Notes

Requirements

A Notion integration token with access to the target workspace. Python with the requests library for API calls. Database and page IDs for the target resources.

Usage Recommendations

Do: handle pagination for all database queries since results are limited to 100 per request. Use the correct property type format when creating or updating pages. Implement rate limiting to stay within three requests per second.

Don't: poll databases in tight loops for change detection when webhook alternatives exist. Store large binary files as page content when external storage with Notion links is more efficient. Assume property names are stable across workspace reorganizations without validation.

Limitations

The Notion API rate limit of three requests per second constrains bulk operations on large databases. Some Notion features like inline databases are not fully supported through the API. Real-time change notifications require polling since Notion does not provide native webhook push events.