- Notifications
You must be signed in to change notification settings - Fork701
Official Notion JavaScript Client
License
makenotion/notion-sdk-js
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A simple and easy to use client for theNotion API.
npm install @notionhq/client
Note
Use Notion'sGetting Started Guide to get set up to use Notion's API.
Import and initialize a client using anintegration token or an OAuthaccess token.
const{ Client}=require("@notionhq/client")// Initializing a clientconstnotion=newClient({auth:process.env.NOTION_TOKEN,})
Make a request to any Notion API endpoint.
;(async()=>{constlistUsersResponse=awaitnotion.users.list({})})()
Note
See the complete list of endpoints in theAPI reference.
Each method returns aPromise that resolves the response.
console.log(listUsersResponse)
{results:[{object:"user",id:"d40e767c-d7af-4b18-a86d-55c61f1e39a4",type:"person",person:{email:"avo@example.org",},name:"Avocado Lovelace",avatar_url:"https://secure.notion-static.com/e6a352a8-8381-44d0-a1dc-9ed80e62b53d.jpg",},// ...]}
Endpoint parameters are grouped into a single object. You don't need to remember which parameters go in the path, query, or body.
constmyPage=awaitnotion.dataSources.query({data_source_id:"897e5a76-ae52-4b48-9fdf-e71f5945d1af",filter:{property:"Landmark",rich_text:{contains:"Bridge",},},})
If the API returns an unsuccessful response, the returnedPromise rejects with aAPIResponseError.
The error contains properties from the response, and the most helpful iscode. You can comparecode to the values in theAPIErrorCode object to avoid misspelling error codes.
const{ Client, APIErrorCode}=require("@notionhq/client")try{constnotion=newClient({auth:process.env.NOTION_TOKEN})constmyPage=awaitnotion.dataSources.query({data_source_id:dataSourceId,filter:{property:"Landmark",rich_text:{contains:"Bridge",},},})}catch(error){if(error.code===APIErrorCode.ObjectNotFound){//// For example: handle by asking the user to select a different data source//}else{// Other error handling codeconsole.error(error)}}
The client emits useful information to a logger. By default, it only emits warnings and errors.
If you're debugging an application, and would like the client to log response bodies, set thelogLevel option toLogLevel.DEBUG.
const{ Client, LogLevel}=require("@notionhq/client")constnotion=newClient({auth:process.env.NOTION_TOKEN,logLevel:LogLevel.DEBUG,})
You may also set a customlogger to emit logs to a destination other thanstdout. A custom logger is a function which is called with 3 parameters:logLevel,message, andextraInfo. The custom logger should not return a value.
TheClient supports the following options on initialization. These options are all keys in the single constructor parameter.
| Option | Default value | Type | Description |
|---|---|---|---|
auth | undefined | string | Bearer token for authentication. If left undefined, theauth parameter should be set on each request. |
logLevel | LogLevel.WARN | LogLevel | Verbosity of logs the instance will produce. By default, logs are written tostdout. |
timeoutMs | 60_000 | number | Number of milliseconds to wait before emitting aRequestTimeoutError |
baseUrl | "https://api.notion.com" | string | The root URL for sending API requests. This can be changed to test with a mock server. |
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 thanlogLevel. |
agent | Default node agent | http.Agent | Used to control creation of TCP sockets. A common use is to proxy requests withhttps-proxy-agent |
This package contains type definitions for all request parameters and responses,as well as some useful sub-objects from those entities.
Because errors in TypeScript start with typeany orunknown, you should usetheisNotionClientError type guard to handle them in a type-safe way. EachNotionClientError type is uniquely identified by itserror.code. Codes intheAPIErrorCode enum are returned from the server. Codes in theClientErrorCode enum are produced on the client.
try{constresponse=awaitnotion.dataSources.query({/* ... */})}catch(error:unknown){if(isNotionClientError(error)){// error is now strongly typed to NotionClientErrorswitch(error.code){caseClientErrorCode.RequestTimeout:// ...breakcaseAPIErrorCode.ObjectNotFound:// ...breakcaseAPIErrorCode.Unauthorized:// ...break// ...default:// you could even take advantage of exhaustiveness checkingassertNever(error.code)}}}
There are severaltype guardsprovided to distinguish between full and partial API responses.
| Type guard function | Purpose |
|---|---|
isFullPage | Determine whether an object is a fullPageObjectResponse |
isFullBlock | Determine whether an object is a fullBlockObjectResponse |
isFullDataSource | Determine whether an object is a fullDataSourceObjectResponse |
isFullPageOrDataSource | Determine whether an object is a fullPageObjectResponse orDataSourceObjectResponse |
isFullUser | Determine whether an object is a fullUserObjectResponse |
isFullComment | Determine whether an object is a fullCommentObjectResponse |
Here is an example of using a type guard:
constfullOrPartialPages=awaitnotion.dataSources.query({data_source_id:"897e5a76-ae52-4b48-9fdf-e71f5945d1af",})for(constpageoffullOrPartialPages.results){if(!isFullPageOrDataSource(page)){continue}// The page variable has been narrowed from// PageObjectResponse | PartialPageObjectResponse | DataSourceObjectResponse | PartialDataSourceObjectResponse// to// PageObjectResponse | DataSourceObjectResponse.console.log("Created at:",page.created_time)}
This package also exports a few utility functions that are helpful for dealing withany of our paginated APIs.
This utility turns any paginated API into an async iterator.
Parameters:
listFn: Any function on the Notion client that represents a paginated API (i.e. acceptsstart_cursor.) Example:notion.blocks.children.list.firstPageArgs: Arguments that should be passed to the API on the first and subsequent callsto the API, for example ablock_id.
Returns:
Anasync iteratorover results from the API.
Example:
forawait(constblockofiteratePaginatedAPI(notion.blocks.children.list,{block_id:parentBlockId,})){// Do something with block.}
This utility accepts the same arguments asiteratePaginatedAPI, but collectsthe results into an in-memory array.
Before using this utility, check that the data you are dealing with issmall enough to fit in memory.
Parameters:
listFn: Any function on the Notion client that represents a paginated API (i.e. acceptsstart_cursor.) Example:notion.blocks.children.list.firstPageArgs: Arguments that should be passed to the API on the first and subsequent callsto the API, for example ablock_id.
Returns:
An array with results from the API.
Example:
constblocks=awaitcollectPaginatedAPI(notion.blocks.children.list,{block_id:parentBlockId,})// Do something with blocks.
To make requests directly to a Notion API endpoint instead of using the pre-built families of methods, call therequest() method. For example:
// POST /v1/commentsconstresponse=awaitnotion.request({path:"comments",method:"post",body:{parent:{page_id:"5c6a28216bb14a7eb6e1c50111515c3d"},rich_text:[{text:{content:"Hello, world!"}}],},// No `query` params in this example, only `body`.})console.log(JSON.stringify(response,null,2))
Thenotion.request<ResponseBody>({...}) method is generic;ResponseBody represents the expected type of response object Notion returns for the endpoint you're calling (we don't validate this at runtime; you can pass anything!)
Tip
Usually, making custom requests withnotion.request() isn't necessary, but can be helpful in some cases, e.g. when upgrading yourNotion API version incrementally before upgrading your SDK version. For example, if there's a new or renamed endpoint in the new API version that isn't yet available to call via a dedicated method onClient.
In the above example, the simpler approach is to useawait notion.comments.create().
Another customization you can make is to pass your ownfetch function to theClient constructor. This might be helpful for some execution environments where the default, built-infetch isn't suitable.
For sample code and example projects, seenotion-cookbook.
This package supports the following minimum versions:
- Runtime:
node >= 18 - Type definitions (optional):
typescript >= 5.9
Earlier versions may still work, but we encourage people building new applications to upgrade to the current stable.
In some cases, due to backwards-incompatible changes acrossNotion API versions, more recent versions of this SDK don't work well with older API versions:
| Version of JS/TS SDK | Minimum recommended API version |
|---|---|
| v4.0.0 and above | 2022-06-28 |
| v5.0.0 and above | 2025-09-03 |
In these cases, we recommend upgrading your Notion API version header using theClient() constructor across all of your requests before upgrading to a newer version of the SDK.
If you want to submit a feature request for Notion's API, or are experiencing any issues with the API platform, please email us atdevelopers@makenotion.com.
To report issues with the SDK, it is possible tosubmit an issue to this repo. However, we don't monitor these issues very closely. We recommend you reach out to us atdevelopers@makenotion.com instead.
About
Official Notion JavaScript Client
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.