@visus-io/notion-sdk-ts 1.0.0 → 2.0.1
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.
- package/README.md +56 -786
- package/dist/api/base.api.d.ts +161 -0
- package/dist/api/base.api.js +228 -0
- package/dist/api/blocks.api.d.ts +3687 -4
- package/dist/api/blocks.api.js +16 -47
- package/dist/api/comments.api.d.ts +259 -4
- package/dist/api/comments.api.js +11 -29
- package/dist/api/dataSources.api.d.ts +788 -4
- package/dist/api/dataSources.api.js +14 -28
- package/dist/api/databases.api.d.ts +513 -14
- package/dist/api/databases.api.js +25 -50
- package/dist/api/fileUploads.api.d.ts +25 -3
- package/dist/api/fileUploads.api.js +7 -2
- package/dist/api/index.d.ts +0 -1
- package/dist/api/index.js +0 -1
- package/dist/api/pages.api.d.ts +864 -3
- package/dist/api/pages.api.js +14 -28
- package/dist/api/search.api.d.ts +9 -7
- package/dist/api/search.api.js +12 -17
- package/dist/api/users.api.d.ts +40 -4
- package/dist/api/users.api.js +12 -35
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/errors.d.ts +0 -1
- package/dist/errors.js +0 -1
- package/dist/helpers/block.helpers.d.ts +0 -1
- package/dist/helpers/block.helpers.js +0 -1
- package/dist/helpers/file.helpers.d.ts +0 -1
- package/dist/helpers/file.helpers.js +0 -1
- package/dist/helpers/filter.helpers.d.ts +0 -1
- package/dist/helpers/filter.helpers.js +0 -1
- package/dist/helpers/index.d.ts +0 -1
- package/dist/helpers/index.js +0 -1
- package/dist/helpers/pagination.helpers.d.ts +0 -1
- package/dist/helpers/pagination.helpers.js +0 -1
- package/dist/helpers/parent.helpers.d.ts +10 -3
- package/dist/helpers/parent.helpers.js +10 -4
- package/dist/helpers/property.helpers.d.ts +0 -1
- package/dist/helpers/property.helpers.js +0 -1
- package/dist/helpers/richText.helpers.d.ts +0 -1
- package/dist/helpers/richText.helpers.js +0 -1
- package/dist/helpers/sort.helpers.d.ts +0 -1
- package/dist/helpers/sort.helpers.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/models/base.model.d.ts +0 -1
- package/dist/models/base.model.js +0 -1
- package/dist/models/block.model.d.ts +0 -1
- package/dist/models/block.model.js +0 -1
- package/dist/models/comment.model.d.ts +0 -1
- package/dist/models/comment.model.js +0 -1
- package/dist/models/dataSource.model.d.ts +0 -1
- package/dist/models/dataSource.model.js +0 -1
- package/dist/models/database.model.d.ts +0 -1
- package/dist/models/database.model.js +0 -1
- package/dist/models/fileUpload.model.d.ts +0 -1
- package/dist/models/fileUpload.model.js +0 -1
- package/dist/models/index.d.ts +0 -1
- package/dist/models/index.js +0 -1
- package/dist/models/page.model.d.ts +0 -1
- package/dist/models/page.model.js +0 -1
- package/dist/models/richText.model.d.ts +0 -1
- package/dist/models/richText.model.js +0 -1
- package/dist/models/user.model.d.ts +0 -1
- package/dist/models/user.model.js +0 -1
- package/dist/notion.d.ts +0 -1
- package/dist/notion.js +0 -1
- package/dist/schemas/block.schema.d.ts +0 -1
- package/dist/schemas/block.schema.js +0 -1
- package/dist/schemas/codeLanguages.d.ts +0 -1
- package/dist/schemas/codeLanguages.js +0 -1
- package/dist/schemas/colors.d.ts +0 -1
- package/dist/schemas/colors.js +0 -1
- package/dist/schemas/comment.schema.d.ts +0 -1
- package/dist/schemas/comment.schema.js +0 -1
- package/dist/schemas/dataSource.schema.d.ts +0 -1
- package/dist/schemas/dataSource.schema.js +0 -1
- package/dist/schemas/database.schema.d.ts +0 -1
- package/dist/schemas/database.schema.js +0 -1
- package/dist/schemas/emoji.schema.d.ts +0 -1
- package/dist/schemas/emoji.schema.js +0 -1
- package/dist/schemas/file.schema.d.ts +0 -1
- package/dist/schemas/file.schema.js +0 -1
- package/dist/schemas/fileUpload.schema.d.ts +0 -1
- package/dist/schemas/fileUpload.schema.js +0 -1
- package/dist/schemas/index.d.ts +0 -1
- package/dist/schemas/index.js +0 -1
- package/dist/schemas/page.schema.d.ts +0 -1
- package/dist/schemas/page.schema.js +0 -1
- package/dist/schemas/pageProperties.schema.d.ts +0 -1
- package/dist/schemas/pageProperties.schema.js +0 -1
- package/dist/schemas/pagination.schema.d.ts +5 -2
- package/dist/schemas/pagination.schema.js +2 -1
- package/dist/schemas/parent.schema.d.ts +0 -1
- package/dist/schemas/parent.schema.js +0 -1
- package/dist/schemas/propertyObjects.schema.d.ts +0 -1
- package/dist/schemas/propertyObjects.schema.js +0 -1
- package/dist/schemas/richText.schema.d.ts +0 -1
- package/dist/schemas/richText.schema.js +0 -1
- package/dist/schemas/user.schema.d.ts +0 -1
- package/dist/schemas/user.schema.js +0 -1
- package/dist/validation.d.ts +0 -1
- package/dist/validation.js +0 -1
- package/package.json +1 -1
- package/dist/api/blocks.api.d.ts.map +0 -1
- package/dist/api/blocks.api.js.map +0 -1
- package/dist/api/comments.api.d.ts.map +0 -1
- package/dist/api/comments.api.js.map +0 -1
- package/dist/api/dataSources.api.d.ts.map +0 -1
- package/dist/api/dataSources.api.js.map +0 -1
- package/dist/api/databases.api.d.ts.map +0 -1
- package/dist/api/databases.api.js.map +0 -1
- package/dist/api/fileUploads.api.d.ts.map +0 -1
- package/dist/api/fileUploads.api.js.map +0 -1
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/pages.api.d.ts.map +0 -1
- package/dist/api/pages.api.js.map +0 -1
- package/dist/api/search.api.d.ts.map +0 -1
- package/dist/api/search.api.js.map +0 -1
- package/dist/api/users.api.d.ts.map +0 -1
- package/dist/api/users.api.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/helpers/block.helpers.d.ts.map +0 -1
- package/dist/helpers/block.helpers.js.map +0 -1
- package/dist/helpers/file.helpers.d.ts.map +0 -1
- package/dist/helpers/file.helpers.js.map +0 -1
- package/dist/helpers/filter.helpers.d.ts.map +0 -1
- package/dist/helpers/filter.helpers.js.map +0 -1
- package/dist/helpers/index.d.ts.map +0 -1
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/pagination.helpers.d.ts.map +0 -1
- package/dist/helpers/pagination.helpers.js.map +0 -1
- package/dist/helpers/parent.helpers.d.ts.map +0 -1
- package/dist/helpers/parent.helpers.js.map +0 -1
- package/dist/helpers/property.helpers.d.ts.map +0 -1
- package/dist/helpers/property.helpers.js.map +0 -1
- package/dist/helpers/richText.helpers.d.ts.map +0 -1
- package/dist/helpers/richText.helpers.js.map +0 -1
- package/dist/helpers/sort.helpers.d.ts.map +0 -1
- package/dist/helpers/sort.helpers.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/models/base.model.d.ts.map +0 -1
- package/dist/models/base.model.js.map +0 -1
- package/dist/models/block.model.d.ts.map +0 -1
- package/dist/models/block.model.js.map +0 -1
- package/dist/models/comment.model.d.ts.map +0 -1
- package/dist/models/comment.model.js.map +0 -1
- package/dist/models/dataSource.model.d.ts.map +0 -1
- package/dist/models/dataSource.model.js.map +0 -1
- package/dist/models/database.model.d.ts.map +0 -1
- package/dist/models/database.model.js.map +0 -1
- package/dist/models/fileUpload.model.d.ts.map +0 -1
- package/dist/models/fileUpload.model.js.map +0 -1
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js.map +0 -1
- package/dist/models/page.model.d.ts.map +0 -1
- package/dist/models/page.model.js.map +0 -1
- package/dist/models/richText.model.d.ts.map +0 -1
- package/dist/models/richText.model.js.map +0 -1
- package/dist/models/user.model.d.ts.map +0 -1
- package/dist/models/user.model.js.map +0 -1
- package/dist/notion.d.ts.map +0 -1
- package/dist/notion.js.map +0 -1
- package/dist/schemas/block.schema.d.ts.map +0 -1
- package/dist/schemas/block.schema.js.map +0 -1
- package/dist/schemas/codeLanguages.d.ts.map +0 -1
- package/dist/schemas/codeLanguages.js.map +0 -1
- package/dist/schemas/colors.d.ts.map +0 -1
- package/dist/schemas/colors.js.map +0 -1
- package/dist/schemas/comment.schema.d.ts.map +0 -1
- package/dist/schemas/comment.schema.js.map +0 -1
- package/dist/schemas/dataSource.schema.d.ts.map +0 -1
- package/dist/schemas/dataSource.schema.js.map +0 -1
- package/dist/schemas/database.schema.d.ts.map +0 -1
- package/dist/schemas/database.schema.js.map +0 -1
- package/dist/schemas/emoji.schema.d.ts.map +0 -1
- package/dist/schemas/emoji.schema.js.map +0 -1
- package/dist/schemas/file.schema.d.ts.map +0 -1
- package/dist/schemas/file.schema.js.map +0 -1
- package/dist/schemas/fileUpload.schema.d.ts.map +0 -1
- package/dist/schemas/fileUpload.schema.js.map +0 -1
- package/dist/schemas/index.d.ts.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/page.schema.d.ts.map +0 -1
- package/dist/schemas/page.schema.js.map +0 -1
- package/dist/schemas/pageProperties.schema.d.ts.map +0 -1
- package/dist/schemas/pageProperties.schema.js.map +0 -1
- package/dist/schemas/pagination.schema.d.ts.map +0 -1
- package/dist/schemas/pagination.schema.js.map +0 -1
- package/dist/schemas/parent.schema.d.ts.map +0 -1
- package/dist/schemas/parent.schema.js.map +0 -1
- package/dist/schemas/propertyObjects.schema.d.ts.map +0 -1
- package/dist/schemas/propertyObjects.schema.js.map +0 -1
- package/dist/schemas/richText.schema.d.ts.map +0 -1
- package/dist/schemas/richText.schema.js.map +0 -1
- package/dist/schemas/user.schema.d.ts.map +0 -1
- package/dist/schemas/user.schema.js.map +0 -1
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,42 +5,12 @@
|
|
|
5
5
|
[](https://sonarcloud.io/summary/overall?id=visus%3Anotion-sdk-ts)
|
|
6
6
|
[](https://sonarcloud.io/summary/overall?id=visus%3Anotion-sdk-ts)
|
|
7
7
|
|
|
8
|
-

|
|
8
|
+
[](https://www.npmjs.com/package/@visus-io/notion-sdk-ts)
|
|
9
9
|

|
|
10
10
|

|
|
11
11
|
|
|
12
12
|
A type-safe TypeScript SDK for the Notion API with Zod validation, OOP models, and ergonomic helpers.
|
|
13
13
|
|
|
14
|
-
## Table of Contents
|
|
15
|
-
|
|
16
|
-
- [Features](#features)
|
|
17
|
-
- [Installation](#installation)
|
|
18
|
-
- [Quick Start](#quick-start)
|
|
19
|
-
- [Helpers](#helpers)
|
|
20
|
-
- [Rich Text](#rich-text)
|
|
21
|
-
- [Block Builder](#block-builder)
|
|
22
|
-
- [Page Properties](#page-properties)
|
|
23
|
-
- [Filters](#filters)
|
|
24
|
-
- [Sorting](#sorting)
|
|
25
|
-
- [Parent, Icon, Cover & File](#parent-icon-cover--file)
|
|
26
|
-
- [Models](#models)
|
|
27
|
-
- [Error Handling](#error-handling)
|
|
28
|
-
- [Request Size Limits](#request-size-limits)
|
|
29
|
-
- [Pagination](#pagination)
|
|
30
|
-
- [Configuration](#configuration)
|
|
31
|
-
- [API Reference](#api-reference)
|
|
32
|
-
- [Pages](#pages-api)
|
|
33
|
-
- [Blocks](#blocks-api)
|
|
34
|
-
- [Databases](#databases-api)
|
|
35
|
-
- [Data Sources](#data-sources-api)
|
|
36
|
-
- [Comments](#comments-api)
|
|
37
|
-
- [Search](#search-api)
|
|
38
|
-
- [Users](#users-api)
|
|
39
|
-
- [File Uploads](#file-uploads-api)
|
|
40
|
-
- [TypeScript Support](#typescript-support)
|
|
41
|
-
- [Development](#development)
|
|
42
|
-
- [Project Structure](#project-structure)
|
|
43
|
-
|
|
44
14
|
## Features
|
|
45
15
|
|
|
46
16
|
- **Type-safe** Zod v4 runtime validation on every API response; full TypeScript declarations
|
|
@@ -58,19 +28,12 @@ A type-safe TypeScript SDK for the Notion API with Zod validation, OOP models, a
|
|
|
58
28
|
npm install @visus-io/notion-sdk-ts
|
|
59
29
|
```
|
|
60
30
|
|
|
31
|
+
**Requirements:** Node.js 18+ (uses native `fetch`)
|
|
32
|
+
|
|
61
33
|
## Quick Start
|
|
62
34
|
|
|
63
35
|
```typescript
|
|
64
|
-
import {
|
|
65
|
-
Notion,
|
|
66
|
-
block,
|
|
67
|
-
richText,
|
|
68
|
-
filter,
|
|
69
|
-
sort,
|
|
70
|
-
prop,
|
|
71
|
-
parent,
|
|
72
|
-
paginate,
|
|
73
|
-
} from '@visus-io/notion-sdk-ts';
|
|
36
|
+
import { Notion, block, richText, filter, sort, prop, parent } from '@visus-io/notion-sdk-ts';
|
|
74
37
|
|
|
75
38
|
const notion = new Notion({ auth: process.env.NOTION_TOKEN });
|
|
76
39
|
|
|
@@ -79,13 +42,15 @@ const page = await notion.pages.retrieve('page-id');
|
|
|
79
42
|
console.log(page.getTitle());
|
|
80
43
|
|
|
81
44
|
// Create a page in a database
|
|
45
|
+
const database = await notion.databases.retrieve('database-id');
|
|
46
|
+
const dataSourceId = database.dataSources[0].id;
|
|
47
|
+
|
|
82
48
|
await notion.pages.create({
|
|
83
|
-
parent: parent.
|
|
49
|
+
parent: parent.dataSource(dataSourceId, database.id),
|
|
84
50
|
properties: {
|
|
85
51
|
Name: prop.title('New Task'),
|
|
86
52
|
Status: prop.status('In Progress'),
|
|
87
53
|
Priority: prop.select('High'),
|
|
88
|
-
'Due Date': prop.date('2025-03-01'),
|
|
89
54
|
},
|
|
90
55
|
});
|
|
91
56
|
|
|
@@ -94,14 +59,11 @@ await notion.blocks.children.append('page-id', {
|
|
|
94
59
|
children: [
|
|
95
60
|
block.heading2('Meeting Notes'),
|
|
96
61
|
block.paragraph('Discussed the roadmap for Q2.'),
|
|
97
|
-
block.paragraph(richText('Action item: ').build().concat(richText('ship v2').bold().build())),
|
|
98
62
|
block.toDo('Follow up with design', { checked: false }),
|
|
99
|
-
block.divider(),
|
|
100
|
-
block.code('console.log("hello")', 'typescript'),
|
|
101
63
|
],
|
|
102
64
|
});
|
|
103
65
|
|
|
104
|
-
// Query a database with
|
|
66
|
+
// Query a database with filters
|
|
105
67
|
const results = await notion.databases.query('database-id', {
|
|
106
68
|
filter: filter.and(
|
|
107
69
|
filter.status('Status').equals('In Progress'),
|
|
@@ -109,781 +71,89 @@ const results = await notion.databases.query('database-id', {
|
|
|
109
71
|
),
|
|
110
72
|
sorts: [sort.property('Due Date').ascending()],
|
|
111
73
|
});
|
|
112
|
-
|
|
113
|
-
for (const page of results.results) {
|
|
114
|
-
console.log(page.getTitle(), page.url);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Search across workspace
|
|
118
|
-
const search = await notion.search.query({
|
|
119
|
-
query: 'project planning',
|
|
120
|
-
filter: { property: 'object', value: 'page' },
|
|
121
|
-
});
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Helpers
|
|
125
|
-
|
|
126
|
-
The SDK provides namespace objects that eliminate the verbose JSON the Notion API requires. All text-accepting helpers accept a `string`, a `RichTextBuilder`, or a raw `NotionRichText` array.
|
|
127
|
-
|
|
128
|
-
### Rich Text
|
|
129
|
-
|
|
130
|
-
Build formatted rich text with a chainable API:
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
import { richText } from '@visus-io/notion-sdk-ts';
|
|
134
|
-
|
|
135
|
-
// Plain text
|
|
136
|
-
richText('Hello world').build();
|
|
137
|
-
|
|
138
|
-
// Chained formatting
|
|
139
|
-
richText('Important').bold().italic().color('red').build();
|
|
140
|
-
|
|
141
|
-
// Link
|
|
142
|
-
richText('Notion').link('https://notion.so').build();
|
|
143
|
-
|
|
144
|
-
// Combine multiple segments
|
|
145
|
-
richText.join(
|
|
146
|
-
richText('Normal '),
|
|
147
|
-
richText('bold').bold(),
|
|
148
|
-
richText(' and '),
|
|
149
|
-
richText('italic').italic(),
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
// Mentions
|
|
153
|
-
richText.mentionPage('page-id').build();
|
|
154
|
-
richText.mentionDatabase('db-id').build();
|
|
155
|
-
richText.mentionUser({ object: 'user', id: 'user-id' }).build();
|
|
156
|
-
richText.mentionDate('2025-03-01').build();
|
|
157
|
-
richText.mentionLinkPreview('https://example.com').build();
|
|
158
|
-
|
|
159
|
-
// Inline equation
|
|
160
|
-
richText.equation('E=mc^2').build();
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Block Builder
|
|
164
|
-
|
|
165
|
-
Factory functions for all 31 block types. Returns plain objects ready for `blocks.children.append()` or `pages.create()`:
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
import { block, richText } from '@visus-io/notion-sdk-ts';
|
|
169
|
-
|
|
170
|
-
const children = [
|
|
171
|
-
// Text blocks (accept string, RichTextBuilder, or NotionRichText)
|
|
172
|
-
block.heading1('Title'),
|
|
173
|
-
block.heading2('Subtitle', { isToggleable: true }),
|
|
174
|
-
block.paragraph('Plain text'),
|
|
175
|
-
block.paragraph(richText('Styled text').bold().color('blue')),
|
|
176
|
-
block.bulletedListItem('First item'),
|
|
177
|
-
block.numberedListItem('Step one'),
|
|
178
|
-
block.toDo('Task', { checked: true }),
|
|
179
|
-
block.toggle('Click to expand', { children: [block.paragraph('Hidden content')] }),
|
|
180
|
-
block.quote('A wise saying'),
|
|
181
|
-
block.callout('Heads up!', { icon: { type: 'emoji', emoji: '⚠️' } }),
|
|
182
|
-
|
|
183
|
-
// Code & math
|
|
184
|
-
block.code('const x = 42;', 'typescript', { caption: 'Example' }),
|
|
185
|
-
block.equation('\\sum_{i=1}^{n} i'),
|
|
186
|
-
|
|
187
|
-
// Media (accept URL string or FileSource object)
|
|
188
|
-
block.image('https://example.com/photo.png', { caption: 'Photo' }),
|
|
189
|
-
block.video('https://example.com/video.mp4'),
|
|
190
|
-
block.audio('https://example.com/song.mp3'),
|
|
191
|
-
block.file('https://example.com/doc.pdf'),
|
|
192
|
-
block.pdf('https://example.com/doc.pdf'),
|
|
193
|
-
|
|
194
|
-
// Embeds
|
|
195
|
-
block.embed('https://twitter.com/example/status/123'),
|
|
196
|
-
block.bookmark('https://example.com', { caption: 'Example site' }),
|
|
197
|
-
block.linkPreview('https://github.com/example/repo'),
|
|
198
|
-
|
|
199
|
-
// Structural
|
|
200
|
-
block.divider(),
|
|
201
|
-
block.breadcrumb(),
|
|
202
|
-
block.tableOfContents(),
|
|
203
|
-
block.table(3, {
|
|
204
|
-
hasColumnHeader: true,
|
|
205
|
-
children: [
|
|
206
|
-
block.tableRow(['Name', 'Role', 'Status']),
|
|
207
|
-
block.tableRow(['Alice', 'Engineer', 'Active']),
|
|
208
|
-
],
|
|
209
|
-
}),
|
|
210
|
-
block.columnList([[block.paragraph('Column 1')], [block.paragraph('Column 2')]]),
|
|
211
|
-
|
|
212
|
-
// Synced blocks
|
|
213
|
-
block.syncedBlock({ children: [block.paragraph('Original content')] }),
|
|
214
|
-
block.syncedBlock({ syncedFrom: 'source-block-id' }),
|
|
215
|
-
];
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Page Properties
|
|
219
|
-
|
|
220
|
-
Factory functions for setting page property values when creating or updating pages:
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
import { prop, richText } from '@visus-io/notion-sdk-ts';
|
|
224
|
-
|
|
225
|
-
const properties = {
|
|
226
|
-
Name: prop.title('My Task'),
|
|
227
|
-
Description: prop.richText('Some notes'),
|
|
228
|
-
Notes: prop.richText(richText('Important').bold()),
|
|
229
|
-
Score: prop.number(95),
|
|
230
|
-
Done: prop.checkbox(true),
|
|
231
|
-
Priority: prop.select('High'),
|
|
232
|
-
Tags: prop.multiSelect(['urgent', 'frontend']),
|
|
233
|
-
Status: prop.status('In Progress'),
|
|
234
|
-
'Due Date': prop.date('2025-03-01'),
|
|
235
|
-
'Date Range': prop.date('2025-03-01', { end: '2025-03-15' }),
|
|
236
|
-
Website: prop.url('https://example.com'),
|
|
237
|
-
Contact: prop.email('user@example.com'),
|
|
238
|
-
Phone: prop.phoneNumber('+1-555-0100'),
|
|
239
|
-
Related: prop.relation(['page-id-1', 'page-id-2']),
|
|
240
|
-
Assignee: prop.people(['user-id']),
|
|
241
|
-
Attachments: prop.files([{ name: 'doc.pdf', url: 'https://example.com/doc.pdf' }]),
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// Clear a property by passing null
|
|
245
|
-
prop.select(null);
|
|
246
|
-
prop.date(null);
|
|
247
|
-
prop.url(null);
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Filters
|
|
251
|
-
|
|
252
|
-
Chainable filter builders for database queries:
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
import { filter } from '@visus-io/notion-sdk-ts';
|
|
256
|
-
|
|
257
|
-
// Single property filters
|
|
258
|
-
filter.status('Status').equals('Active');
|
|
259
|
-
filter.select('Priority').doesNotEqual('Low');
|
|
260
|
-
filter.number('Score').greaterThan(80);
|
|
261
|
-
filter.checkbox('Done').equals(false);
|
|
262
|
-
filter.date('Due Date').before('2025-06-01');
|
|
263
|
-
filter.date('Due Date').pastWeek();
|
|
264
|
-
filter.text('Description').contains('important');
|
|
265
|
-
filter.title('Name').startsWith('Project');
|
|
266
|
-
filter.url('Website').isNotEmpty();
|
|
267
|
-
filter.email('Contact').isNotEmpty();
|
|
268
|
-
filter.multiSelect('Tags').contains('urgent');
|
|
269
|
-
filter.people('Assignee').contains('user-id');
|
|
270
|
-
filter.relation('Project').contains('page-id');
|
|
271
|
-
filter.files('Attachments').isNotEmpty();
|
|
272
|
-
|
|
273
|
-
// Timestamp filters (no property name needed)
|
|
274
|
-
filter.createdTime().after('2025-01-01');
|
|
275
|
-
filter.lastEditedTime().pastMonth();
|
|
276
|
-
|
|
277
|
-
// Compound filters
|
|
278
|
-
filter.and(
|
|
279
|
-
filter.status('Status').equals('Active'),
|
|
280
|
-
filter.number('Score').greaterThan(80),
|
|
281
|
-
filter.or(filter.date('Due Date').before('2025-06-01'), filter.date('Due Date').isEmpty()),
|
|
282
|
-
);
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
### Sorting
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
import { sort } from '@visus-io/notion-sdk-ts';
|
|
289
|
-
|
|
290
|
-
const sorts = [
|
|
291
|
-
sort.property('Priority').ascending(),
|
|
292
|
-
sort.property('Due Date').descending(),
|
|
293
|
-
sort.createdTime().descending(),
|
|
294
|
-
sort.lastEditedTime().ascending(),
|
|
295
|
-
];
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Parent, Icon, Cover & File
|
|
299
|
-
|
|
300
|
-
```typescript
|
|
301
|
-
import { parent, icon, cover, notionFile } from '@visus-io/notion-sdk-ts';
|
|
302
|
-
|
|
303
|
-
// Parent objects
|
|
304
|
-
parent.database('database-id');
|
|
305
|
-
parent.page('page-id');
|
|
306
|
-
parent.dataSource('data-source-id');
|
|
307
|
-
parent.block('block-id');
|
|
308
|
-
parent.workspace();
|
|
309
|
-
|
|
310
|
-
// Icons
|
|
311
|
-
icon.emoji('🚀');
|
|
312
|
-
icon.external('https://example.com/icon.png');
|
|
313
|
-
icon.fileUpload('upload-id');
|
|
314
|
-
|
|
315
|
-
// Covers
|
|
316
|
-
cover.external('https://example.com/banner.jpg');
|
|
317
|
-
cover.fileUpload('upload-id');
|
|
318
|
-
|
|
319
|
-
// File references
|
|
320
|
-
notionFile.external('https://example.com/doc.pdf');
|
|
321
|
-
notionFile.upload('upload-id');
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
## Models
|
|
325
|
-
|
|
326
|
-
All API methods return model instances with typed properties and helper methods. Every model validates raw API data through its Zod schema on construction.
|
|
327
|
-
|
|
328
|
-
### Page
|
|
329
|
-
|
|
330
|
-
```typescript
|
|
331
|
-
const page = await notion.pages.retrieve('page-id');
|
|
332
|
-
|
|
333
|
-
page.id; // UUID
|
|
334
|
-
page.url; // Notion URL
|
|
335
|
-
page.publicUrl; // Public URL (if shared)
|
|
336
|
-
page.createdTime; // Date
|
|
337
|
-
page.lastEditedTime; // Date
|
|
338
|
-
page.archived; // boolean
|
|
339
|
-
page.inTrash; // boolean
|
|
340
|
-
page.properties; // Record of property values
|
|
341
|
-
|
|
342
|
-
page.getTitle(); // Plain text title
|
|
343
|
-
page.getProperty('Name'); // Specific property value
|
|
344
|
-
page.isInDatabase(); // true if parent is a database
|
|
345
|
-
page.isSubpage(); // true if parent is a page
|
|
346
|
-
page.toJSON(); // Raw validated data
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### Block
|
|
350
|
-
|
|
351
|
-
```typescript
|
|
352
|
-
const block = await notion.blocks.retrieve('block-id');
|
|
353
|
-
|
|
354
|
-
block.id; // UUID
|
|
355
|
-
block.type; // 'paragraph' | 'heading_1' | ...
|
|
356
|
-
block.hasChildren; // boolean
|
|
357
|
-
|
|
358
|
-
block.isTextBlock(); // paragraph, heading, list item, etc.
|
|
359
|
-
block.isHeading(); // heading_1, heading_2, heading_3
|
|
360
|
-
block.canHaveChildren(); // toggle, column, synced_block, etc.
|
|
361
|
-
block.getPlainText(); // Extracted text content
|
|
362
|
-
block.toJSON();
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### Database
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
const db = await notion.databases.retrieve('database-id');
|
|
369
|
-
|
|
370
|
-
db.id; // UUID
|
|
371
|
-
db.title; // NotionRichText
|
|
372
|
-
db.description; // NotionRichText
|
|
373
|
-
db.dataSources; // DataSourceRef[]
|
|
374
|
-
db.url; // Notion URL
|
|
375
|
-
db.isInline; // boolean
|
|
376
|
-
|
|
377
|
-
db.getTitle(); // Plain text title
|
|
378
|
-
db.getDescription(); // Plain text description
|
|
379
|
-
db.isFullPage(); // true if not inline
|
|
380
|
-
db.hasPageParent();
|
|
381
|
-
db.hasWorkspaceParent();
|
|
382
|
-
db.toJSON();
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
### DataSource
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
const ds = await notion.dataSources.retrieve('data-source-id');
|
|
389
|
-
|
|
390
|
-
ds.id; // UUID
|
|
391
|
-
ds.properties; // Property configurations
|
|
392
|
-
|
|
393
|
-
ds.getTitle();
|
|
394
|
-
ds.getDescription();
|
|
395
|
-
ds.getParentDatabaseId();
|
|
396
|
-
ds.getProperty('Name'); // Specific property config
|
|
397
|
-
ds.getPropertyNames(); // All property names
|
|
398
|
-
ds.hasProperty('Status');
|
|
399
|
-
ds.toJSON();
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### User
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
const user = await notion.users.retrieve('user-id');
|
|
406
|
-
|
|
407
|
-
user.id; // UUID
|
|
408
|
-
user.type; // 'person' | 'bot' | undefined
|
|
409
|
-
user.name; // string | undefined
|
|
410
|
-
user.avatarUrl; // string | undefined
|
|
411
|
-
|
|
412
|
-
user.isPerson(); // Type guard
|
|
413
|
-
user.isBot(); // Type guard
|
|
414
|
-
user.getEmail(); // Person users only
|
|
415
|
-
user.getBotInfo(); // Bot users only
|
|
416
|
-
user.toJSON();
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
### Comment
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
const comments = await notion.comments.list('page-id');
|
|
423
|
-
const comment = comments.results[0];
|
|
424
|
-
|
|
425
|
-
comment.id;
|
|
426
|
-
comment.discussionId;
|
|
427
|
-
comment.richText; // NotionRichText
|
|
428
|
-
comment.createdTime; // Date
|
|
429
|
-
comment.attachments;
|
|
430
|
-
comment.displayName;
|
|
431
|
-
|
|
432
|
-
comment.getPlainText();
|
|
433
|
-
comment.hasAttachments();
|
|
434
|
-
comment.hasCustomDisplayName();
|
|
435
|
-
comment.getDisplayName(); // Resolved display name string
|
|
436
|
-
comment.hasPageParent();
|
|
437
|
-
comment.hasBlockParent();
|
|
438
|
-
comment.toJSON();
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
### FileUpload
|
|
442
|
-
|
|
443
|
-
```typescript
|
|
444
|
-
const upload = await notion.fileUploads.retrieve('upload-id');
|
|
445
|
-
|
|
446
|
-
upload.id;
|
|
447
|
-
upload.status; // 'pending' | 'uploaded' | 'expired' | 'failed'
|
|
448
|
-
upload.filename;
|
|
449
|
-
upload.contentType;
|
|
450
|
-
upload.contentLength;
|
|
451
|
-
upload.uploadUrl;
|
|
452
|
-
upload.completeUrl;
|
|
453
|
-
|
|
454
|
-
upload.isPending();
|
|
455
|
-
upload.isUploaded();
|
|
456
|
-
upload.isExpired();
|
|
457
|
-
upload.isFailed();
|
|
458
|
-
upload.toJSON();
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### RichText Utility
|
|
462
|
-
|
|
463
|
-
Parse and convert Notion rich text to other formats:
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
import { RichText } from '@visus-io/notion-sdk-ts';
|
|
467
|
-
|
|
468
|
-
const rt = new RichText(page.properties.Name.title);
|
|
469
|
-
|
|
470
|
-
rt.toPlainText(); // "Project Documentation"
|
|
471
|
-
rt.toMarkdown(); // "**Project** Documentation"
|
|
472
|
-
rt.toHTML(); // "<strong>Project</strong> Documentation"
|
|
473
|
-
rt.hasLinks(); // boolean
|
|
474
|
-
rt.getLinks(); // string[]
|
|
475
|
-
rt.toJSON(); // Raw NotionRichText
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
**Supported conversions:**
|
|
479
|
-
|
|
480
|
-
| Format | Bold | Italic | Strikethrough | Underline | Code | Link |
|
|
481
|
-
| -------- | ---------- | -------- | ------------- | --------- | ------------ | ------------- |
|
|
482
|
-
| Markdown | `**text**` | `*text*` | `~~text~~` | -- | `` `text` `` | `[text](url)` |
|
|
483
|
-
| HTML | `<strong>` | `<em>` | `<s>` | `<u>` | `<code>` | `<a href="">` |
|
|
484
|
-
|
|
485
|
-
## Error Handling
|
|
486
|
-
|
|
487
|
-
Four error classes cover all failure modes:
|
|
488
|
-
|
|
489
|
-
```typescript
|
|
490
|
-
import {
|
|
491
|
-
NotionAPIError,
|
|
492
|
-
NotionNetworkError,
|
|
493
|
-
NotionRequestTimeoutError,
|
|
494
|
-
NotionValidationError,
|
|
495
|
-
} from '@visus-io/notion-sdk-ts';
|
|
496
|
-
|
|
497
|
-
try {
|
|
498
|
-
await notion.pages.retrieve('page-id');
|
|
499
|
-
} catch (error) {
|
|
500
|
-
if (error instanceof NotionValidationError) {
|
|
501
|
-
// Client-side size limit exceeded (thrown before the request is sent)
|
|
502
|
-
console.error(error.message);
|
|
503
|
-
} else if (error instanceof NotionAPIError) {
|
|
504
|
-
// Structured API error with status code and error code
|
|
505
|
-
console.error(error.status, error.code, error.message);
|
|
506
|
-
|
|
507
|
-
error.isNotFound(); // 404
|
|
508
|
-
error.isUnauthorized(); // 401
|
|
509
|
-
error.isValidationError(); // 400
|
|
510
|
-
error.isRateLimited(); // 429 (auto-retried by default)
|
|
511
|
-
error.isServerError(); // 5xx
|
|
512
|
-
error.isRetryable(); // rate limited OR server error
|
|
513
|
-
} else if (error instanceof NotionNetworkError) {
|
|
514
|
-
// DNS failure, connection refused, etc.
|
|
515
|
-
console.error(error.message, error.cause);
|
|
516
|
-
} else if (error instanceof NotionRequestTimeoutError) {
|
|
517
|
-
// Request exceeded configured timeout
|
|
518
|
-
console.error(error.message);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
**Error codes:** `invalid_json`, `invalid_request_url`, `invalid_request`, `validation_error`, `missing_version`, `unauthorized`, `restricted_resource`, `object_not_found`, `conflict_error`, `rate_limited`, `internal_server_error`, `service_unavailable`, `database_connection_unavailable`, `gateway_timeout`
|
|
524
|
-
|
|
525
|
-
## Request Size Limits
|
|
526
|
-
|
|
527
|
-
The SDK enforces [Notion API size limits](https://developers.notion.com/reference/request-limits#size-limits) client-side, throwing `NotionValidationError` before the request is sent. This applies at both layers: helpers validate when constructing objects, and API methods validate before sending.
|
|
528
|
-
|
|
529
|
-
| Limit | Value | Where enforced |
|
|
530
|
-
| ---------------------------- | ------------ | ----------------------------------------------------------------------------------------------- |
|
|
531
|
-
| `text.content` length | 2,000 chars | `richText()`, `block.*()`, `prop.title()`, `prop.richText()` |
|
|
532
|
-
| `text.link.url` length | 2,000 chars | `richText().link()` |
|
|
533
|
-
| `equation.expression` length | 1,000 chars | `richText.equation()`, `block.equation()` |
|
|
534
|
-
| Any URL property | 2,000 chars | `prop.url()`, `block.embed()`, `block.bookmark()`, `block.linkPreview()`, `block.image()`, etc. |
|
|
535
|
-
| Email property | 200 chars | `prop.email()` |
|
|
536
|
-
| Phone number property | 200 chars | `prop.phoneNumber()` |
|
|
537
|
-
| Block/rich-text arrays | 100 elements | `blocks.children.append()`, `pages.create()`, `comments.create()`, `databases.create/update()` |
|
|
538
|
-
| Multi-select options | 100 options | `prop.multiSelect()` |
|
|
539
|
-
| Relation pages | 100 pages | `prop.relation()` |
|
|
540
|
-
| People users | 100 users | `prop.people()` |
|
|
541
|
-
| Comment attachments | 3 files | `comments.create()` |
|
|
542
|
-
| `filter_properties` | 100 items | `pages.retrieve()`, `databases.retrieve/query()`, `dataSources.retrieve/query()` |
|
|
543
|
-
|
|
544
|
-
All limit constants are exported as `LIMITS` for reference:
|
|
545
|
-
|
|
546
|
-
```typescript
|
|
547
|
-
import { LIMITS } from '@visus-io/notion-sdk-ts';
|
|
548
|
-
|
|
549
|
-
console.log(LIMITS.RICH_TEXT_CONTENT); // 2000
|
|
550
|
-
console.log(LIMITS.URL); // 2000
|
|
551
|
-
console.log(LIMITS.EMAIL); // 200
|
|
552
|
-
console.log(LIMITS.ARRAY_ELEMENTS); // 100
|
|
553
74
|
```
|
|
554
75
|
|
|
555
|
-
##
|
|
556
|
-
|
|
557
|
-
All list endpoints return `PaginatedList<T>` with cursor-based pagination:
|
|
558
|
-
|
|
559
|
-
```typescript
|
|
560
|
-
interface PaginatedList<T> {
|
|
561
|
-
results: T[];
|
|
562
|
-
next_cursor: string | null;
|
|
563
|
-
has_more: boolean;
|
|
564
|
-
}
|
|
565
|
-
```
|
|
76
|
+
## Documentation
|
|
566
77
|
|
|
567
|
-
|
|
78
|
+
Comprehensive documentation is available in the [**GitHub Wiki**](https://github.com/visus-io/notion-sdk-ts/wiki):
|
|
568
79
|
|
|
569
|
-
###
|
|
80
|
+
### Getting Started
|
|
570
81
|
|
|
571
|
-
|
|
82
|
+
- [**Getting Started**](https://github.com/visus-io/notion-sdk-ts/wiki/Getting-Started) - Installation, quick start, and basic configuration
|
|
83
|
+
- [**Migration Guide**](https://github.com/visus-io/notion-sdk-ts/wiki/Migration-Guide) - Migrating to API version 2025-09-03
|
|
84
|
+
- [**Common Use Cases**](https://github.com/visus-io/notion-sdk-ts/wiki/Common-Use-Cases) - Practical examples and workflows
|
|
572
85
|
|
|
573
|
-
|
|
574
|
-
import { paginate } from '@visus-io/notion-sdk-ts';
|
|
575
|
-
|
|
576
|
-
// All blocks from a page
|
|
577
|
-
const blocks = await paginate((cursor) =>
|
|
578
|
-
notion.blocks.children.list('page-id', { start_cursor: cursor, page_size: 100 }),
|
|
579
|
-
);
|
|
580
|
-
|
|
581
|
-
// All pages from a database query
|
|
582
|
-
const pages = await paginate((cursor) =>
|
|
583
|
-
notion.databases.query('database-id', {
|
|
584
|
-
start_cursor: cursor,
|
|
585
|
-
page_size: 100,
|
|
586
|
-
filter: filter.status('Status').equals('Active'),
|
|
587
|
-
}),
|
|
588
|
-
);
|
|
589
|
-
|
|
590
|
-
// All comments on a page
|
|
591
|
-
const comments = await paginate((cursor) =>
|
|
592
|
-
notion.comments.list('page-id', { start_cursor: cursor }),
|
|
593
|
-
);
|
|
594
|
-
|
|
595
|
-
// All users in workspace
|
|
596
|
-
const users = await paginate((cursor) => notion.users.list({ start_cursor: cursor }));
|
|
597
|
-
|
|
598
|
-
// All search results
|
|
599
|
-
const searchResults = await paginate((cursor) =>
|
|
600
|
-
notion.search.query({
|
|
601
|
-
query: 'project',
|
|
602
|
-
filter: { property: 'object', value: 'page' },
|
|
603
|
-
start_cursor: cursor,
|
|
604
|
-
}),
|
|
605
|
-
);
|
|
606
|
-
```
|
|
86
|
+
### Core Concepts
|
|
607
87
|
|
|
608
|
-
|
|
88
|
+
- [**Helpers**](https://github.com/visus-io/notion-sdk-ts/wiki/Helpers) - Rich Text, Block Builder, Properties, Filters, Sorting
|
|
89
|
+
- [**Models**](https://github.com/visus-io/notion-sdk-ts/wiki/Models) - Page, Block, Database, DataSource, User, Comment, FileUpload
|
|
90
|
+
- [**API Reference**](https://github.com/visus-io/notion-sdk-ts/wiki/API-Reference) - Complete API endpoint documentation
|
|
609
91
|
|
|
610
|
-
|
|
92
|
+
### Configuration & Advanced Topics
|
|
611
93
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
for await (const block of paginateIterator((cursor) =>
|
|
617
|
-
notion.blocks.children.list('page-id', { start_cursor: cursor }),
|
|
618
|
-
)) {
|
|
619
|
-
console.log(block.type, block.id);
|
|
620
|
-
if (block.isTextBlock()) {
|
|
621
|
-
console.log(block.getPlainText());
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
// Process database pages one at a time
|
|
626
|
-
for await (const page of paginateIterator((cursor) =>
|
|
627
|
-
notion.databases.query('database-id', {
|
|
628
|
-
start_cursor: cursor,
|
|
629
|
-
filter: filter.status('Status').equals('Active'),
|
|
630
|
-
}),
|
|
631
|
-
)) {
|
|
632
|
-
console.log(page.getTitle());
|
|
633
|
-
// Process without loading all pages into memory
|
|
634
|
-
}
|
|
635
|
-
```
|
|
94
|
+
- [**Configuration & Features**](https://github.com/visus-io/notion-sdk-ts/wiki/Configuration) - Client options, rate limiting, retries
|
|
95
|
+
- [**Error Handling**](https://github.com/visus-io/notion-sdk-ts/wiki/Error-Handling) - Error types, codes, and handling patterns
|
|
96
|
+
- [**Pagination**](https://github.com/visus-io/notion-sdk-ts/wiki/Pagination) - Automatic pagination helpers
|
|
97
|
+
- [**Request Size Limits**](https://github.com/visus-io/notion-sdk-ts/wiki/Request-Size-Limits) - Notion API size limits
|
|
636
98
|
|
|
637
|
-
###
|
|
99
|
+
### Development
|
|
638
100
|
|
|
639
|
-
|
|
101
|
+
- [**TypeScript Support**](https://github.com/visus-io/notion-sdk-ts/wiki/TypeScript-Support) - Types, schemas, and type safety
|
|
102
|
+
- [**Development & Contributing**](https://github.com/visus-io/notion-sdk-ts/wiki/Development) - Project structure and architecture
|
|
640
103
|
|
|
641
|
-
|
|
642
|
-
import { paginateWithMetadata } from '@visus-io/notion-sdk-ts';
|
|
104
|
+
## Migration Notice
|
|
643
105
|
|
|
644
|
-
|
|
645
|
-
notion.blocks.children.list('page-id', { start_cursor: cursor }),
|
|
646
|
-
);
|
|
106
|
+
**This SDK now defaults to Notion API version `2025-09-03`** (previously `2022-06-28`). This version introduces breaking changes for multi-source database support.
|
|
647
107
|
|
|
648
|
-
|
|
649
|
-
```
|
|
108
|
+
### Key Changes
|
|
650
109
|
|
|
651
|
-
**
|
|
110
|
+
- **Database creation:** Properties moved to `initial_data_source.properties`
|
|
111
|
+
- **Database updates:** Use Data Sources API for property changes
|
|
112
|
+
- **Page creation:** Requires both data source ID and database ID
|
|
113
|
+
- **Search API:** Returns `DataSource` objects instead of `Database`
|
|
652
114
|
|
|
653
|
-
|
|
115
|
+
### Quick Migration Example
|
|
654
116
|
|
|
655
117
|
```typescript
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
baseUrl: 'https://api.notion.com', // Default
|
|
661
|
-
notionVersion: '2022-06-28', // Default
|
|
662
|
-
timeoutMs: 60_000, // Default: 60s
|
|
663
|
-
retryOnRateLimit: true, // Default: true
|
|
664
|
-
maxRetries: 3, // Default: 3
|
|
665
|
-
fetch: customFetch, // Custom fetch implementation
|
|
118
|
+
// OLD (2022-06-28)
|
|
119
|
+
await notion.pages.create({
|
|
120
|
+
parent: parent.database('database-id'),
|
|
121
|
+
properties: { Name: prop.title('Task') },
|
|
666
122
|
});
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
**Rate limiting:** The SDK automatically retries 429 responses using the server's `Retry-After` header when present, falling back to exponential backoff (1s, 2s, 4s, 8s... capped at 60s) otherwise. Disable with `retryOnRateLimit: false` or adjust with `maxRetries`.
|
|
670
|
-
|
|
671
|
-
## API Reference
|
|
672
|
-
|
|
673
|
-
### Pages API
|
|
674
|
-
|
|
675
|
-
| Method | Description |
|
|
676
|
-
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
677
|
-
| `pages.retrieve(id, options?)` | Get a page. Options: `filter_properties` (max 100) |
|
|
678
|
-
| `pages.create(options)` | Create a page. Requires `parent` + `properties`. Optional: `icon`, `cover`, `children` (max 100), `template`, `position` |
|
|
679
|
-
| `pages.update(id, options)` | Update properties, icon, cover, lock status, or archive state. Supports `erase_content` |
|
|
680
|
-
| `pages.archive(id)` | Archive a page |
|
|
681
|
-
| `pages.restore(id)` | Restore an archived page |
|
|
682
|
-
|
|
683
|
-
### Blocks API
|
|
684
|
-
|
|
685
|
-
| Method | Description |
|
|
686
|
-
| ------------------------------------- | --------------------------------------------------------- |
|
|
687
|
-
| `blocks.retrieve(id, options?)` | Get a block |
|
|
688
|
-
| `blocks.update(id, options)` | Update block content |
|
|
689
|
-
| `blocks.delete(id)` | Delete (archive) a block |
|
|
690
|
-
| `blocks.children.list(id, params?)` | List child blocks (paginated) |
|
|
691
|
-
| `blocks.children.append(id, options)` | Append child blocks (max 100). Optional: `after` block ID |
|
|
692
|
-
|
|
693
|
-
### Databases API
|
|
694
|
-
|
|
695
|
-
| Method | Description |
|
|
696
|
-
| ---------------------------------- | ----------------------------------------------------------------------- |
|
|
697
|
-
| `databases.retrieve(id, options?)` | Get a database |
|
|
698
|
-
| `databases.query(id, options?)` | Query with `filter`, `sorts`, pagination. Returns `PaginatedList<Page>` |
|
|
699
|
-
| `databases.create(options)` | Create a database. Requires `parent` + `properties` |
|
|
700
|
-
| `databases.update(id, options)` | Update title, description, properties, icon, cover |
|
|
701
|
-
| `databases.archive(id)` | Archive a database |
|
|
702
|
-
| `databases.restore(id)` | Restore a database |
|
|
703
|
-
|
|
704
|
-
### Data Sources API
|
|
705
|
-
|
|
706
|
-
Data sources represent individual tables under databases (API version 2025-09-03).
|
|
707
|
-
|
|
708
|
-
| Method | Description |
|
|
709
|
-
| ----------------------------------------- | -------------------------------------------------------------------- |
|
|
710
|
-
| `dataSources.retrieve(id, options?)` | Get a data source |
|
|
711
|
-
| `dataSources.query(id, options?)` | Query with filters/sorts. `result_type`: `'page'` or `'data_source'` |
|
|
712
|
-
| `dataSources.create(options)` | Create a data source under a database |
|
|
713
|
-
| `dataSources.update(id, options)` | Update a data source |
|
|
714
|
-
| `dataSources.archive(id)` / `restore(id)` | Archive/restore |
|
|
715
|
-
| `dataSources.trash(id)` / `untrash(id)` | Move to/from trash |
|
|
716
|
-
|
|
717
|
-
### Comments API
|
|
718
|
-
|
|
719
|
-
| Method | Description |
|
|
720
|
-
| ---------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
721
|
-
| `comments.list(parentId, params?)` | List comments on a page/block (paginated) |
|
|
722
|
-
| `comments.create(options)` | Create a comment. Options: `parent`, `rich_text`, `discussion_id`, `attachments` (max 3), `display_name` |
|
|
723
|
-
|
|
724
|
-
### Search API
|
|
725
|
-
|
|
726
|
-
| Method | Description |
|
|
727
|
-
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
|
|
728
|
-
| `search.query(options?)` | Search workspace. Filter by `'page'` or `'database'`. Sort by `last_edited_time`. Returns `PaginatedList<Page \| Database>` |
|
|
729
|
-
|
|
730
|
-
### Users API
|
|
731
|
-
|
|
732
|
-
| Method | Description |
|
|
733
|
-
| --------------------- | -------------------------------------- |
|
|
734
|
-
| `users.list(params?)` | List all workspace users (paginated) |
|
|
735
|
-
| `users.retrieve(id)` | Get a user by ID |
|
|
736
|
-
| `users.me()` | Get the bot user for the current token |
|
|
737
123
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
742
|
-
| `fileUploads.uploadFile(filename, data, contentType)` | Upload a file in one call (handles initiate + upload + complete). `data`: `Buffer \| ArrayBuffer \| Blob` |
|
|
743
|
-
| `fileUploads.initiate(options)` | Step 1: Initiate upload |
|
|
744
|
-
| `fileUploads.upload(url, data, contentType)` | Step 2: Upload file data |
|
|
745
|
-
| `fileUploads.complete(url)` | Step 3: Mark upload complete |
|
|
746
|
-
| `fileUploads.retrieve(id)` | Check upload status |
|
|
747
|
-
|
|
748
|
-
**Full example:**
|
|
749
|
-
|
|
750
|
-
```typescript
|
|
751
|
-
import { readFileSync } from 'fs';
|
|
752
|
-
|
|
753
|
-
// One-step upload
|
|
754
|
-
const upload = await notion.fileUploads.uploadFile(
|
|
755
|
-
'document.pdf',
|
|
756
|
-
readFileSync('./document.pdf'),
|
|
757
|
-
'application/pdf',
|
|
758
|
-
);
|
|
759
|
-
|
|
760
|
-
console.log(upload.status); // 'uploaded'
|
|
124
|
+
// NEW (2025-09-03)
|
|
125
|
+
const db = await notion.databases.retrieve('database-id');
|
|
126
|
+
const dataSourceId = db.dataSources[0].id;
|
|
761
127
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
content_type: 'application/pdf',
|
|
128
|
+
await notion.pages.create({
|
|
129
|
+
parent: parent.dataSource(dataSourceId, db.id),
|
|
130
|
+
properties: { Name: prop.title('Task') },
|
|
766
131
|
});
|
|
767
|
-
await notion.fileUploads.upload(init.uploadUrl, fileData, 'application/pdf');
|
|
768
|
-
const completed = await notion.fileUploads.complete(init.completeUrl);
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
## TypeScript Support
|
|
772
|
-
|
|
773
|
-
All Zod schemas and their inferred types are exported:
|
|
774
|
-
|
|
775
|
-
```typescript
|
|
776
|
-
import type {
|
|
777
|
-
NotionPage,
|
|
778
|
-
NotionBlock,
|
|
779
|
-
NotionDatabase,
|
|
780
|
-
NotionUser,
|
|
781
|
-
NotionComment,
|
|
782
|
-
NotionDataSource,
|
|
783
|
-
NotionFileUpload,
|
|
784
|
-
NotionRichText,
|
|
785
|
-
NotionParent,
|
|
786
|
-
NotionFile,
|
|
787
|
-
NotionColor,
|
|
788
|
-
PaginatedList,
|
|
789
|
-
} from '@visus-io/notion-sdk-ts';
|
|
790
|
-
|
|
791
|
-
// Model classes
|
|
792
|
-
import type {
|
|
793
|
-
Page,
|
|
794
|
-
Block,
|
|
795
|
-
Database,
|
|
796
|
-
User,
|
|
797
|
-
Comment,
|
|
798
|
-
DataSource,
|
|
799
|
-
FileUpload,
|
|
800
|
-
} from '@visus-io/notion-sdk-ts';
|
|
801
|
-
|
|
802
|
-
// Zod schemas for manual validation
|
|
803
|
-
import { pageSchema, blockSchema, databaseSchema, userSchema } from '@visus-io/notion-sdk-ts';
|
|
804
|
-
|
|
805
|
-
const validated = pageSchema.parse(rawData);
|
|
806
132
|
```
|
|
807
133
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
**Supported property types (21):** title, rich_text, number, checkbox, date, url, email, phone_number, select, multi_select, status, relation, rollup, people, created_by, last_edited_by, created_time, last_edited_time, files, formula, unique_id, verification
|
|
134
|
+
See the [**Migration Guide**](https://github.com/visus-io/notion-sdk-ts/wiki/Migration-Guide) for complete details.
|
|
811
135
|
|
|
812
136
|
## Development
|
|
813
137
|
|
|
814
138
|
```bash
|
|
815
139
|
npm install # Install dependencies
|
|
816
|
-
npm run build # Compile TypeScript
|
|
140
|
+
npm run build # Compile TypeScript
|
|
817
141
|
|
|
818
|
-
npm test # Run tests
|
|
142
|
+
npm test # Run tests
|
|
819
143
|
npm run test:watch # Watch mode
|
|
820
|
-
npm run test:coverage # Coverage report
|
|
144
|
+
npm run test:coverage # Coverage report
|
|
821
145
|
|
|
822
146
|
npm run lint # ESLint
|
|
823
|
-
npm run lint:fix # Auto-fix
|
|
147
|
+
npm run lint:fix # Auto-fix
|
|
824
148
|
npm run format # Prettier
|
|
825
|
-
npm run format:check # Check formatting
|
|
826
|
-
```
|
|
827
|
-
|
|
828
|
-
## Project Structure
|
|
829
|
-
|
|
830
|
-
```
|
|
831
|
-
src/
|
|
832
|
-
├── index.ts # Entry point — re-exports everything
|
|
833
|
-
├── notion.ts # Notion class (main SDK entry)
|
|
834
|
-
├── client.ts # HTTP client with retry logic
|
|
835
|
-
├── errors.ts # NotionAPIError, NotionNetworkError, NotionRequestTimeoutError
|
|
836
|
-
├── validation.ts # NotionValidationError, LIMITS, size-limit validators
|
|
837
|
-
├── api/
|
|
838
|
-
│ ├── blocks.api.ts # Blocks API
|
|
839
|
-
│ ├── comments.api.ts # Comments API
|
|
840
|
-
│ ├── databases.api.ts # Databases API
|
|
841
|
-
│ ├── dataSources.api.ts # Data Sources API
|
|
842
|
-
│ ├── fileUploads.api.ts # File Uploads API
|
|
843
|
-
│ ├── pages.api.ts # Pages API
|
|
844
|
-
│ ├── search.api.ts # Search API
|
|
845
|
-
│ └── users.api.ts # Users API
|
|
846
|
-
├── helpers/
|
|
847
|
-
│ ├── block.helpers.ts # block.paragraph(), block.heading1(), etc.
|
|
848
|
-
│ ├── richText.helpers.ts # richText(), RichTextBuilder
|
|
849
|
-
│ ├── filter.helpers.ts # filter.status(), filter.and(), etc.
|
|
850
|
-
│ ├── sort.helpers.ts # sort.property(), sort.createdTime()
|
|
851
|
-
│ ├── property.helpers.ts # prop.title(), prop.select(), etc.
|
|
852
|
-
│ ├── parent.helpers.ts # parent.database(), parent.page()
|
|
853
|
-
│ └── file.helpers.ts # icon, cover, notionFile
|
|
854
|
-
├── models/
|
|
855
|
-
│ ├── base.model.ts # Abstract BaseModel<T> with Zod validation
|
|
856
|
-
│ ├── page.model.ts # Page
|
|
857
|
-
│ ├── block.model.ts # Block
|
|
858
|
-
│ ├── database.model.ts # Database
|
|
859
|
-
│ ├── dataSource.model.ts # DataSource
|
|
860
|
-
│ ├── comment.model.ts # Comment
|
|
861
|
-
│ ├── user.model.ts # User
|
|
862
|
-
│ ├── fileUpload.model.ts # FileUpload
|
|
863
|
-
│ └── richText.model.ts # RichText (toPlainText/toMarkdown/toHTML)
|
|
864
|
-
└── schemas/
|
|
865
|
-
├── page.schema.ts # pageSchema + NotionPage
|
|
866
|
-
├── block.schema.ts # blockSchema + NotionBlock (31 types)
|
|
867
|
-
├── database.schema.ts # databaseSchema + NotionDatabase
|
|
868
|
-
├── dataSource.schema.ts # dataSourceSchema + NotionDataSource
|
|
869
|
-
├── comment.schema.ts # commentSchema + NotionComment
|
|
870
|
-
├── user.schema.ts # userSchema + NotionUser
|
|
871
|
-
├── fileUpload.schema.ts # fileUploadSchema + NotionFileUpload
|
|
872
|
-
├── pageProperties.schema.ts # 21 page property value types
|
|
873
|
-
├── propertyObjects.schema.ts# 21 database property config types
|
|
874
|
-
├── richText.schema.ts # richTextSchema + 3 types + 6 mention types
|
|
875
|
-
├── pagination.schema.ts # PaginatedList<T>, PaginationParameters
|
|
876
|
-
├── parent.schema.ts # 5 parent types
|
|
877
|
-
├── file.schema.ts # 3 file variants
|
|
878
|
-
├── emoji.schema.ts # NotionEmoji
|
|
879
|
-
├── colors.ts # NOTION_COLORS (19 colors)
|
|
880
|
-
└── codeLanguages.ts # CODE_BLOCK_LANGUAGES (75 languages)
|
|
881
149
|
```
|
|
882
150
|
|
|
883
|
-
**
|
|
151
|
+
See [**Development & Contributing**](https://github.com/visus-io/notion-sdk-ts/wiki/Development) for more details.
|
|
884
152
|
|
|
885
153
|
## Links
|
|
886
154
|
|
|
887
|
-
- [
|
|
888
|
-
- [
|
|
889
|
-
- [
|
|
155
|
+
- [**Documentation Wiki**](https://github.com/visus-io/notion-sdk-ts/wiki)
|
|
156
|
+
- [**GitHub Repository**](https://github.com/visus-io/notion-sdk-ts)
|
|
157
|
+
- [**npm Package**](https://www.npmjs.com/package/@visus-io/notion-sdk-ts)
|
|
158
|
+
- [**Notion API Documentation**](https://developers.notion.com/reference/intro)
|
|
159
|
+
- [**Notion API Changelog**](https://developers.notion.com/page/changelog)
|