v1) is deprecated. The next Notion-Version makes Notion-flavored Markdown (v2) the default and rejects markdown_version: "v1". Watch the changelog for the version name and date.
You can switch now on any current Notion-Version. The steps below cover the request change, the syntax changes, and how to test.
1. Find where you send markdown
These endpoints acceptmarkdown_version:
On
POST /v1/pages and the comment endpoints, send markdown_version only with markdown. Sending it with children or rich_text returns a 400 validation_error.
2. Add markdown_version: "v2"
Set the parameter on every request in the table. The version applies to the whole request, so v2 input is parsed as v2 and v2 responses are rendered as v2.
markdown_version in @notionhq/client v5.29.0 and later.
3. Update your parser and generator
Compare your code against the syntax differences table below. The biggest changes are structural:- Separate blocks with a blank line. In
v2, a single newline doesn’t start a new block. - Don’t indent children with tabs, except in lists. A block that has children uses its tag form, such as
<p>,<quote>, or<toggle>, with the children after a blank line. - Put block colors in a
colorattribute on the block’s tag.v2saves{color="..."}as literal text. - Expect
v2output to use tags for inline formatting, such as<b>and<code>, wherev1used**and backticks.
v2 syntax, see the Notion-flavored Markdown format reference.
4. Handle new v2 behavior
Parse errors return a400. When v2 input can’t become the blocks it describes, the request fails with a validation_error whose message starts with Markdown errors blocked parsing. v1 saved the same input as literal text. For example, an image inside a line of text (Text  more) fails in v2. Put each image on its own line with blank lines around it.
Updates can return warnings. A PATCH /v1/pages/:page_id/markdown request that succeeds can include a warnings array. Each entry has a code and a message:
Log these warnings while you migrate. A
deprecated_tag warning means your generator still writes v1 syntax. See Update warnings for the response shape.
Meeting note transcripts use a new tag. v2 puts the transcript in <meeting-notes-section-transcript> inside <meeting-notes>. See Transcripts in v2.
5. Test the switch
- Pick a page that uses the block types your integration reads or writes.
- Retrieve it twice, once with
markdown_version=v1and once withmarkdown_version=v2. Diff the two outputs and check each difference against the table below. - Run your parser on the
v2output and confirm it finds the same blocks it found in thev1output. - On a test page, write your generator’s output with
PATCH /v1/pages/:page_id/markdown,"type": "replace_content", and"markdown_version": "v2". Check that the response has nowarnings. Then retrieve the page withmarkdown_version=v2and run your parser on it. Check that it finds the blocks you meant to write. Don’t compare exact text, becausev2output can differ from valid input, such as<b>for**.
Syntax differences
Each row shows the same content in both versions, taken from real API output. Syntax not listed here, such as plain headings, bulleted and numbered list items,- [ ] to-dos, links, images, dividers, fenced code, block equations, citations, and custom emoji, is the same in both versions.
Structure
Blocks
Inline content
Common problems
Content runs together into one block. Your generator puts one newline between blocks. Add a blank line between blocks. A quote swallows the lines after it. A line right after a> line joins the quote. Add a blank line after the quote.
Indented text joins its parent paragraph. Tab indentation only nests list items in v2. For other children, use the parent’s tag form, such as <p> or <toggle>.
{color="..."} shows up as text on the page. v2 doesn’t read the v1 color syntax and doesn’t warn about it. Move the color into the block’s color attribute.
An update fails with Markdown errors blocked parsing. The input mixes syntax that v2 can’t parse, such as an image inside a line of text. The error message says what to fix.