chub-dev 0.1.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1435 @@
1
+ ---
2
+ name: workspace-api
3
+ description: "Notion JavaScript/TypeScript SDK for interacting with Notion workspaces, pages, and databases via the official API."
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "5.3.0"
7
+ updated-on: "2026-03-01"
8
+ source: maintainer
9
+ tags: "notion,api,workspace,pages,databases"
10
+ ---
11
+
12
+ # Notion API JavaScript/TypeScript SDK Coding Guidelines
13
+
14
+ You are a Notion API coding expert. Help me with writing code using the Notion API calling the official libraries and SDKs.
15
+
16
+ You can find the official SDK documentation and code samples here:
17
+ https://developers.notion.com/reference/
18
+
19
+ ## Golden Rule: Use the Correct and Current SDK
20
+
21
+ Always use the Notion JavaScript SDK to interact with Notion workspaces, which is the standard library for all Notion API interactions. Do not use legacy libraries or unofficial SDKs.
22
+
23
+ - **Library Name:** Notion JavaScript SDK
24
+ - **NPM Package:** `@notionhq/client`
25
+ - **Legacy Libraries**: `notion-api-js`, `notion-client`, and other unofficial packages are not recommended
26
+
27
+ **Installation:**
28
+
29
+ - **Correct:** `npm install @notionhq/client`
30
+
31
+ **APIs and Usage:**
32
+
33
+ - **Correct:** `const { Client } = require("@notionhq/client")`
34
+ - **Correct:** `const notion = new Client({ auth: process.env.NOTION_TOKEN })`
35
+ - **Correct:** `await notion.pages.create(...)`
36
+ - **Correct:** `await notion.databases.query(...)`
37
+ - **Correct:** `await notion.dataSources.query(...)`
38
+ - **Incorrect:** `NotionClient` or `NotionAPI`
39
+ - **Incorrect:** Legacy notion-py style APIs
40
+
41
+ ## Installation
42
+
43
+ Install the Notion JavaScript SDK using npm:
44
+
45
+ ```bash
46
+ npm install @notionhq/client
47
+ ```
48
+
49
+ Set your environment variable for the Notion API token:
50
+
51
+ ```bash
52
+ export NOTION_TOKEN="your_integration_token_here"
53
+ ```
54
+
55
+ You can obtain an integration token by creating a new integration at:
56
+ https://www.notion.com/my-integrations
57
+
58
+ ## Initialization and API Key
59
+
60
+ The `@notionhq/client` library requires creating a `Client` instance for all API calls.
61
+
62
+ - Always use `const notion = new Client({})` to create an instance.
63
+ - Set the `NOTION_TOKEN` environment variable, which will be picked up automatically.
64
+
65
+ ```javascript
66
+ const { Client } = require('@notionhq/client');
67
+
68
+ // Uses the NOTION_TOKEN environment variable if auth not specified
69
+ const notion = new Client({
70
+ auth: process.env.NOTION_TOKEN,
71
+ });
72
+ ```
73
+
74
+ ### Client Configuration Options
75
+
76
+ ```javascript
77
+ const { Client, LogLevel } = require('@notionhq/client');
78
+
79
+ const notion = new Client({
80
+ auth: process.env.NOTION_TOKEN,
81
+ logLevel: LogLevel.DEBUG, // Controls logging verbosity (default: LogLevel.WARN)
82
+ timeoutMs: 60000, // Request timeout in milliseconds (default: 60000)
83
+ baseUrl: 'https://api.notion.com', // API endpoint (default shown)
84
+ });
85
+ ```
86
+
87
+ ## Important API Version Changes (2025-09-03)
88
+
89
+ As of API version 2025-09-03, Notion separated databases and data sources:
90
+
91
+ - **Databases** parent one or more data sources
92
+ - **Data Sources** each parent zero or more pages
93
+ - Use `notion.dataSources.query()` instead of `notion.databases.query()` for newer implementations
94
+ - The SDK minimum version for this API is v5.0.0+
95
+
96
+ ## Pages API
97
+
98
+ ### Create a Page
99
+
100
+ Create a new page as a child of an existing page:
101
+
102
+ ```javascript
103
+ const { Client } = require('@notionhq/client');
104
+ const notion = new Client({ auth: process.env.NOTION_TOKEN });
105
+
106
+ async function createPage() {
107
+ const response = await notion.pages.create({
108
+ parent: {
109
+ page_id: '494c87d072c44cf6960f55f8427f7692',
110
+ },
111
+ properties: {
112
+ title: {
113
+ type: 'title',
114
+ title: [
115
+ {
116
+ type: 'text',
117
+ text: { content: 'A note from your pals at Notion' },
118
+ },
119
+ ],
120
+ },
121
+ },
122
+ });
123
+
124
+ console.log(response);
125
+ }
126
+
127
+ createPage();
128
+ ```
129
+
130
+ ### Create a Page in a Data Source (Database)
131
+
132
+ ```javascript
133
+ async function createPageInDataSource() {
134
+ const response = await notion.pages.create({
135
+ parent: {
136
+ data_source_id: '897e5a76-ae52-4b48-9fdf-e71f5945d1af',
137
+ },
138
+ properties: {
139
+ // Properties must match your data source schema
140
+ Name: {
141
+ title: [
142
+ {
143
+ text: {
144
+ content: 'Golden Gate Bridge',
145
+ },
146
+ },
147
+ ],
148
+ },
149
+ Tags: {
150
+ multi_select: [
151
+ { name: 'Landmark' },
152
+ { name: 'San Francisco' },
153
+ ],
154
+ },
155
+ Status: {
156
+ status: {
157
+ name: 'Active',
158
+ },
159
+ },
160
+ },
161
+ });
162
+
163
+ return response;
164
+ }
165
+ ```
166
+
167
+ ### Create a Page with Content Blocks
168
+
169
+ ```javascript
170
+ async function createPageWithContent() {
171
+ const response = await notion.pages.create({
172
+ parent: {
173
+ page_id: '494c87d072c44cf6960f55f8427f7692',
174
+ },
175
+ properties: {
176
+ title: {
177
+ title: [{ text: { content: 'My New Page' } }],
178
+ },
179
+ },
180
+ children: [
181
+ {
182
+ object: 'block',
183
+ type: 'heading_2',
184
+ heading_2: {
185
+ rich_text: [{ type: 'text', text: { content: 'Introduction' } }],
186
+ },
187
+ },
188
+ {
189
+ object: 'block',
190
+ type: 'paragraph',
191
+ paragraph: {
192
+ rich_text: [
193
+ {
194
+ type: 'text',
195
+ text: { content: 'This is a paragraph with ' },
196
+ },
197
+ {
198
+ type: 'text',
199
+ text: { content: 'bold text', link: null },
200
+ annotations: { bold: true },
201
+ },
202
+ ],
203
+ },
204
+ },
205
+ {
206
+ object: 'block',
207
+ type: 'bulleted_list_item',
208
+ bulleted_list_item: {
209
+ rich_text: [{ type: 'text', text: { content: 'First bullet point' } }],
210
+ },
211
+ },
212
+ ],
213
+ });
214
+
215
+ return response;
216
+ }
217
+ ```
218
+
219
+ ### Retrieve a Page
220
+
221
+ ```javascript
222
+ async function retrievePage(pageId) {
223
+ const response = await notion.pages.retrieve({
224
+ page_id: pageId,
225
+ });
226
+
227
+ console.log('Page title:', response.properties.title);
228
+ console.log('Created at:', response.created_time);
229
+ console.log('Last edited:', response.last_edited_time);
230
+
231
+ return response;
232
+ }
233
+ ```
234
+
235
+ ### Update Page Properties
236
+
237
+ ```javascript
238
+ async function updatePage(pageId) {
239
+ const response = await notion.pages.update({
240
+ page_id: pageId,
241
+ properties: {
242
+ Status: {
243
+ status: {
244
+ name: 'Completed',
245
+ },
246
+ },
247
+ Tags: {
248
+ multi_select: [
249
+ { name: 'Updated' },
250
+ { name: 'Important' },
251
+ ],
252
+ },
253
+ },
254
+ });
255
+
256
+ return response;
257
+ }
258
+ ```
259
+
260
+ ### Archive (Trash) a Page
261
+
262
+ ```javascript
263
+ async function archivePage(pageId) {
264
+ const response = await notion.pages.update({
265
+ page_id: pageId,
266
+ archived: true,
267
+ });
268
+
269
+ return response;
270
+ }
271
+ ```
272
+
273
+ ## Databases API
274
+
275
+ ### Query a Database (Legacy - Pre 2025-09-03)
276
+
277
+ ```javascript
278
+ async function queryDatabase(databaseId) {
279
+ const response = await notion.databases.query({
280
+ database_id: databaseId,
281
+ });
282
+
283
+ console.log('Results:', response.results);
284
+ return response;
285
+ }
286
+ ```
287
+
288
+ ### Query with Filters and Sorting
289
+
290
+ ```javascript
291
+ async function queryDatabaseWithFilters(databaseId) {
292
+ const response = await notion.databases.query({
293
+ database_id: databaseId,
294
+ filter: {
295
+ and: [
296
+ {
297
+ property: 'Status',
298
+ status: {
299
+ equals: 'Active',
300
+ },
301
+ },
302
+ {
303
+ property: 'Priority',
304
+ select: {
305
+ equals: 'High',
306
+ },
307
+ },
308
+ ],
309
+ },
310
+ sorts: [
311
+ {
312
+ property: 'Created',
313
+ direction: 'descending',
314
+ },
315
+ ],
316
+ });
317
+
318
+ return response;
319
+ }
320
+ ```
321
+
322
+ ### Query Data Source (API Version 2025-09-03+)
323
+
324
+ ```javascript
325
+ async function queryDataSource(dataSourceId) {
326
+ const response = await notion.dataSources.query({
327
+ data_source_id: dataSourceId,
328
+ filter: {
329
+ property: 'Landmark',
330
+ rich_text: {
331
+ contains: 'Bridge',
332
+ },
333
+ },
334
+ });
335
+
336
+ return response;
337
+ }
338
+ ```
339
+
340
+ ### Filter Examples
341
+
342
+ ```javascript
343
+ // Text property contains value
344
+ const textFilter = {
345
+ property: 'Description',
346
+ rich_text: { contains: 'important' },
347
+ };
348
+
349
+ // Checkbox equals value
350
+ const checkboxFilter = {
351
+ property: 'Done',
352
+ checkbox: { equals: true },
353
+ };
354
+
355
+ // Date is after specific date
356
+ const dateFilter = {
357
+ property: 'Due Date',
358
+ date: { after: '2025-01-01' },
359
+ };
360
+
361
+ // Number greater than value
362
+ const numberFilter = {
363
+ property: 'Score',
364
+ number: { greater_than: 50 },
365
+ };
366
+
367
+ // Multi-select contains value
368
+ const multiSelectFilter = {
369
+ property: 'Tags',
370
+ multi_select: { contains: 'urgent' },
371
+ };
372
+
373
+ // Compound OR filter
374
+ const orFilter = {
375
+ or: [
376
+ { property: 'Tags', multi_select: { contains: 'A' } },
377
+ { property: 'Tags', multi_select: { contains: 'B' } },
378
+ ],
379
+ };
380
+
381
+ // Compound AND filter
382
+ const andFilter = {
383
+ and: [
384
+ { property: 'Done', checkbox: { equals: false } },
385
+ { property: 'Priority', select: { equals: 'High' } },
386
+ ],
387
+ };
388
+ ```
389
+
390
+ ### Retrieve a Database
391
+
392
+ ```javascript
393
+ async function retrieveDatabase(databaseId) {
394
+ const response = await notion.databases.retrieve({
395
+ database_id: databaseId,
396
+ });
397
+
398
+ console.log('Database title:', response.title);
399
+ console.log('Properties:', response.properties);
400
+
401
+ return response;
402
+ }
403
+ ```
404
+
405
+ ### Create a Database
406
+
407
+ ```javascript
408
+ async function createDatabase(parentPageId) {
409
+ const response = await notion.databases.create({
410
+ parent: {
411
+ type: 'page_id',
412
+ page_id: parentPageId,
413
+ },
414
+ title: [
415
+ {
416
+ type: 'text',
417
+ text: {
418
+ content: 'Task List',
419
+ },
420
+ },
421
+ ],
422
+ properties: {
423
+ Name: {
424
+ title: {},
425
+ },
426
+ Status: {
427
+ status: {
428
+ options: [
429
+ { name: 'Not started', color: 'red' },
430
+ { name: 'In progress', color: 'yellow' },
431
+ { name: 'Completed', color: 'green' },
432
+ ],
433
+ },
434
+ },
435
+ Priority: {
436
+ select: {
437
+ options: [
438
+ { name: 'High', color: 'red' },
439
+ { name: 'Medium', color: 'yellow' },
440
+ { name: 'Low', color: 'gray' },
441
+ ],
442
+ },
443
+ },
444
+ Tags: {
445
+ multi_select: {
446
+ options: [
447
+ { name: 'Bug', color: 'red' },
448
+ { name: 'Feature', color: 'blue' },
449
+ ],
450
+ },
451
+ },
452
+ 'Due Date': {
453
+ date: {},
454
+ },
455
+ },
456
+ });
457
+
458
+ return response;
459
+ }
460
+ ```
461
+
462
+ ### Update Database Properties
463
+
464
+ ```javascript
465
+ async function updateDatabase(databaseId) {
466
+ const response = await notion.databases.update({
467
+ database_id: databaseId,
468
+ title: [
469
+ {
470
+ text: {
471
+ content: 'Updated Task List',
472
+ },
473
+ },
474
+ ],
475
+ properties: {
476
+ Status: {
477
+ status: {
478
+ options: [
479
+ { name: 'To Do', color: 'red' },
480
+ { name: 'Doing', color: 'yellow' },
481
+ { name: 'Done', color: 'green' },
482
+ ],
483
+ },
484
+ },
485
+ },
486
+ });
487
+
488
+ return response;
489
+ }
490
+ ```
491
+
492
+ ## Blocks API
493
+
494
+ ### Retrieve Block Children
495
+
496
+ ```javascript
497
+ async function getBlockChildren(blockId) {
498
+ const response = await notion.blocks.children.list({
499
+ block_id: blockId,
500
+ page_size: 50,
501
+ });
502
+
503
+ console.log('Number of blocks:', response.results.length);
504
+ return response.results;
505
+ }
506
+ ```
507
+
508
+ ### Append Block Children
509
+
510
+ ```javascript
511
+ async function appendBlockChildren(blockId) {
512
+ const response = await notion.blocks.children.append({
513
+ block_id: blockId,
514
+ children: [
515
+ {
516
+ object: 'block',
517
+ type: 'heading_2',
518
+ heading_2: {
519
+ rich_text: [
520
+ {
521
+ type: 'text',
522
+ text: { content: 'New Section' },
523
+ },
524
+ ],
525
+ },
526
+ },
527
+ {
528
+ object: 'block',
529
+ type: 'paragraph',
530
+ paragraph: {
531
+ rich_text: [
532
+ {
533
+ type: 'text',
534
+ text: { content: 'This is a new paragraph.' },
535
+ },
536
+ ],
537
+ },
538
+ },
539
+ {
540
+ object: 'block',
541
+ type: 'to_do',
542
+ to_do: {
543
+ rich_text: [{ type: 'text', text: { content: 'Complete this task' } }],
544
+ checked: false,
545
+ },
546
+ },
547
+ ],
548
+ });
549
+
550
+ return response;
551
+ }
552
+ ```
553
+
554
+ ### Common Block Types
555
+
556
+ ```javascript
557
+ // Heading blocks
558
+ const heading1 = {
559
+ type: 'heading_1',
560
+ heading_1: {
561
+ rich_text: [{ text: { content: 'Heading 1' } }],
562
+ },
563
+ };
564
+
565
+ const heading2 = {
566
+ type: 'heading_2',
567
+ heading_2: {
568
+ rich_text: [{ text: { content: 'Heading 2' } }],
569
+ },
570
+ };
571
+
572
+ const heading3 = {
573
+ type: 'heading_3',
574
+ heading_3: {
575
+ rich_text: [{ text: { content: 'Heading 3' } }],
576
+ },
577
+ };
578
+
579
+ // Paragraph with formatting
580
+ const paragraph = {
581
+ type: 'paragraph',
582
+ paragraph: {
583
+ rich_text: [
584
+ { text: { content: 'Normal text ' } },
585
+ { text: { content: 'bold' }, annotations: { bold: true } },
586
+ { text: { content: ' and ' } },
587
+ { text: { content: 'italic' }, annotations: { italic: true } },
588
+ { text: { content: ' and ' } },
589
+ { text: { content: 'code' }, annotations: { code: true } },
590
+ ],
591
+ },
592
+ };
593
+
594
+ // Bulleted list item
595
+ const bulletedListItem = {
596
+ type: 'bulleted_list_item',
597
+ bulleted_list_item: {
598
+ rich_text: [{ text: { content: 'Bullet point' } }],
599
+ },
600
+ };
601
+
602
+ // Numbered list item
603
+ const numberedListItem = {
604
+ type: 'numbered_list_item',
605
+ numbered_list_item: {
606
+ rich_text: [{ text: { content: 'Numbered item' } }],
607
+ },
608
+ };
609
+
610
+ // To-do item
611
+ const toDo = {
612
+ type: 'to_do',
613
+ to_do: {
614
+ rich_text: [{ text: { content: 'Task to complete' } }],
615
+ checked: false,
616
+ },
617
+ };
618
+
619
+ // Toggle block (collapsible)
620
+ const toggle = {
621
+ type: 'toggle',
622
+ toggle: {
623
+ rich_text: [{ text: { content: 'Click to expand' } }],
624
+ },
625
+ };
626
+
627
+ // Quote
628
+ const quote = {
629
+ type: 'quote',
630
+ quote: {
631
+ rich_text: [{ text: { content: 'This is a quote' } }],
632
+ },
633
+ };
634
+
635
+ // Callout
636
+ const callout = {
637
+ type: 'callout',
638
+ callout: {
639
+ rich_text: [{ text: { content: 'Important note' } }],
640
+ icon: { emoji: '💡' },
641
+ },
642
+ };
643
+
644
+ // Code block
645
+ const codeBlock = {
646
+ type: 'code',
647
+ code: {
648
+ rich_text: [{ text: { content: 'const x = 42;' } }],
649
+ language: 'javascript',
650
+ },
651
+ };
652
+
653
+ // Divider
654
+ const divider = {
655
+ type: 'divider',
656
+ divider: {},
657
+ };
658
+
659
+ // Image
660
+ const image = {
661
+ type: 'image',
662
+ image: {
663
+ type: 'external',
664
+ external: {
665
+ url: 'https://example.com/image.png',
666
+ },
667
+ },
668
+ };
669
+
670
+ // Bookmark
671
+ const bookmark = {
672
+ type: 'bookmark',
673
+ bookmark: {
674
+ url: 'https://notion.so',
675
+ },
676
+ };
677
+ ```
678
+
679
+ ### Update a Block
680
+
681
+ ```javascript
682
+ async function updateBlock(blockId) {
683
+ const response = await notion.blocks.update({
684
+ block_id: blockId,
685
+ paragraph: {
686
+ rich_text: [
687
+ {
688
+ text: {
689
+ content: 'Updated paragraph content',
690
+ },
691
+ },
692
+ ],
693
+ },
694
+ });
695
+
696
+ return response;
697
+ }
698
+ ```
699
+
700
+ ### Delete a Block
701
+
702
+ ```javascript
703
+ async function deleteBlock(blockId) {
704
+ const response = await notion.blocks.delete({
705
+ block_id: blockId,
706
+ });
707
+
708
+ return response;
709
+ }
710
+ ```
711
+
712
+ ### Retrieve a Block
713
+
714
+ ```javascript
715
+ async function retrieveBlock(blockId) {
716
+ const response = await notion.blocks.retrieve({
717
+ block_id: blockId,
718
+ });
719
+
720
+ console.log('Block type:', response.type);
721
+ return response;
722
+ }
723
+ ```
724
+
725
+ ## Users API
726
+
727
+ ### List All Users
728
+
729
+ ```javascript
730
+ async function listUsers() {
731
+ const response = await notion.users.list({});
732
+
733
+ console.log('Users:', response.results);
734
+ return response.results;
735
+ }
736
+ ```
737
+
738
+ ### Retrieve a User
739
+
740
+ ```javascript
741
+ async function retrieveUser(userId) {
742
+ const response = await notion.users.retrieve({
743
+ user_id: userId,
744
+ });
745
+
746
+ console.log('User name:', response.name);
747
+ console.log('User type:', response.type);
748
+
749
+ return response;
750
+ }
751
+ ```
752
+
753
+ ### Retrieve Bot User (Your Integration)
754
+
755
+ ```javascript
756
+ async function retrieveBotUser() {
757
+ const response = await notion.users.me();
758
+
759
+ console.log('Bot name:', response.name);
760
+ console.log('Bot ID:', response.id);
761
+
762
+ return response;
763
+ }
764
+ ```
765
+
766
+ ## Search API
767
+
768
+ ### Basic Search
769
+
770
+ ```javascript
771
+ async function searchPages(query) {
772
+ const response = await notion.search({
773
+ query: query,
774
+ filter: {
775
+ value: 'page',
776
+ property: 'object',
777
+ },
778
+ sort: {
779
+ direction: 'descending',
780
+ timestamp: 'last_edited_time',
781
+ },
782
+ });
783
+
784
+ return response.results;
785
+ }
786
+ ```
787
+
788
+ ### Search for Databases
789
+
790
+ ```javascript
791
+ async function searchDatabases(query) {
792
+ const response = await notion.search({
793
+ query: query,
794
+ filter: {
795
+ value: 'database',
796
+ property: 'object',
797
+ },
798
+ });
799
+
800
+ return response.results;
801
+ }
802
+ ```
803
+
804
+ ### Search All Content
805
+
806
+ ```javascript
807
+ async function searchAll(query) {
808
+ const response = await notion.search({
809
+ query: query,
810
+ page_size: 100,
811
+ });
812
+
813
+ console.log(`Found ${response.results.length} results`);
814
+ return response.results;
815
+ }
816
+ ```
817
+
818
+ ## Comments API
819
+
820
+ ### Create a Comment
821
+
822
+ ```javascript
823
+ async function createComment(pageId) {
824
+ const response = await notion.comments.create({
825
+ parent: {
826
+ page_id: pageId,
827
+ },
828
+ rich_text: [
829
+ {
830
+ text: {
831
+ content: 'This is a comment on the page.',
832
+ },
833
+ },
834
+ ],
835
+ });
836
+
837
+ return response;
838
+ }
839
+ ```
840
+
841
+ ### Create a Discussion Comment (Reply)
842
+
843
+ ```javascript
844
+ async function createDiscussionComment(discussionId) {
845
+ const response = await notion.comments.create({
846
+ discussion_id: discussionId,
847
+ rich_text: [
848
+ {
849
+ text: {
850
+ content: 'This is a reply to an existing comment.',
851
+ },
852
+ },
853
+ ],
854
+ });
855
+
856
+ return response;
857
+ }
858
+ ```
859
+
860
+ ### List Comments
861
+
862
+ ```javascript
863
+ async function listComments(blockId) {
864
+ const response = await notion.comments.list({
865
+ block_id: blockId,
866
+ });
867
+
868
+ console.log('Comments:', response.results);
869
+ return response.results;
870
+ }
871
+ ```
872
+
873
+ ## Pagination
874
+
875
+ ### Manual Pagination
876
+
877
+ ```javascript
878
+ async function getAllPages(databaseId) {
879
+ let hasMore = true;
880
+ let startCursor = undefined;
881
+ let allResults = [];
882
+
883
+ while (hasMore) {
884
+ const response = await notion.databases.query({
885
+ database_id: databaseId,
886
+ start_cursor: startCursor,
887
+ page_size: 100,
888
+ });
889
+
890
+ allResults = allResults.concat(response.results);
891
+ hasMore = response.has_more;
892
+ startCursor = response.next_cursor;
893
+ }
894
+
895
+ console.log(`Retrieved ${allResults.length} total results`);
896
+ return allResults;
897
+ }
898
+ ```
899
+
900
+ ### Using Pagination Helpers
901
+
902
+ ```javascript
903
+ const { iteratePaginatedAPI, collectPaginatedAPI } = require('@notionhq/client');
904
+
905
+ // Iterate through paginated results
906
+ async function iterateBlocks(blockId) {
907
+ for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
908
+ block_id: blockId,
909
+ })) {
910
+ console.log('Block type:', block.type);
911
+ }
912
+ }
913
+
914
+ // Collect all paginated results at once
915
+ async function collectAllBlocks(blockId) {
916
+ const blocks = await collectPaginatedAPI(notion.blocks.children.list, {
917
+ block_id: blockId,
918
+ });
919
+
920
+ console.log(`Total blocks: ${blocks.length}`);
921
+ return blocks;
922
+ }
923
+ ```
924
+
925
+ ## Error Handling
926
+
927
+ ### Basic Error Handling
928
+
929
+ ```javascript
930
+ const { Client, APIErrorCode } = require('@notionhq/client');
931
+
932
+ const notion = new Client({ auth: process.env.NOTION_TOKEN });
933
+
934
+ async function handleErrors() {
935
+ try {
936
+ const response = await notion.pages.retrieve({
937
+ page_id: 'invalid-id',
938
+ });
939
+ } catch (error) {
940
+ if (error.code === APIErrorCode.ObjectNotFound) {
941
+ console.error('Page not found');
942
+ } else if (error.code === APIErrorCode.Unauthorized) {
943
+ console.error('Invalid API token');
944
+ } else if (error.code === APIErrorCode.RestrictedResource) {
945
+ console.error('Access denied - integration not shared with this resource');
946
+ } else if (error.code === APIErrorCode.RateLimited) {
947
+ console.error('Rate limit exceeded');
948
+ } else {
949
+ console.error('Error:', error.message);
950
+ }
951
+ }
952
+ }
953
+ ```
954
+
955
+ ### TypeScript Error Handling
956
+
957
+ ```typescript
958
+ import { Client, isNotionClientError, ClientErrorCode, APIErrorCode } from '@notionhq/client';
959
+
960
+ const notion = new Client({ auth: process.env.NOTION_TOKEN });
961
+
962
+ async function handleErrorsTypescript() {
963
+ try {
964
+ const response = await notion.pages.retrieve({
965
+ page_id: 'some-id',
966
+ });
967
+ } catch (error: unknown) {
968
+ if (isNotionClientError(error)) {
969
+ switch (error.code) {
970
+ case ClientErrorCode.RequestTimeout:
971
+ console.error('Request timed out');
972
+ break;
973
+ case APIErrorCode.ObjectNotFound:
974
+ console.error('Object not found');
975
+ break;
976
+ case APIErrorCode.Unauthorized:
977
+ console.error('Unauthorized');
978
+ break;
979
+ case APIErrorCode.RestrictedResource:
980
+ console.error('Access denied');
981
+ break;
982
+ case APIErrorCode.RateLimited:
983
+ console.error('Rate limited');
984
+ break;
985
+ default:
986
+ console.error('Unknown error:', error);
987
+ }
988
+ }
989
+ }
990
+ }
991
+ ```
992
+
993
+ ### Common Error Codes
994
+
995
+ | Error Code | Description |
996
+ |------------|-------------|
997
+ | `ObjectNotFound` | The requested resource doesn't exist |
998
+ | `Unauthorized` | Invalid or missing API token |
999
+ | `RestrictedResource` | Integration doesn't have access to the resource |
1000
+ | `RateLimited` | Too many requests, retry after delay |
1001
+ | `ValidationError` | Invalid request parameters |
1002
+ | `ConflictError` | Resource conflict (e.g., duplicate) |
1003
+ | `RequestTimeout` | Request took too long |
1004
+
1005
+ ## Advanced Features
1006
+
1007
+ ### Custom Request
1008
+
1009
+ ```javascript
1010
+ async function customRequest() {
1011
+ const response = await notion.request({
1012
+ path: 'comments',
1013
+ method: 'post',
1014
+ body: {
1015
+ parent: { page_id: '5c6a28216bb14a7eb6e1c50111515c3d' },
1016
+ rich_text: [{ text: { content: 'Custom request comment' } }],
1017
+ },
1018
+ });
1019
+
1020
+ return response;
1021
+ }
1022
+ ```
1023
+
1024
+ ### TypeScript Type Guards
1025
+
1026
+ ```typescript
1027
+ import { isFullPageOrDataSource, isFullBlock } from '@notionhq/client';
1028
+
1029
+ async function useTypeGuards(dataSourceId: string) {
1030
+ const response = await notion.dataSources.query({
1031
+ data_source_id: dataSourceId,
1032
+ });
1033
+
1034
+ for (const page of response.results) {
1035
+ if (isFullPageOrDataSource(page)) {
1036
+ // Now TypeScript knows page has full properties
1037
+ console.log('Created at:', page.created_time);
1038
+ console.log('Last edited:', page.last_edited_time);
1039
+ }
1040
+ }
1041
+ }
1042
+
1043
+ async function checkBlockType(blockId: string) {
1044
+ const block = await notion.blocks.retrieve({ block_id: blockId });
1045
+
1046
+ if (isFullBlock(block)) {
1047
+ console.log('Block type:', block.type);
1048
+ }
1049
+ }
1050
+ ```
1051
+
1052
+ ### Rich Text Formatting
1053
+
1054
+ ```javascript
1055
+ const richText = [
1056
+ {
1057
+ type: 'text',
1058
+ text: { content: 'Plain text ' },
1059
+ },
1060
+ {
1061
+ type: 'text',
1062
+ text: { content: 'bold text' },
1063
+ annotations: { bold: true },
1064
+ },
1065
+ {
1066
+ type: 'text',
1067
+ text: { content: ' ' },
1068
+ },
1069
+ {
1070
+ type: 'text',
1071
+ text: { content: 'italic text' },
1072
+ annotations: { italic: true },
1073
+ },
1074
+ {
1075
+ type: 'text',
1076
+ text: { content: ' ' },
1077
+ },
1078
+ {
1079
+ type: 'text',
1080
+ text: { content: 'strikethrough' },
1081
+ annotations: { strikethrough: true },
1082
+ },
1083
+ {
1084
+ type: 'text',
1085
+ text: { content: ' ' },
1086
+ },
1087
+ {
1088
+ type: 'text',
1089
+ text: { content: 'underline' },
1090
+ annotations: { underline: true },
1091
+ },
1092
+ {
1093
+ type: 'text',
1094
+ text: { content: ' ' },
1095
+ },
1096
+ {
1097
+ type: 'text',
1098
+ text: { content: 'code' },
1099
+ annotations: { code: true },
1100
+ },
1101
+ {
1102
+ type: 'text',
1103
+ text: { content: ' ' },
1104
+ },
1105
+ {
1106
+ type: 'text',
1107
+ text: { content: 'colored text' },
1108
+ annotations: { color: 'red' },
1109
+ },
1110
+ {
1111
+ type: 'text',
1112
+ text: { content: ' ' },
1113
+ },
1114
+ {
1115
+ type: 'text',
1116
+ text: { content: 'link text', link: { url: 'https://notion.so' } },
1117
+ },
1118
+ ];
1119
+ ```
1120
+
1121
+ ### Property Types
1122
+
1123
+ ```javascript
1124
+ // Title property
1125
+ const titleProperty = {
1126
+ title: [
1127
+ {
1128
+ text: { content: 'Page Title' },
1129
+ },
1130
+ ],
1131
+ };
1132
+
1133
+ // Rich text property
1134
+ const richTextProperty = {
1135
+ rich_text: [
1136
+ {
1137
+ text: { content: 'Some text content' },
1138
+ },
1139
+ ],
1140
+ };
1141
+
1142
+ // Number property
1143
+ const numberProperty = {
1144
+ number: 42,
1145
+ };
1146
+
1147
+ // Select property
1148
+ const selectProperty = {
1149
+ select: {
1150
+ name: 'Option 1',
1151
+ },
1152
+ };
1153
+
1154
+ // Multi-select property
1155
+ const multiSelectProperty = {
1156
+ multi_select: [
1157
+ { name: 'Tag 1' },
1158
+ { name: 'Tag 2' },
1159
+ ],
1160
+ };
1161
+
1162
+ // Date property
1163
+ const dateProperty = {
1164
+ date: {
1165
+ start: '2025-01-01',
1166
+ end: '2025-01-31',
1167
+ },
1168
+ };
1169
+
1170
+ // Checkbox property
1171
+ const checkboxProperty = {
1172
+ checkbox: true,
1173
+ };
1174
+
1175
+ // URL property
1176
+ const urlProperty = {
1177
+ url: 'https://notion.so',
1178
+ };
1179
+
1180
+ // Email property
1181
+ const emailProperty = {
1182
+ email: 'user@example.com',
1183
+ };
1184
+
1185
+ // Phone number property
1186
+ const phoneProperty = {
1187
+ phone_number: '+1-555-0100',
1188
+ };
1189
+
1190
+ // Status property
1191
+ const statusProperty = {
1192
+ status: {
1193
+ name: 'In Progress',
1194
+ },
1195
+ };
1196
+
1197
+ // People property
1198
+ const peopleProperty = {
1199
+ people: [
1200
+ {
1201
+ object: 'user',
1202
+ id: 'user-id-here',
1203
+ },
1204
+ ],
1205
+ };
1206
+
1207
+ // Files property
1208
+ const filesProperty = {
1209
+ files: [
1210
+ {
1211
+ name: 'Document.pdf',
1212
+ type: 'external',
1213
+ external: {
1214
+ url: 'https://example.com/document.pdf',
1215
+ },
1216
+ },
1217
+ ],
1218
+ };
1219
+
1220
+ // Relation property
1221
+ const relationProperty = {
1222
+ relation: [
1223
+ {
1224
+ id: 'related-page-id',
1225
+ },
1226
+ ],
1227
+ };
1228
+ ```
1229
+
1230
+ ## Complete Example: Task Management System
1231
+
1232
+ ```javascript
1233
+ const { Client } = require('@notionhq/client');
1234
+
1235
+ const notion = new Client({
1236
+ auth: process.env.NOTION_TOKEN,
1237
+ });
1238
+
1239
+ async function createTaskManagementSystem() {
1240
+ // 1. Create a database for tasks
1241
+ const database = await notion.databases.create({
1242
+ parent: {
1243
+ type: 'page_id',
1244
+ page_id: process.env.PARENT_PAGE_ID,
1245
+ },
1246
+ title: [
1247
+ {
1248
+ type: 'text',
1249
+ text: { content: 'Task Manager' },
1250
+ },
1251
+ ],
1252
+ properties: {
1253
+ Name: {
1254
+ title: {},
1255
+ },
1256
+ Status: {
1257
+ status: {
1258
+ options: [
1259
+ { name: 'Not started', color: 'red' },
1260
+ { name: 'In progress', color: 'yellow' },
1261
+ { name: 'Completed', color: 'green' },
1262
+ ],
1263
+ },
1264
+ },
1265
+ Priority: {
1266
+ select: {
1267
+ options: [
1268
+ { name: 'High', color: 'red' },
1269
+ { name: 'Medium', color: 'yellow' },
1270
+ { name: 'Low', color: 'gray' },
1271
+ ],
1272
+ },
1273
+ },
1274
+ 'Due Date': {
1275
+ date: {},
1276
+ },
1277
+ Tags: {
1278
+ multi_select: {
1279
+ options: [
1280
+ { name: 'Bug', color: 'red' },
1281
+ { name: 'Feature', color: 'blue' },
1282
+ { name: 'Documentation', color: 'purple' },
1283
+ ],
1284
+ },
1285
+ },
1286
+ Assignee: {
1287
+ people: {},
1288
+ },
1289
+ },
1290
+ });
1291
+
1292
+ console.log('Database created:', database.id);
1293
+
1294
+ // 2. Create a task
1295
+ const task = await notion.pages.create({
1296
+ parent: {
1297
+ database_id: database.id,
1298
+ },
1299
+ properties: {
1300
+ Name: {
1301
+ title: [
1302
+ {
1303
+ text: { content: 'Implement user authentication' },
1304
+ },
1305
+ ],
1306
+ },
1307
+ Status: {
1308
+ status: { name: 'In progress' },
1309
+ },
1310
+ Priority: {
1311
+ select: { name: 'High' },
1312
+ },
1313
+ 'Due Date': {
1314
+ date: { start: '2025-02-01' },
1315
+ },
1316
+ Tags: {
1317
+ multi_select: [{ name: 'Feature' }],
1318
+ },
1319
+ },
1320
+ });
1321
+
1322
+ console.log('Task created:', task.id);
1323
+
1324
+ // 3. Add content to the task
1325
+ await notion.blocks.children.append({
1326
+ block_id: task.id,
1327
+ children: [
1328
+ {
1329
+ object: 'block',
1330
+ type: 'heading_2',
1331
+ heading_2: {
1332
+ rich_text: [{ text: { content: 'Task Details' } }],
1333
+ },
1334
+ },
1335
+ {
1336
+ object: 'block',
1337
+ type: 'paragraph',
1338
+ paragraph: {
1339
+ rich_text: [
1340
+ {
1341
+ text: {
1342
+ content: 'Implement OAuth 2.0 authentication for user login.',
1343
+ },
1344
+ },
1345
+ ],
1346
+ },
1347
+ },
1348
+ {
1349
+ object: 'block',
1350
+ type: 'heading_3',
1351
+ heading_3: {
1352
+ rich_text: [{ text: { content: 'Requirements' } }],
1353
+ },
1354
+ },
1355
+ {
1356
+ object: 'block',
1357
+ type: 'to_do',
1358
+ to_do: {
1359
+ rich_text: [{ text: { content: 'Set up OAuth provider' } }],
1360
+ checked: false,
1361
+ },
1362
+ },
1363
+ {
1364
+ object: 'block',
1365
+ type: 'to_do',
1366
+ to_do: {
1367
+ rich_text: [{ text: { content: 'Create login page' } }],
1368
+ checked: false,
1369
+ },
1370
+ },
1371
+ {
1372
+ object: 'block',
1373
+ type: 'to_do',
1374
+ to_do: {
1375
+ rich_text: [{ text: { content: 'Test authentication flow' } }],
1376
+ checked: false,
1377
+ },
1378
+ },
1379
+ ],
1380
+ });
1381
+
1382
+ // 4. Add a comment
1383
+ await notion.comments.create({
1384
+ parent: { page_id: task.id },
1385
+ rich_text: [
1386
+ {
1387
+ text: { content: 'Starting work on this task today.' },
1388
+ },
1389
+ ],
1390
+ });
1391
+
1392
+ // 5. Query all high priority tasks
1393
+ const highPriorityTasks = await notion.databases.query({
1394
+ database_id: database.id,
1395
+ filter: {
1396
+ property: 'Priority',
1397
+ select: {
1398
+ equals: 'High',
1399
+ },
1400
+ },
1401
+ sorts: [
1402
+ {
1403
+ property: 'Due Date',
1404
+ direction: 'ascending',
1405
+ },
1406
+ ],
1407
+ });
1408
+
1409
+ console.log('High priority tasks:', highPriorityTasks.results.length);
1410
+
1411
+ // 6. Update task status
1412
+ await notion.pages.update({
1413
+ page_id: task.id,
1414
+ properties: {
1415
+ Status: {
1416
+ status: { name: 'Completed' },
1417
+ },
1418
+ },
1419
+ });
1420
+
1421
+ console.log('Task marked as completed');
1422
+ }
1423
+
1424
+ // Run the example
1425
+ createTaskManagementSystem().catch(console.error);
1426
+ ```
1427
+
1428
+ ## Useful Links
1429
+
1430
+ - Documentation: https://developers.notion.com/
1431
+ - API Reference: https://developers.notion.com/reference/
1432
+ - SDK Repository: https://github.com/makenotion/notion-sdk-js
1433
+ - NPM Package: https://www.npmjs.com/package/@notionhq/client
1434
+ - Create Integration: https://www.notion.com/my-integrations
1435
+ - Community: Notion Developers Slack