N2y
Notion to YAML (and Markdown)
Install / Use
/learn @innolitics/N2yREADME
Notion to YAML
This commandline tool exports data from selected Notion pages and databases into YAML and markdown files. Internally, it converts the Notion pages into a Pandoc AST, which enables fine-grained customization of the conversion process.
We use it at Innolitics to generate pages for our website, thus allowing us to use Notion as a content management system. We also use it to generate PDFs and Word Documents from Notion pages.
Installation
Install first pandoc and mermaid CLIs. Please note that n2y has only been tested with pandoc 2.19.2 and mermaid-cli 9.4.0. This pandoc link will take you to their 2.19.2 github releases page. This mermaid link will take you to their github page where you will find installation instructions. If using npm to install mermaid, append @9.4.0 to the npm command to install that specific version.
Finally, install n2y:
pip install n2y
Authorization
Before you'll be able to export any content from your Notion account you'll first need to give n2y permission to access the pages. You'll need to be an admin.
To do this, go to the "Settings and Members" page in Notion. You should see an "Integrations" option in the side bar. Click the link that says "Develop your own integrations" and follow the instructions on the page. Copy the "Internal Integration Token" into the NOTION_ACCESS_TOKEN environment variable.
Finally, in Notion you'll need to share the relevant pages with your internal integration---just like you'd share a page with another person.
Configuration
N2y is configured using a single YAML file. This file contains a few top-level keys:
| Top-level key | Description | | --- | --- | | media_url | Sets the base URL for all downloaded media files (e.g., images, videos, PDFs, etc.) | | media_root | The directory where media files should be downloaded to | | exports | A list of export configuration items, indicating how a notion page or database is to be exported. See below for the keys. | | export_defaults | Default values for the export configuration items. |
The export configuration items may contain the following keys:
| Export key | Description |
| --- | --- |
| id | The notion database or page id, taken from the "share URL". |
| node_type | Either "database_as_yaml", "database_as_files", or "page". |
| output | The path the output file, or directory, where the data will be written. |
| pandoc_format | The pandoc format that we're generating. |
| pandoc_options | A list of strings that are writer options for pandoc. |
| content_property | When set, it indicates the property name that will contain the content of the notion pages in that databse. If set to None, then only the page's properties will be included in the export. (Only applies to the database_as_files node type.) |
| yaml_front_matter | Only used when exporting to text files. Indicates if the page properties should be exported as yaml front matter. |
| id_property | When set, this indicates the property name in which to place the page's underlying notion ID. |
| url_property | When set, this indicates the property name in which to place the page's underlying notion url. |
| filename_template | This key is only used for the "database_as_files" node type; when set, it provides a format string that is evaluated against the page's properties to generate the file name. Note that the filenames are sanitized. When not set, the title property is used and the extension is deduced from the pandoc_format. A special "TITLE" property may be used to access the title property in the template string. |
| plugins | A list of python modules to use as plugins. |
| notion_filter | A notion filter object to be applied to the database. |
| notion_sorts | A notion sorts object to be applied to the database. |
| property_map | A mapping between the name of properties in Notion, and the name of the properties in the exported files. Set the new value to null to discard the property.|
Example Configuration Files
The command is run using n2y configuration.yaml.
Convert a Database to YAML
A notion database (e.g., with a share URL like this https://www.notion.so/176fa24d4b7f4256877e60a1035b45a4?v=130ffd3224fd4512871bb45dbceaa7b2) could be exported into a YAML file using this minimal configuration file:
exports:
- id: 176fa24d4b7f4256877e60a1035b45a4
node_type: database_as_yaml
output: database.yml
Convert a Database to a set of Markdown Files
The same database could be exported into a set of markdown files as follows:
exports:
- id: 176fa24d4b7f4256877e60a1035b45a4
node_type: database_as_files
output: directory
filename_template: "{Name}.md"
Each page in the database will generate a single markdown file, named according to the filename_template. This process will automatically skip pages whose "Name" property is empty.
Convert a Page to a Markdown File
An individual notion page (e.g., with a share URL like this https://www.notion.so/All-Blocks-Test-Page-5f18c7d7eda44986ae7d938a12817cc0) could be exported to markdown with this minimal configuration file:
exports:
- id: 5f18c7d7eda44986ae7d938a12817cc0
node_type: page
output: page.md
Audit a Page and it's Children For External Links
Sometimes it is useful to ensure that a root Notion page, and it's child-pages, don't contain links to any notion pages outside the hierarchy. The n2yaudit tool can be used to audit a page hierarchy for any of these links.
n2yaudit PAGE_LINK
Bigger Example
This example shows how you can use the export_defaults property to avoid duplicated configuration between export items. It also shows now you can use notion filters to export pages from the same database into two different directories.
media_root: "media"
media_url: "./media/"
export_defaults:
plugins:
- "n2y.plugins.mermaid"
- "n2y.plugins.rawcodeblocks"
- "n2y.plugins.removecallouts"
- "n2y.plugins.deepheaders"
- "n2y.plugins.expandlinktopages"
content_property: null
id_property: id
url_property: url
exports:
- output: "documents/dhf"
node_type: "database_as_files"
filename_template: "{Name}.md"
id: e24f839e724848d69342d43c07cb5f3e
plugins:
- "n2y.plugins.mermaid"
- "n2y.plugins.rawcodeblocks"
- "n2y.plugins.removecallouts"
- "n2y.plugins.deepheaders"
- "n2y.plugins.expandlinktopages"
- "plugins.page"
- "plugins.idmentions"
notion_filter:
property: "Tags"
multi_select: { "contains": "DHF" }
- output: "documents/510k"
id: e24f839e724848d69342d43c07cb5f3e
filename_template: "{Name}.md"
node_type: "database_as_files"
plugins:
- "n2y.plugins.mermaid"
- "n2y.plugins.rawcodeblocks"
- "n2y.plugins.removecallouts"
- "n2y.plugins.deepheaders"
- "n2y.plugins.expandlinktopages"
- "plugins.page"
- "plugins.idmentions"
notion_filter:
property: "Tags"
multi_select: { "contains": "510(k)" }
- output: "data/Roles.yml"
id: b47a694953714222810152736d9dc66c
node_type: "database_as_yaml"
content_property: "Description"
- output: "data/Glossary.yml"
id: df6bef74e2372118becd93e321de2c69
node_type: "database_as_yaml"
Plugins
At the core of n2y are a set of python classes that represent the various parts of a Notion workspace:
| Notion Object Type | Description | | --- | --- | | Page | Represents a Notion page (which may or may not be in a database) | | Database | A Notion database, which can also be though of as a set of Notion pages with some structured meta data, or properties | | Property | A type descriptor for a property (or column) in a Notion database | | PropertyValue | A particular value that a particular page in database has for a particular Property | | Block | A bit of content within a Page | | RichTextArray | A sequence of formatted text in Notion; present in many blocks and property values | | RichText | A segment of text with the same styling | | Mention | A reference to another Notion object (e.g., a page, database, block, user, etc. ) | User | A notion user; used in property values and in page, block, and database metadata | | File | A file | | Emoji | An emoji |
The Property, PropertyValue, Block, RichText, and Mention classes have subclasses that represent the various subtypes. E.g., there is a ParagraphBlock that represents paragraph.
These classes are responsible for converting the Notion data into pandoc abstract syntax tree objects. We use a python wrapper library that makes it easier to work with pandoc's AST. See here for details. See the Notion API documentation for details about their data structures.
The default implementation of these classes can be modified using a plugin system. To create a plugin, follow these steps:
- Create a new Python module
- Subclass the various notion classes, modifying their constructor or
to_pandocmethod as desired - Set the
pluginsproperty in your export config to the module name (e.g.,n2y.plugins.deepheaders)
See the builtin plugins for examples.
Using Multiple Plugins
You can use multiple plugins. If two plugins provide cla
Related Skills
apple-reminders
350.1kManage Apple Reminders via remindctl CLI (list, add, edit, complete, delete). Supports lists, date filters, and JSON/plain output.
node-connect
350.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
notion
350.1kNotion API for creating and managing pages, databases, and blocks.
