@notionhq/client 5.26.0 → 5.27.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 +130 -129
- package/build/package.json +4 -3
- package/build/src/Client.d.ts +1867 -130
- package/build/src/Client.d.ts.map +1 -1
- package/build/src/Client.js +95 -571
- package/build/src/Client.js.map +1 -1
- package/build/src/api-endpoint-methods.d.ts +920 -0
- package/build/src/api-endpoint-methods.d.ts.map +1 -0
- package/build/src/api-endpoint-methods.js +171 -0
- package/build/src/api-endpoint-methods.js.map +1 -0
- package/build/src/api-endpoints/agent-skills.d.ts +68 -0
- package/build/src/api-endpoints/agent-skills.d.ts.map +1 -0
- package/build/src/api-endpoints/agent-skills.js +36 -0
- package/build/src/api-endpoints/agent-skills.js.map +1 -0
- package/build/src/api-endpoints/agents.d.ts +173 -146
- package/build/src/api-endpoints/agents.d.ts.map +1 -1
- package/build/src/api-endpoints/agents.js.map +1 -1
- package/build/src/api-endpoints/data-sources.d.ts +1 -0
- package/build/src/api-endpoints/data-sources.d.ts.map +1 -1
- package/build/src/api-endpoints/data-sources.js.map +1 -1
- package/build/src/api-endpoints/databases.d.ts +3 -1
- package/build/src/api-endpoints/databases.d.ts.map +1 -1
- package/build/src/api-endpoints/databases.js +1 -0
- package/build/src/api-endpoints/databases.js.map +1 -1
- package/build/src/api-endpoints/file-uploads.d.ts.map +1 -1
- package/build/src/api-endpoints/file-uploads.js.map +1 -1
- package/build/src/api-endpoints/pages.d.ts.map +1 -1
- package/build/src/api-endpoints/pages.js.map +1 -1
- package/build/src/api-endpoints/users.d.ts.map +1 -1
- package/build/src/api-endpoints/users.js.map +1 -1
- package/build/src/api-endpoints.d.ts +1 -0
- package/build/src/api-endpoints.d.ts.map +1 -1
- package/build/src/api-endpoints.js +1 -0
- package/build/src/api-endpoints.js.map +1 -1
- package/build/src/errors.d.ts +11 -0
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +20 -1
- package/build/src/errors.js.map +1 -1
- package/build/src/helpers.d.ts +4 -4
- package/build/src/helpers.d.ts.map +1 -1
- package/build/src/helpers.js.map +1 -1
- package/build/src/index.d.ts +2 -2
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +2 -1
- package/build/src/index.js.map +1 -1
- package/build/src/webhooks.d.ts +12 -19
- package/build/src/webhooks.d.ts.map +1 -1
- package/build/src/webhooks.js +27 -35
- package/build/src/webhooks.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Notion SDK for JavaScript
|
|
2
2
|
|
|
3
|
-
<img alt="Notion
|
|
3
|
+
<img alt="Notion logo" src="https://mcp.notion.com/notion-logo-block-sticker.svg" width="70" />
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A JavaScript and TypeScript client for the [Notion API](https://developers.notion.com). This reference covers the SDK's methods, options, and helpers.
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
[](https://www.npmjs.com/package/@notionhq/client)
|
|
@@ -18,14 +18,13 @@ npm install @notionhq/client
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
20
|
> [!NOTE]
|
|
21
|
-
>
|
|
21
|
+
> For setup steps, see Notion's [getting started guide](https://developers.notion.com/docs/getting-started).
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
`Client` accepts an integration token or an OAuth access token.
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
26
|
const { Client } = require("@notionhq/client")
|
|
27
27
|
|
|
28
|
-
// Initializing a client
|
|
29
28
|
const notion = new Client({
|
|
30
29
|
auth: process.env.NOTION_TOKEN,
|
|
31
30
|
})
|
|
@@ -36,17 +35,14 @@ Make a request to any Notion API endpoint.
|
|
|
36
35
|
```js
|
|
37
36
|
;(async () => {
|
|
38
37
|
const listUsersResponse = await notion.users.list({})
|
|
38
|
+
console.log(listUsersResponse)
|
|
39
39
|
})()
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
> [!NOTE]
|
|
43
43
|
> See the complete list of endpoints in the [API reference](https://developers.notion.com/reference).
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```js
|
|
48
|
-
console.log(listUsersResponse)
|
|
49
|
-
```
|
|
45
|
+
Request methods return a `Promise` with the response. For example:
|
|
50
46
|
|
|
51
47
|
```ts
|
|
52
48
|
{
|
|
@@ -83,12 +79,14 @@ const myPage = await notion.dataSources.query({
|
|
|
83
79
|
|
|
84
80
|
### Handling errors
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
The error contains properties from the response, and the most helpful is `code`. You can compare `code` to the values in the `APIErrorCode` object to avoid misspelling error codes.
|
|
82
|
+
Notion API errors reject the request with an `APIResponseError`. The `code` property identifies the error. `APIErrorCode` contains the known server error codes.
|
|
89
83
|
|
|
90
84
|
```js
|
|
91
|
-
const {
|
|
85
|
+
const {
|
|
86
|
+
Client,
|
|
87
|
+
APIErrorCode,
|
|
88
|
+
isNotionClientError,
|
|
89
|
+
} = require("@notionhq/client")
|
|
92
90
|
|
|
93
91
|
try {
|
|
94
92
|
const notion = new Client({ auth: process.env.NOTION_TOKEN })
|
|
@@ -102,10 +100,11 @@ try {
|
|
|
102
100
|
},
|
|
103
101
|
})
|
|
104
102
|
} catch (error) {
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
if (
|
|
104
|
+
isNotionClientError(error) &&
|
|
105
|
+
error.code === APIErrorCode.ObjectNotFound
|
|
106
|
+
) {
|
|
107
|
+
// Ask the user to select a different data source.
|
|
109
108
|
} else {
|
|
110
109
|
// Other error handling code
|
|
111
110
|
console.error(error)
|
|
@@ -115,9 +114,7 @@ try {
|
|
|
115
114
|
|
|
116
115
|
### Logging
|
|
117
116
|
|
|
118
|
-
The
|
|
119
|
-
|
|
120
|
-
If you're debugging an application, and would like the client to log response bodies, set the `logLevel` option to `LogLevel.DEBUG`.
|
|
117
|
+
The default logger writes warnings and errors to the console. `LogLevel.DEBUG` also logs response bodies.
|
|
121
118
|
|
|
122
119
|
```js
|
|
123
120
|
const { Client, LogLevel } = require("@notionhq/client")
|
|
@@ -128,42 +125,57 @@ const notion = new Client({
|
|
|
128
125
|
})
|
|
129
126
|
```
|
|
130
127
|
|
|
131
|
-
|
|
128
|
+
A custom `logger` receives `logLevel`, `message`, and `extraInfo`. It should return no value.
|
|
132
129
|
|
|
133
130
|
### Client options
|
|
134
131
|
|
|
135
|
-
The `Client`
|
|
132
|
+
The `Client` constructor accepts one options object.
|
|
133
|
+
|
|
134
|
+
| Option | Default value | Type | Description |
|
|
135
|
+
| ------------------------- | --------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `auth` | `undefined` | `string` | Bearer token for authentication. If left undefined, the `auth` parameter should be set on each request. |
|
|
137
|
+
| `logLevel` | `LogLevel.WARN` | `LogLevel` | Verbosity of logs the instance will produce. By default, logs are written to `stdout`. |
|
|
138
|
+
| `timeoutMs` | `DEFAULT_TIMEOUT_MS` | `number` | Number of milliseconds to wait before emitting a `RequestTimeoutError` |
|
|
139
|
+
| `baseUrl` | `DEFAULT_BASE_URL` | `string` | The root URL for sending API requests. This can be changed to test with a mock server. |
|
|
140
|
+
| `logger` | Log to console | `Logger` | A custom logging function. This function is only called when the client emits a log that is equal or greater severity than `logLevel`. |
|
|
141
|
+
| `agent` | Default node agent | `http.Agent` | Used to control creation of TCP sockets. A common use is to proxy requests with [`https-proxy-agent`](https://github.com/TooTallNate/node-https-proxy-agent) |
|
|
142
|
+
| `retry` | See [constants](#constants) | `RetryOptions` | Configuration for automatic retries on rate limits (429), service overloads (529), and server errors (500, 503). See [Automatic retries](#automatic-retries) below. |
|
|
143
|
+
| `dangerouslyAllowBrowser` | `false` | `boolean` | Allows a token inside a browser page or worker. Without it, the client throws `BrowserTokenNotAllowedError` there. See [Browser usage](#browser-usage) below. |
|
|
136
144
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
### Browser usage
|
|
146
|
+
|
|
147
|
+
The Notion API sends CORS headers, so browser code can call `api.notion.com` directly. The client works in modern browsers with the built-in `fetch`.
|
|
148
|
+
|
|
149
|
+
A token in a web page isn't a secret. Anyone who can load the page can read it and act as your connection.
|
|
150
|
+
|
|
151
|
+
- For an app other people use, keep the token on a server. Create a [public connection](https://developers.notion.com/guides/get-started/public-connections), which uses OAuth. Exchange the authorization code on your server, and send the page only the data it needs.
|
|
152
|
+
- For a personal tool or a local page that only you can open, using a token directly is your own risk to accept.
|
|
153
|
+
|
|
154
|
+
The client blocks tokens in a browser by default. Constructing it with `auth` inside a browser page throws `BrowserTokenNotAllowedError`. Pass `dangerouslyAllowBrowser: true` to confirm you understand the risk.
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
const notion = new Client({
|
|
158
|
+
auth: tokenTypedIntoYourOwnPage,
|
|
159
|
+
dangerouslyAllowBrowser: true,
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
A token passed per request through `auth` is blocked the same way: the request rejects with `BrowserTokenNotAllowedError` before anything is sent. A client without a token still works in a browser, for example with a `baseUrl` that points at your own server, which adds the token. Web workers and service workers in a browser count as a browser too, because every visitor downloads their script. Server runtimes that borrow worker APIs, such as Cloudflare Workers and Deno worker threads, don't count. Test runners that emulate a browser, such as jsdom, count as well, so pass `dangerouslyAllowBrowser: true` in those tests. The `agent` option is ignored in browsers, and the client doesn't send its `user-agent` header there, so a proxy's CORS rules don't need to allow it. OAuth token endpoints under `/v1/oauth/` don't send CORS headers, so exchange authorization codes on a server.
|
|
146
164
|
|
|
147
165
|
### Automatic retries
|
|
148
166
|
|
|
149
|
-
The client
|
|
167
|
+
The client retries failed requests up to 2 times by default. Delays increase with each retry and include a random offset.
|
|
150
168
|
|
|
151
|
-
|
|
169
|
+
Retried errors:
|
|
152
170
|
|
|
153
171
|
- `rate_limited` (HTTP 429) - Too many requests; retried for all HTTP methods
|
|
154
172
|
- `service_overload` (HTTP 529) - Service overloaded; retried for all HTTP methods
|
|
155
173
|
- `internal_server_error` (HTTP 500) - Server error; retried only for GET and DELETE
|
|
156
174
|
- `service_unavailable` (HTTP 503) - Service temporarily unavailable; retried only for GET and DELETE
|
|
157
175
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
**Retry behavior:**
|
|
176
|
+
For server errors, only GET and DELETE are retried to avoid repeating writes. The client uses the `Retry-After` header when present. It accepts a delay in seconds or an HTTP date.
|
|
161
177
|
|
|
162
|
-
|
|
163
|
-
- Respects the `Retry-After` header when present (both delta-seconds and HTTP-date formats)
|
|
164
|
-
- Adds random jitter to prevent thundering herd problems
|
|
165
|
-
|
|
166
|
-
**Configuration:**
|
|
178
|
+
Retry options:
|
|
167
179
|
|
|
168
180
|
```js
|
|
169
181
|
const notion = new Client({
|
|
@@ -187,7 +199,7 @@ const notion = new Client({
|
|
|
187
199
|
|
|
188
200
|
### Constants
|
|
189
201
|
|
|
190
|
-
The SDK exports
|
|
202
|
+
The SDK exports these defaults and Notion-specific values:
|
|
191
203
|
|
|
192
204
|
```js
|
|
193
205
|
const {
|
|
@@ -200,7 +212,7 @@ const {
|
|
|
200
212
|
} = require("@notionhq/client")
|
|
201
213
|
```
|
|
202
214
|
|
|
203
|
-
`MIN_VIEW_COLUMN_WIDTH` is the minimum
|
|
215
|
+
`MIN_VIEW_COLUMN_WIDTH` is the minimum table column width in pixels. A column at this width appears collapsed. For example:
|
|
204
216
|
|
|
205
217
|
```js
|
|
206
218
|
await notion.views.create({
|
|
@@ -223,19 +235,22 @@ await notion.views.create({
|
|
|
223
235
|
|
|
224
236
|
### TypeScript
|
|
225
237
|
|
|
226
|
-
|
|
227
|
-
as well as some useful sub-objects from those entities.
|
|
238
|
+
The package includes types for request parameters, responses, and their fields.
|
|
228
239
|
|
|
229
|
-
|
|
230
|
-
the
|
|
231
|
-
`
|
|
232
|
-
the `APIErrorCode` enum are returned from the server. Codes in the
|
|
233
|
-
`ClientErrorCode` enum are produced on the client.
|
|
240
|
+
With strict TypeScript, caught errors have type `unknown`. `isNotionClientError`
|
|
241
|
+
narrows the error to a known SDK error type. `APIErrorCode` identifies server
|
|
242
|
+
errors; `ClientErrorCode` identifies errors raised by the client.
|
|
234
243
|
|
|
235
244
|
```ts
|
|
245
|
+
import {
|
|
246
|
+
APIErrorCode,
|
|
247
|
+
ClientErrorCode,
|
|
248
|
+
isNotionClientError,
|
|
249
|
+
} from "@notionhq/client"
|
|
250
|
+
|
|
236
251
|
try {
|
|
237
252
|
const response = await notion.dataSources.query({
|
|
238
|
-
|
|
253
|
+
data_source_id: dataSourceId,
|
|
239
254
|
})
|
|
240
255
|
} catch (error: unknown) {
|
|
241
256
|
if (isNotionClientError(error)) {
|
|
@@ -250,10 +265,8 @@ try {
|
|
|
250
265
|
case APIErrorCode.Unauthorized:
|
|
251
266
|
// ...
|
|
252
267
|
break
|
|
253
|
-
// ...
|
|
254
268
|
default:
|
|
255
|
-
|
|
256
|
-
assertNever(error.code)
|
|
269
|
+
console.error(error)
|
|
257
270
|
}
|
|
258
271
|
}
|
|
259
272
|
}
|
|
@@ -261,8 +274,8 @@ try {
|
|
|
261
274
|
|
|
262
275
|
#### Type guards
|
|
263
276
|
|
|
264
|
-
|
|
265
|
-
|
|
277
|
+
These [type guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types)
|
|
278
|
+
distinguish full API responses from partial responses.
|
|
266
279
|
|
|
267
280
|
| Type guard function | Purpose |
|
|
268
281
|
| ------------------------ | ---------------------------------------------------------------------------------------- |
|
|
@@ -273,7 +286,7 @@ provided to distinguish between full and partial API responses.
|
|
|
273
286
|
| `isFullUser` | Determine whether an object is a full `UserObjectResponse` |
|
|
274
287
|
| `isFullComment` | Determine whether an object is a full `CommentObjectResponse` |
|
|
275
288
|
|
|
276
|
-
|
|
289
|
+
Example:
|
|
277
290
|
|
|
278
291
|
```typescript
|
|
279
292
|
const fullOrPartialPages = await notion.dataSources.query({
|
|
@@ -293,26 +306,25 @@ for (const page of fullOrPartialPages.results) {
|
|
|
293
306
|
|
|
294
307
|
### Utility functions
|
|
295
308
|
|
|
296
|
-
|
|
297
|
-
any of our paginated APIs.
|
|
309
|
+
These helpers read results across multiple pages.
|
|
298
310
|
|
|
299
311
|
#### `iteratePaginatedAPI(listFn, firstPageArgs)`
|
|
300
312
|
|
|
301
|
-
|
|
313
|
+
Returns an async iterator that reads each page of results as needed.
|
|
302
314
|
|
|
303
|
-
|
|
315
|
+
Parameters:
|
|
304
316
|
|
|
305
317
|
- `listFn`: Any function on the Notion client that represents a paginated API (i.e. accepts
|
|
306
318
|
`start_cursor`.) Example: `notion.blocks.children.list`.
|
|
307
319
|
- `firstPageArgs`: Arguments that should be passed to the API on the first and subsequent calls
|
|
308
320
|
to the API, for example a `block_id`.
|
|
309
321
|
|
|
310
|
-
|
|
322
|
+
Returns:
|
|
311
323
|
|
|
312
324
|
An [async iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols)
|
|
313
325
|
over results from the API.
|
|
314
326
|
|
|
315
|
-
|
|
327
|
+
Example:
|
|
316
328
|
|
|
317
329
|
```javascript
|
|
318
330
|
for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
|
|
@@ -324,24 +336,21 @@ for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
|
|
|
324
336
|
|
|
325
337
|
#### `collectPaginatedAPI(listFn, firstPageArgs)`
|
|
326
338
|
|
|
327
|
-
|
|
328
|
-
|
|
339
|
+
Accepts the same arguments as `iteratePaginatedAPI` and returns all results in
|
|
340
|
+
one array. The results must fit in memory.
|
|
329
341
|
|
|
330
|
-
|
|
331
|
-
small enough to fit in memory.
|
|
332
|
-
|
|
333
|
-
**Parameters:**
|
|
342
|
+
Parameters:
|
|
334
343
|
|
|
335
344
|
- `listFn`: Any function on the Notion client that represents a paginated API (i.e. accepts
|
|
336
345
|
`start_cursor`.) Example: `notion.blocks.children.list`.
|
|
337
346
|
- `firstPageArgs`: Arguments that should be passed to the API on the first and subsequent calls
|
|
338
347
|
to the API, for example a `block_id`.
|
|
339
348
|
|
|
340
|
-
|
|
349
|
+
Returns:
|
|
341
350
|
|
|
342
351
|
An array with results from the API.
|
|
343
352
|
|
|
344
|
-
|
|
353
|
+
Example:
|
|
345
354
|
|
|
346
355
|
```javascript
|
|
347
356
|
const blocks = await collectPaginatedAPI(notion.blocks.children.list, {
|
|
@@ -352,23 +361,14 @@ const blocks = await collectPaginatedAPI(notion.blocks.children.list, {
|
|
|
352
361
|
|
|
353
362
|
#### `iterateAllDataSourceRows(client, args)`
|
|
354
363
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
`
|
|
358
|
-
pagination such as `iteratePaginatedAPI` stops there and silently misses the rest
|
|
359
|
-
of a larger data source.
|
|
360
|
-
|
|
361
|
-
This utility reads every row anyway. It partitions the data source into
|
|
362
|
-
`created_time` windows: it sorts by `created_time` ascending, and whenever a
|
|
363
|
-
window hits the limit it starts a fresh query from the last row's timestamp.
|
|
364
|
-
Each fresh query has a different filter, so it gets its own result budget. Rows
|
|
365
|
-
that share a boundary timestamp are de-duplicated by id, so every row is yielded
|
|
366
|
-
exactly once.
|
|
364
|
+
Reads rows beyond the limit for a single data source query, which is 10,000 by
|
|
365
|
+
default. At that limit, `has_more` is `false` and `request_status.type` is
|
|
366
|
+
`"incomplete"`; ordinary pagination stops.
|
|
367
367
|
|
|
368
|
-
`created_time`
|
|
369
|
-
|
|
368
|
+
This helper sorts by `created_time` and starts a new query from the last row's
|
|
369
|
+
timestamp each time it reaches the limit. It removes duplicate rows by ID.
|
|
370
370
|
|
|
371
|
-
|
|
371
|
+
Parameters:
|
|
372
372
|
|
|
373
373
|
- `client`: A Notion client instance.
|
|
374
374
|
- `args`: The same arguments as `dataSources.query`, minus the fields the helper
|
|
@@ -376,17 +376,17 @@ rows between windows as they are edited, causing gaps or duplicates.
|
|
|
376
376
|
`created_time` ascending to partition). `data_source_id` is required. Any
|
|
377
377
|
`filter` you pass is combined with the window bound using `and`.
|
|
378
378
|
|
|
379
|
-
|
|
379
|
+
Returns:
|
|
380
380
|
|
|
381
381
|
An async iterator over every row in the data source.
|
|
382
382
|
|
|
383
|
-
|
|
383
|
+
Throws:
|
|
384
384
|
|
|
385
385
|
If a single `created_time` value holds more rows than the limit, the window
|
|
386
386
|
cannot be narrowed by time alone. Pass a `filter` in that case so each window
|
|
387
387
|
stays under the limit.
|
|
388
388
|
|
|
389
|
-
|
|
389
|
+
Example:
|
|
390
390
|
|
|
391
391
|
```javascript
|
|
392
392
|
for await (const row of iterateAllDataSourceRows(notion, {
|
|
@@ -398,23 +398,20 @@ for await (const row of iterateAllDataSourceRows(notion, {
|
|
|
398
398
|
|
|
399
399
|
#### `collectAllDataSourceRows(client, args)`
|
|
400
400
|
|
|
401
|
-
|
|
402
|
-
|
|
401
|
+
Accepts the same arguments as `iterateAllDataSourceRows` and returns all results
|
|
402
|
+
in one array. The full data source must fit in memory. For larger data sources,
|
|
403
|
+
`iterateAllDataSourceRows` reads rows as a stream.
|
|
403
404
|
|
|
404
|
-
|
|
405
|
-
very large data sources, prefer `iterateAllDataSourceRows` and process rows as
|
|
406
|
-
they stream.
|
|
407
|
-
|
|
408
|
-
**Parameters:**
|
|
405
|
+
Parameters:
|
|
409
406
|
|
|
410
407
|
- `client`: A Notion client instance.
|
|
411
408
|
- `args`: The same arguments as `iterateAllDataSourceRows`.
|
|
412
409
|
|
|
413
|
-
|
|
410
|
+
Returns:
|
|
414
411
|
|
|
415
412
|
An array with every row in the data source.
|
|
416
413
|
|
|
417
|
-
|
|
414
|
+
Example:
|
|
418
415
|
|
|
419
416
|
```javascript
|
|
420
417
|
const rows = await collectAllDataSourceRows(notion, {
|
|
@@ -425,7 +422,7 @@ const rows = await collectAllDataSourceRows(notion, {
|
|
|
425
422
|
|
|
426
423
|
### Custom requests
|
|
427
424
|
|
|
428
|
-
|
|
425
|
+
`request()` calls a Notion API endpoint directly. For example:
|
|
429
426
|
|
|
430
427
|
```ts
|
|
431
428
|
// POST /v1/comments
|
|
@@ -442,51 +439,57 @@ const response = await notion.request({
|
|
|
442
439
|
console.log(JSON.stringify(response, null, 2))
|
|
443
440
|
```
|
|
444
441
|
|
|
445
|
-
|
|
442
|
+
`notion.request<ResponseBody>({...})` uses `ResponseBody` as the expected response type. It does not validate that type at runtime.
|
|
446
443
|
|
|
447
444
|
> [!TIP]
|
|
448
|
-
>
|
|
449
|
-
>
|
|
450
|
-
> In the above example, the simpler approach is to use `await notion.comments.create()`.
|
|
445
|
+
> Prefer a named SDK method when one exists, such as `notion.comments.create()` for this example. `request()` can call endpoints that the SDK does not yet cover.
|
|
451
446
|
|
|
452
|
-
|
|
447
|
+
The `Client` constructor also accepts a custom `fetch` function.
|
|
453
448
|
|
|
454
449
|
### Verifying webhook signatures
|
|
455
450
|
|
|
456
|
-
|
|
451
|
+
`verifyWebhookSignature` checks the signature on a [Notion webhook event](https://developers.notion.com/reference/webhooks). It uses the raw request body, the subscription's verification token, and the `X-Notion-Signature` header. The header contains an HMAC-SHA256 signature in the form `sha256=<hex>`.
|
|
457
452
|
|
|
458
453
|
```ts
|
|
459
454
|
import { verifyWebhookSignature } from "@notionhq/client"
|
|
460
455
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
456
|
+
const verificationToken = process.env.NOTION_WEBHOOK_VERIFICATION_TOKEN
|
|
457
|
+
if (!verificationToken) {
|
|
458
|
+
throw new Error("Missing webhook verification token")
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Express example. Use the raw body: parsing and re-serializing JSON
|
|
462
|
+
// can change its bytes and invalidate the signature.
|
|
464
463
|
app.post(
|
|
465
464
|
"/notion-webhook",
|
|
466
465
|
express.text({ type: "application/json" }),
|
|
467
466
|
async (req, res) => {
|
|
467
|
+
const body: unknown = req.body
|
|
468
|
+
if (typeof body !== "string") {
|
|
469
|
+
return res.status(400).send("expected a raw text body")
|
|
470
|
+
}
|
|
468
471
|
const ok = await verifyWebhookSignature({
|
|
469
|
-
body
|
|
472
|
+
body,
|
|
470
473
|
signature: req.header("x-notion-signature"),
|
|
471
|
-
verificationToken
|
|
474
|
+
verificationToken,
|
|
472
475
|
})
|
|
473
476
|
if (!ok) {
|
|
474
477
|
return res.status(401).send("invalid signature")
|
|
475
478
|
}
|
|
476
479
|
|
|
477
|
-
const event = JSON.parse(
|
|
478
|
-
//
|
|
480
|
+
const event: unknown = JSON.parse(body)
|
|
481
|
+
// Validate the event's shape before using its fields.
|
|
479
482
|
res.status(200).send("ok")
|
|
480
483
|
}
|
|
481
484
|
)
|
|
482
485
|
```
|
|
483
486
|
|
|
484
|
-
|
|
487
|
+
Subscription setup is separate from event validation. The [webhook setup guide](https://developers.notion.com/reference/webhooks#step-2-verifying-the-subscription) covers receiving and saving the initial verification token.
|
|
485
488
|
|
|
486
|
-
`signWebhookPayload({ body, verificationToken })`
|
|
489
|
+
`signWebhookPayload({ body, verificationToken })` creates a signature for tests without a live subscription.
|
|
487
490
|
|
|
488
491
|
> [!NOTE]
|
|
489
|
-
> Both helpers are async. They
|
|
492
|
+
> Both helpers are async. They use `globalThis.crypto.subtle` when available and fall back to the Web Crypto API in `node:crypto` on Node.js.
|
|
490
493
|
|
|
491
494
|
## Examples
|
|
492
495
|
|
|
@@ -499,9 +502,7 @@ This package supports the following minimum versions:
|
|
|
499
502
|
- Runtime: `node >= 18`
|
|
500
503
|
- Type definitions (optional): `typescript >= 5.9`
|
|
501
504
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
In some cases, due to backwards-incompatible changes across [Notion API versions](https://developers.notion.com/reference/versioning), more recent versions of this SDK don't work well with older API versions:
|
|
505
|
+
Older versions are not supported. SDK releases also have minimum recommended [Notion API versions](https://developers.notion.com/reference/versioning):
|
|
505
506
|
|
|
506
507
|
| Version of JS/TS SDK | Minimum recommended API version |
|
|
507
508
|
| -------------------- | ------------------------------- |
|
|
@@ -519,24 +520,24 @@ const notion = new Client({
|
|
|
519
520
|
|
|
520
521
|
Key changes in `2026-03-11`:
|
|
521
522
|
|
|
522
|
-
-
|
|
523
|
-
-
|
|
524
|
-
-
|
|
523
|
+
- The `position` parameter replaces `after` on `appendBlockChildren`. It supports `after_block`, `start`, and `end`.
|
|
524
|
+
- The `in_trash` field replaces `archived` on pages, blocks, databases, and data sources.
|
|
525
|
+
- The `meeting_notes` block type replaces `transcription`.
|
|
525
526
|
|
|
526
|
-
|
|
527
|
+
The SDK's TypeScript types include both sets of field names. Older names are marked `@deprecated`.
|
|
527
528
|
|
|
528
|
-
|
|
529
|
+
The `notionVersion` constructor option sets the API version header for requests.
|
|
529
530
|
|
|
530
531
|
## Contributing
|
|
531
532
|
|
|
532
|
-
|
|
533
|
+
Follow [the contribution guide](CONTRIBUTING.md) to build, test, and check SDK compatibility before opening a pull request.
|
|
533
534
|
|
|
534
|
-
|
|
535
|
+
Endpoint code is generated from a schema in Notion's internal repo. Outside contributors cannot run that generator. Ask a maintainer for generated-code changes; direct edits will be overwritten. Open an issue to discuss changes to the SDK's core behavior first.
|
|
535
536
|
|
|
536
|
-
|
|
537
|
+
Docs, examples, and bug reports are welcome.
|
|
537
538
|
|
|
538
539
|
## Getting help
|
|
539
540
|
|
|
540
|
-
|
|
541
|
+
For API support, SDK problems, or feature requests, email `developers@makenotion.com`.
|
|
541
542
|
|
|
542
|
-
|
|
543
|
+
You can also [open an SDK issue](https://github.com/makenotion/notion-sdk-js/issues), but we do not monitor issues as closely as email.
|
package/build/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@notionhq/client",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.27.1",
|
|
4
4
|
"description": "A simple and easy to use client for the Notion API",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
"prepublishOnly": "npm run checkLoggedIn && npm run lint && npm run test",
|
|
27
27
|
"build": "tsc",
|
|
28
28
|
"prettier": "prettier --write .",
|
|
29
|
-
"lint": "prettier --check . && eslint . --ext .ts && cspell '**/*'
|
|
29
|
+
"lint": "prettier --check . && eslint . --ext .ts,.js && cspell '**/*'",
|
|
30
30
|
"test": "jest ./test",
|
|
31
|
+
"check:compatibility": "node build/test/checkCompatibility.js",
|
|
31
32
|
"check-links": "git ls-files | grep md$ | xargs -n 1 markdown-link-check",
|
|
32
33
|
"prebuild": "npm run clean",
|
|
33
34
|
"clean": "rm -rf ./build",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
},
|
|
36
37
|
"lint-staged": {
|
|
37
38
|
"*.{ts,js,json,md}": "prettier --write",
|
|
38
|
-
"*.ts": "eslint --fix"
|
|
39
|
+
"*.{ts,js}": "eslint --fix"
|
|
39
40
|
},
|
|
40
41
|
"author": "",
|
|
41
42
|
"license": "MIT",
|