1# notion
2
3Use the Notion API to create/read/update pages, data sources (databases), and blocks.
4
5## Setup
6
71. Create an integration at https://notion.so/my-integrations
82. Copy the API key (starts with `ntn_` or `secret_`)
93. Store it:
10
11mkdir -p ~/.config/notion
12echo "ntn_your_key_here" > ~/.config/notion/api_key
13
144. Share target pages/databases with your integration (click "..." -> "Connect to" -> your integration name)
15
16## API Basics
17
18All requests need:
19
20NOTION_KEY=$(cat ~/.config/notion/api_key)
21curl -X GET "https://api.notion.com/v1/..." \
22 -H "Authorization: Bearer $NOTION_KEY" \
23 -H "Notion-Version: 2025-09-03" \
24 -H "Content-Type: application/json"
25
26
27> **Note:** The `Notion-Version` header is required. This skill uses `2025-09-03` (latest). In this version, databases are called "data sources" in the API.
28
29## Common Operations
30
31**Search for pages and data sources:**
32
33curl -X POST "https://api.notion.com/v1/search" \
34 -H "Authorization: Bearer $NOTION_KEY" \
35 -H "Notion-Version: 2025-09-03" \
36 -H "Content-Type: application/json" \
37 -d '{"query": "page title"}'
38
39
40**Get page:**
41
42curl "https://api.notion.com/v1/pages/{page_id}" \
43 -H "Authorization: Bearer $NOTION_KEY" \
44 -H "Notion-Version: 2025-09-03"
45
46
47**Get page content (blocks):**
48
49curl "https://api.notion.com/v1/blocks/{page_id}/children" \
50 -H "Authorization: Bearer $NOTION_KEY" \
51 -H "Notion-Version: 2025-09-03"
52
53
54**Create page in a data source:**
55
56curl -X POST "https://api.notion.com/v1/pages" \
57 -H "Authorization: Bearer $NOTION_KEY" \
58 -H "Notion-Version: 2025-09-03" \
59 -H "Content-Type: application/json" \
60 -d '{
61 "parent": {"database_id": "xxx"},
62 "properties": {
63 "Name": {"title": [{"text": {"content": "New Item"}}]},
64 "Status": {"select": {"name": "Todo"}}
65 }
66 }'
67
68
69**Query a data source (database):**
70
71curl -X POST "https://api.notion.com/v1/data_sources/{data_source_id}/query" \
72 -H "Authorization: Bearer $NOTION_KEY" \
73 -H "Notion-Version: 2025-09-03" \
74 -H "Content-Type: application/json" \
75 -d '{
76 "filter": {"property": "Status", "select": {"equals": "Active"}},
77 "sorts": [{"property": "Date", "direction": "descending"}]
78 }'
79
80
81**Create a data source (database):**
82
83curl -X POST "https://api.notion.com/v1/data_sources" \
84 -H "Authorization: Bearer $NOTION_KEY" \
85 -H "Notion-Version: 2025-09-03" \
86 -H "Content-Type: application/json" \
87 -d '{
88 "parent": {"page_id": "xxx"},
89 "title": [{"text": {"content": "My Database"}}],
90 "properties": {
91 "Name": {"title": {}},
92 "Status": {"select": {"options": [{"name": "Todo"}, {"name": "Done"}]}},
93 "Date": {"date": {}}
94 }
95 }'
96
97
98**Update page properties:**
99
100curl -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
101 -H "Authorization: Bearer $NOTION_KEY" \
102 -H "Notion-Version: 2025-09-03" \
103 -H "Content-Type: application/json" \
104 -d '{"properties": {"Status": {"select": {"name": "Done"}}}}'
105
106
107**Add blocks to page:**
108
109curl -X PATCH "https://api.notion.com/v1/blocks/{page_id}/children" \
110 -H "Authorization: Bearer $NOTION_KEY" \
111 -H "Notion-Version: 2025-09-03" \
112 -H "Content-Type: application/json" \
113 -d '{
114 "children": [
115 {"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Hello"}}]}}
116 ]
117 }'
118
119
120## Property Types
121
122Common property formats for database items:
123- **Title:** `{"title": [{"text": {"content": "..."}}]}`
124- **Rich text:** `{"rich_text": [{"text": {"content": "..."}}]}`
125- **Select:** `{"select": {"name": "Option"}}`
126- **Multi-select:** `{"multi_select": [{"name": "A"}, {"name": "B"}]}`
127- **Date:** `{"date": {"start": "2024-01-15", "end": "2024-01-16"}}`
128- **Checkbox:** `{"checkbox": true}`
129- **Number:** `{"number": 42}`
130- **URL:** `{"url": "https://..."}`
131- **Email:** `{"email": "a@b.com"}`
132- **Relation:** `{"relation": [{"id": "page_id"}]}`
133
134## Key Differences in 2025-09-03
135
136- **Databases -> Data Sources:** Use `/data_sources/` endpoints for queries and retrieval
137- **Two IDs:** Each database now has both a `database_id` and a `data_source_id`
138 - Use `database_id` when creating pages (`parent: {"database_id": "..."}`)
139 - Use `data_source_id` when querying (`POST /v1/data_sources/{id}/query`)
140- **Search results:** Databases return as `"object": "data_source"` with their `data_source_id`
141- **Parent in responses:** Pages show `parent.data_source_id` alongside `parent.database_id`
142- **Finding the data_source_id:** Search for the database, or call `GET /v1/data_sources/{data_source_id}`
143
144## Notes
145
146- Page/database IDs are UUIDs (with or without dashes)
147- The API cannot set database view filters - that's UI-only
148- Rate limit: ~3 requests/second average
149- Use `is_inline: true` when creating data sources to embed them in pages
150