Quick Start
This guide will help you get started with notion-py-client.
Installation
Install the package:
Authentication
Get your Notion integration token from Notion Integrations.
from notion_py_client import NotionAsyncClient
# Initialize the client
client = NotionAsyncClient(auth="secret_xxx")
# Or with options
client = NotionAsyncClient(
auth="secret_xxx",
options={
"timeout_ms": 30000,
"notion_version": "2025-09-03"
}
)
Basic Usage
Query a Data Source
In Notion API 2025-09-03, databases are containers for data sources. To query data:
async with NotionAsyncClient(auth="secret_xxx") as client:
# Query a data source
response = await client.dataSources.query(
data_source_id="ds_abc123",
page_size=50
)
for page in response.results:
print(f"Page ID: {page.id}")
Create a Page
from notion_py_client.requests.page_requests import CreatePageParameters
from notion_py_client.requests.property_requests import (
TitlePropertyRequest,
StatusPropertyRequest,
)
async with NotionAsyncClient(auth="secret_xxx") as client:
params = CreatePageParameters(
parent={"type": "database_id", "database_id": "db_abc123"},
properties={
"Name": TitlePropertyRequest(
title=[{"type": "text", "text": {"content": "New Page"}}]
),
"Status": StatusPropertyRequest(
status={"name": "In Progress"}
),
}
)
page = await client.pages.create(params)
print(f"Created page: {page.id}")
Update a Page
from notion_py_client.requests.page_requests import UpdatePageParameters
async with NotionAsyncClient(auth="secret_xxx") as client:
params = UpdatePageParameters(
page_id="page_abc123",
properties={
"Status": StatusPropertyRequest(
status={"name": "Done"}
),
}
)
page = await client.pages.update(params)
print(f"Updated page: {page.id}")
Retrieve a Database
async with NotionAsyncClient(auth="secret_xxx") as client:
# Get database metadata and data sources list
db = await client.databases.retrieve(
{"database_id": "db_abc123"}
)
print(f"Database: {db.title}")
print(f"Data sources: {len(db.data_sources)}")
# Get schema from first data source
if db.data_sources:
ds = await client.dataSources.retrieve(
data_source_id=db.data_sources[0]["id"]
)
for name, config in ds.properties.items():
print(f"{name}: {config.type}")
Understanding 2025-09-03 API Changes
The key concept change in API 2025-09-03:
Old API (before 2025-09-03):
- Database = data + schema
New API (2025-09-03+):
- Database = container with multiple data sources
- Data Source = data + schema (equivalent to old database)
Migration guide:
Old API | New API |
---|---|
databases.query() |
dataSources.query() |
databases.retrieve() → properties |
dataSources.retrieve() → properties |
databases.retrieve() → metadata |
databases.retrieve() → metadata |
Type-Safe Filtering
Use typed filter builders for database queries:
from notion_py_client.filters import create_and_filter
# Single filter (dict)
response = await client.dataSources.query(
data_source_id="ds_abc123",
filter={"property": "Name", "rich_text": {"contains": "urgent"}},
)
# Compound filter (helpers)
filter_dict = create_and_filter(
{"property": "Status", "status": {"equals": "In Progress"}},
{"property": "Name", "rich_text": {"is_not_empty": True}},
)
response = await client.dataSources.query(
data_source_id="ds_abc123",
filter=filter_dict,
)
Error Handling
from notion_py_client.notion_client import (
APIResponseError,
RequestTimeoutError,
UnknownHTTPResponseError,
)
async with NotionAsyncClient(auth="secret_xxx") as client:
try:
page = await client.pages.retrieve({"page_id": "page_id"})
except APIResponseError as e:
print(f"API Error: {e.code} - {e.message}")
except RequestTimeoutError:
print("Request timed out")
except UnknownHTTPResponseError as e:
print(f"HTTP Error: {e.status}")
Next Steps
- Databases API - Work with database containers
- Data Sources API - Query and manage data
- Pages API - Create and update pages
- Type Reference - Explore available types