Concept of Notion
First of all, you have to know that I really like Notion. I've tested plenty of tools and I have never been satisfied. Notion is an online tool, a really good one which gives you ability to create nice interface many kinds of content, like TODO-list, wiki, specs, timeline, database, and so on...
And to me, the best advantage of Notion to me is the flexibility of the tool. With only one screen, you can show up easily different views for different teams within your organization.
But compared to the other close tools like Jira or Trello, Notion lacks a very important point: an API.
But since 05/13, a bêta release of Notion API & SDK have been released ! I was so excited about it I couldn't wait to give a try.
API Stacks
Notion API is available with curl or Javascript SDK, with only one dependency which is got.
The SDK basically offers a client, an error registry and few methods implementation ; some examples are given in a following section ;)
The library weighs for a total of 224k, which is acceptable since it also includes Typescript support.
Dive into the API
For our API test, we will only use the Javascript SDK of the Notion API, which brings reusability and sharing all around the world.
A full example can be found here.
Note that all examples are written in Typescript.
Authentication
First at all, you must create a new Integration service in Notion. It will have its private token, keep it secret !
After that, you can start playing with the API.
const { Client } = require('@notionhq/client');
// Initializing a client
const notion = new Client({
auth: process.env.NOTION_TOKEN
});
Important note: each database or page shared with the Integration service will be accessible.
Users
You can either list all users.
notion.users.list();
Or retrieve a single one.
notion.users.retrieve({
user_id: USER_ID
});
Databases
You can list notion databases the Integration service is subscribed to.
notion.databases.list();
Or look for a specific one.
notion.databases.retrieve({
database_id: DATABASE_ID
});
And query one or more items on a specific database.
notion.databases.query({
database_id: DATABASE_ID,
filter: {
property: 'Town',
text: {
contains: 'Tokyo'
},
},
});
Pages
You can create a new page in a page, or a database.
notion.pages.create({
parent: {
page_id: PAGE_ID
},
properties: {
title: [{
type: "text",
text: {
content: "Apple"
}
}],
}
});
You can list all blocks contained in a parent block.
notion.blocks.children.list({
block_id: PAGE_ID
});
And you can append a block on a parent block.
notion.blocks.children.append({
block_id: PAGE_ID
children: [{
object: "block",
type: "paragraph",
paragraph: {
text: [{
type: "text",
text: {
content: "An apple is red, green or yellow"
}
}]
}
}]
});
Search
You can perform a search on your Notion accessible objects from the Integration service Point of view.
notion.search({
query: 'Apple'
});
The query parameter is used to match page titles. In addition, you can sort and filter your results, but only few parameters are accepted.
notion.search({
query: 'Apple',
// Only last_edited_time field is supported
sort: {
direction: 'ascending',
timestamp: 'last_edited_time'
},
// Only object field with page/database values are supported
filter: {
property: 'object',
value: 'page'
},
});
Pagination
Pagination is easy in Notion, just re-use the next_cursor
if more results are available by testing has_more
parameter.
(async () => {
const res = await notion.search({
query: 'Apple',
page_size: 1
});
if (res.has_more) {
notion.search({
start_cursor: res.next_cursor
})
}
})();
Deal with errors
When performing request, sometimes you get errors.
You can check the type of the error with the err.code
attribute, and provide proper fallback or deal.
try {
...
} catch (err) {
if (err.code == APIErrorCode.Unauthorized) {
console.error('Unauthorized error. Definitive.');
}
if (err.code == APIErrorCode.RestrictedResource) {
console.error('Restricted resource error. Definitive.');
}
if (err.code == APIErrorCode.ObjectNotFound) {
console.error('Object not found. Definitive. Check for the right identifier.');
}
if (err.code == APIErrorCode.RateLimited) {
console.error('Rate limit reach, try later. Temporary.');
}
if (err.code == APIErrorCode.InvalidJSON) {
console.error('Invalid JSON. Temporary.');
}
}
Note that only the RateLimited is not a definitive error.
Sources
Go visit Notion developer website :)
Thanks for reading !
Feedbacks and comments are welcome ! :heart: