Skip to content

Configuration

Brandon Young edited this page Nov 5, 2026 · 1 revision

Configuration

You need two things from Notion: an integration token and the ID of the page that will be the root of your sync.

1. Create a Notion integration

  1. Go to notion.so/my-integrations and create a new internal integration.
  2. Copy its token. New tokens start with ntn_; older secret_ tokens also work.

2. Share the parent page with it

  1. Open the page you want to sync under.
  2. In the page's ••• menu, open Connections and add your integration. Sub-pages inherit the access.
  3. Copy the page ID: the 32-character hex string at the end of the page URL.

3a. Guided setup: init

Run this in your project folder:

notion-md-sync init

It asks for the token, the parent page ID and a Markdown folder (default ./docs), then creates:

File Contents
config.yaml Settings
.env Your token and page ID (written with mode 0600)
.env.example A blank template you can commit
docs/welcome.md A sample page to push

init needs an interactive terminal. It always asks for the token, even if NOTION_MD_SYNC_NOTION_TOKEN is already set. If a config.yaml already exists it changes nothing.

3b. Manual setup

Put your secrets in a .env file (never commit it):

NOTION_MD_SYNC_NOTION_TOKEN=ntn_your_token_here
NOTION_MD_SYNC_NOTION_PARENT_PAGE_ID=your_page_id_here

And create config.yaml. The repo has a template at config/config.template.yaml:

notion:
  token: ""            # leave empty, set NOTION_MD_SYNC_NOTION_TOKEN
  parent_page_id: ""   # leave empty, set NOTION_MD_SYNC_NOTION_PARENT_PAGE_ID

directories:
  markdown_root: ./docs
  excluded_patterns:
    - '*.tmp'
    - 'node_modules/**'
    - '.git/**'

sync:
  conflict_resolution: newer   # newer, notion_wins, markdown_wins, diff

Then check it:

notion-md-sync verify

Where settings are read from

Config file, first match wins:

  1. The path given with --config / -c
  2. ./config.yaml
  3. ./configs/config.yaml
  4. ~/.notion-md-sync/config.yaml

A config file is optional if both environment variables are set. The repo's template lives in config/ (singular), which is not searched. Copy it to ./config.yaml or pass -c.

.env file, first match wins: ./.env, then ~/.notion-md-sync/.env, then up to three parent folders.

Environment variables override the config file:

Variable Setting
NOTION_MD_SYNC_NOTION_TOKEN notion.token
NOTION_MD_SYNC_NOTION_PARENT_PAGE_ID notion.parent_page_id

Settings reference

Key Default Meaning
notion.token — Integration token. Required. Prefer the env var.
notion.parent_page_id — Root page of the sync. Required.
directories.markdown_root ./ Folder that holds your Markdown tree.
directories.excluded_patterns none Glob patterns that are never synced. Hidden folders such as .git and .notion-sync are always skipped.
sync.conflict_resolution diff What sync bidirectional does when both sides changed. newer keeps whichever side changed last, and falls back to diff when a time is unknown. notion_wins keeps Notion's version. markdown_wins keeps the local file. diff shows both and asks you.
sync.direction push Shown by verify. The sync command doesn't read it: pass the direction as an argument.
mapping.strategy filename Accepted but not used. Page titles always come from the frontmatter title, or the file name when there is none.
performance.workers 0 Concurrent workers for pull. 0 picks a count from the number of pages.
performance.use_multi_client false Experimental: spread requests over several HTTP clients.
performance.client_count 3 Number of clients when use_multi_client is on.

Global flags

Flag Meaning
-c, --config <path> Use this config file
-v, --verbose More output
--timeout <duration> Stop a command after this long (default 30m)

Keeping secrets safe

  • Keep the token in .env or your environment, not in config.yaml.
  • Add .env and any config containing a token to .gitignore.
  • Commit .env.example instead.

Clone this wiki locally