Did your boss ask you to build a Notion integration, but you’ve never used Notion? Familiar with Notion, but wondering about what the API can do? You’re in the right place! This post is meant to get developers who may or may not have used Notion up to speed on the basic building blocks of Notion.
At first glance, you might think of Notion as a note taking tool. But it can do much more than just take down notes. Notion is a productivity and knowledge management tool that lets users do anything from take notes to build sophisticated team workflows. At it’s core is a block based editor for making pages, combined with a database tool that can structure and relate those pages. These building blocks allow it to become almost a no-code development tool. Notion has a wide range of subscription tiers from a free plan to enterprise services, and has many use cases from students managing their coursework to enterprise wide collaboration and project management.
The Official Notion API is a REST API used to make integrations which have various capabilities granting different permissions, like “Read content”, “Insert Comments”, and “Read user information without email addresses”. Integrations start as Internal integrations, which can only be used on the one workspace, and can then be later turned into Public integrations which authenticate using OAuth to integrate with other workspaces. There is also an internal API used by some apps, read more in Official vs Internal API.
The main Notion documentation for end users is at https://www.notion.so/help, while developer focused documentation is at https://developers.notion.com/.
Pages are what you first see when you open up Notion - the New Page button is in the bottom left of the web app. Pages are built up of blocks representing different types of content, like headings, todo lists, paragraphs, and images. Pages also have typed properties. All pages have a title property, and pages that are part of a database may have many others defined by the database schema. All pages have a parent, which may be another page, a block, a database, or the entire workspace; however, the API can’t create objects with a workspace parent.
Databases are groups of pages with the same properties, whose parent is the database. The default view of a Database is a table, where each row is a page with it’s properties, however, there are several other views like a Board, Calendar, or Gallery, though the API can’t currently manipulate views.
In the UI, a database is sometimes treated as a special kind of page - to create one at the top level, you hit the New Page button and choose a database layout, or, type /database on a page to create an inline database or a database as a sup-page, but in the API they are distinct kinds of objects, and where both can be returned by a request, like search, the type is
page_or_database. Like pages, databases have a parent, which can be a page, a block, or the whole workspace, but not another database.
The default Table view of a Database is similar to a a spreadsheet and you can make spreadsheet type formulas using Formula properties, but unlike a spreadsheet, properties are typed, and each row represents a page which can itself have content and sub pages. The same database can have several different views set up on the same or different pages.
Databases have a schema defining the properties, and each page in a database has these properties (though they may be empty). All pages have at least one property of type
title. Properties range from data like text, checkboxes, or dates, to complicated formulas, relations, and roll ups.
Relations allow you to connect one database to another, for example, you could add a Projects column to a Tasks database to relate a Task to it’s parent Project. Roll Ups pull data from one database into another database and perform a calculation, such as a sum of estimated time for tasks in the project database using data from the Tasks database.
Blocks make up the content of a Page. A block can be text based, like a heading, a paragraph, or a list, a reference to another Notion Page or Database, or something completely different, like an image, a built in embed like a Google Map, or any arbitrary embedded web page. Blocks can have child blocks. Not all block types are supported by the API; these will return type
unsupported if requested. Blocks are parented by a page, a database, or another block. The API currently does not support re-ordering blocks - they can be retrieved, updated, deleted, and appended. There is limited support for updating certain kinds of blocks from the API.
Notion supports some limited text formatting including many of the things you can do with Markdown and some other limited text and background colors, links and mentions, and some block types can affect the formatting as well. When using the UI, Markdown syntax can also be used, e.g. ** to make text bold, however, the API does not work with Markdown. Most text based blocks and properties return their content as rich text objects, which are an array of objects for each separately formatted substring of text.
File objects are used to represent both files uploaded to Notion and external linked files. These files are often images. External files are a URL linking to an external resource, while Notion files are retrieved as an Authenticated Amazon S3 URL that expires after an hour, and so an app would either need to make a local copy or make an API call when the authentication expires. The API does not currently support uploading files to Notion.
Most API responses include some user information. The API can be used to retrieve information about users, but the main API can’t be used for creating users, though there is a separate API for that available to Enterprise plans, which is beyond the scope of this blog. Getting detailed user information is a separate API capability.
Pages and blocks can have comments associated with them. Permission to read and/or write comments is a separate capability from reading and writing other kinds of content.
Notion pages can be turned into publicly accessible web pages using the Share button. Some Notion based tools make use of this using the older unofficial API, however, with the official API public status does not matter, it must be connected to the integration.
When sharing to the web, you can “Allow duplicate as template”. This allows people to make a copy of the page (and subpages!) in their workspace. As an integration developer, this can be useful for setting up scaffolding pages for your integration to work with. Templates can also be shared and sold independently of an integration - Notion has a template gallery and there are other third party sites, and many people use sites like Gumroad to sell templates.
The Notion UI makes heavy use of views for filtering, sorting, and displaying databases in different ways, like a table, gallery, or board. Views are not presently part of the API, though database requests support sorting and filtering. The sort order of a database as it appears in the UI is a property of a View, so it’s not possible to duplicate it at this time.
Now you’ve got the basic concepts of Notion and can move on to Getting Started with the Notion API using Python.