Notion API Automation System
Python scripts and Zapier integrations for automating Notion workspaces. Auto-create pages from form submissions, sync databases bidirectionally, generate weekly reports, send notifications on status changes, and archive completed items — all without manual effort.
Key Features
- Python scripts using Notion API — stdlib-only, no pip dependencies required
- Zapier integration blueprints — pre-built Zap configurations for common workflows
- Bidirectional database sync — keep Notion in sync with Google Sheets, Airtable, or CSV files
- Auto-page creation — templates that generate formatted Notion pages from structured data
- Report generation — weekly/monthly summaries pulled from Notion databases
- Status-based notifications — Slack/email alerts when database properties change
- Archival automation — auto-move completed items to archive databases
What's Included
notion-automation-system/
├── README.md
├── config.example.yaml
├── scripts/
│ ├── api_client.py # Notion API wrapper (stdlib only)
│ └── file_processor.py # CSV/JSON to Notion importer
├── pyproject.toml
└── LICENSE
Quick Start
- Create a Notion integration at https://www.notion.so/my-integrations
- Copy your Internal Integration Token — this is your API key
- Share target databases with your integration (click ••• → Connections → Add)
-
Configure
config.example.yamlwith your token and database IDs -
Run the API client —
python scripts/api_client.py --config config.example.yaml -
Import data —
python scripts/file_processor.py --input data.csv --database YOUR_DB_ID
Example: Notion API Client Usage
# scripts/api_client.py — Core usage patterns
# Query a database with filters
python scripts/api_client.py query \
--database "YOUR_DATABASE_ID" \
--filter '{"property": "Status", "select": {"equals": "In Progress"}}' \
--sort '{"property": "Due Date", "direction": "ascending"}'
# Create a new page in a database
python scripts/api_client.py create \
--database "YOUR_DATABASE_ID" \
--properties '{
"Name": {"title": [{"text": {"content": "New Task"}}]},
"Status": {"select": {"name": "To Do"}},
"Priority": {"select": {"name": "High"}},
"Due Date": {"date": {"start": "2026-04-01"}}
}'
# Update a page property
python scripts/api_client.py update \
--page "YOUR_PAGE_ID" \
--properties '{
"Status": {"select": {"name": "Done"}},
"Completed": {"date": {"start": "2026-03-23"}}
}'
# Bulk import from CSV
python scripts/file_processor.py \
--input tasks.csv \
--database "YOUR_DATABASE_ID" \
--mapping '{"Task Name": "Name", "Due": "Due Date", "Owner": "Assigned To"}'
Example: Zapier Integration Blueprints
# Blueprint 1: Form → Notion Page
zap_1:
trigger: { app: typeform, event: new_entry }
action: { app: notion, event: create_database_item }
mapping: { Name: "{{answer_1}}", Client: "{{answer_2}}", Status: "New Request" }
# Blueprint 2: Notion Status Change → Slack
zap_2:
trigger: { app: notion, event: updated_database_item, filter: "Status changed to Ready for Review" }
action: { app: slack, channel: "#project-updates", message: "*{{Name}}* is ready for review — Assigned: {{Assigned To}}" }
# Blueprint 3: Weekly Digest
zap_3:
trigger: { app: schedule, event: every_week, day: Monday, time: "09:00" }
actions:
- { app: notion, event: find_database_items, filter: "Status = In Progress" }
- { app: email, to: "team@example.com", subject: "Weekly Status", body: "Active: {{results_count}} items" }
Configuration
# config.example.yaml
notion:
# Internal Integration Token (from notion.so/my-integrations)
api_token: "YOUR_NOTION_API_TOKEN"
api_version: "2022-06-28"
# Target databases
databases:
projects:
id: "YOUR_PROJECTS_DB_ID"
description: "Main project tracker"
tasks:
id: "YOUR_TASKS_DB_ID"
description: "Task backlog"
clients:
id: "YOUR_CLIENTS_DB_ID"
description: "Client directory"
# Automation settings
automations:
# Auto-archive items with "Done" status older than N days
archive:
enabled: true
status_field: "Status"
done_value: "Done"
days_before_archive: 30
archive_database_id: "YOUR_ARCHIVE_DB_ID"
# Weekly report generation
report:
enabled: true
schedule: "Monday 09:00 UTC"
email_to: "team@example.com"
include_databases: ["projects", "tasks"]
# Status change notifications
notifications:
enabled: true
watch_property: "Status"
notify_on:
- value: "Blocked"
channel: slack
destination: "#alerts"
- value: "Ready for Review"
channel: email
destination: "reviewer@example.com"
# Sync settings
sync:
# Rate limiting (Notion API: 3 requests/second)
requests_per_second: 3
# Retry on 429 errors
max_retries: 3
retry_delay_seconds: 2
Best Practices
- Share databases explicitly — Notion integrations can only access pages/databases shared with them
- Respect rate limits — Notion allows 3 requests/second; the included client handles this automatically
- Use database IDs, not page IDs — database items are queried via the database, not individual pages
- Filter server-side — use Notion's filter API rather than fetching all records and filtering locally
- Handle pagination — Notion returns max 100 results per query; the client auto-paginates
- Store the API token securely — use environment variables, never hardcode in scripts
- Test with a scratch database — don't experiment on production data
Troubleshooting
| Issue | Solution |
|---|---|
| "Could not find database" error | Ensure the database is shared with your integration (••• → Connections) |
| 401 Unauthorized | Check that the API token is correct and hasn't been revoked |
| 429 Rate Limited | Reduce request frequency; the client retries automatically with backoff |
| Properties not updating | Verify property names match exactly (case-sensitive) in your API calls |
| CSV import creates duplicates | Add a unique ID column and check for existing records before creating |
| Zapier can't find Notion database | Reconnect the Notion account in Zapier and re-select the database |
This is 1 of 11 resources in the No-Code Builder Pro toolkit. Get the complete [Notion API Automation System] with all files, templates, and documentation for $29.
Or grab the entire No-Code Builder Pro bundle (11 products) for $129 — save 30%.
Top comments (0)