# Markdown and Page Content

Use this reference for reading, exporting, appending, and updating page content.

## Read a Page as JSON Blocks

```python
result = helper.get_page(page_id)
properties = result["properties"]
blocks = result["content"]
```

By default, child pages are expanded up to depth 3. Control this with `expand_child_pages=False` or `max_child_page_depth=`.

## Read a Page as Markdown

```python
result = helper.get_page(page_id, return_markdown=True)
markdown = result["content"]
```

`return_markdown` is canonical. Avoid deprecated aliases such as `returnmarkdown` and `markdownformat`.

By default, markdown export uses Notion's native `/v1/pages/{page_id}/markdown` endpoint with API version `2026-03-11`. To force legacy local block conversion:

```python
result = helper.get_page(page_id, return_markdown=True, use_markdown_api=False)
```

Use the native endpoint directly when metadata matters:

```python
markdown_result = helper.get_page_markdown(page_id, include_transcript=True)
markdown = markdown_result["markdown"]
truncated = markdown_result.get("truncated")
unknown = markdown_result.get("unknown_block_ids", [])
```

## Export Markdown to Files

```python
helper.get_page(
    page_id,
    return_markdown=True,
    export_markdown_dir="exports/notion",
    overwrite_existing_export=False,
)
```

The export filename is `{page_id}.md`.

## Append Content

Append markdown:

```python
helper.append_page_body(
    page_id,
    "# Follow-up\n\n- Capture decisions\n- Assign owners",
)
```

Append raw Notion blocks:

```python
helper.append_page_body(
    page_id,
    [
        {
            "object": "block",
            "type": "paragraph",
            "paragraph": {
                "rich_text": [{"type": "text", "text": {"content": "Hello"}}],
            },
        }
    ],
)
```

The helper sanitizes blocks by default and batches append calls at Notion's 100-child limit. Use `sanitize=False` only when the payload is already valid and should be sent as-is.

Supported append conversion includes common headings, paragraphs, bullets, numbered lists, to-dos, quotes, dividers, code fences, images, links, and simple markdown tables. Unsupported or malformed block types are dropped during sanitization.

## Update Native Markdown

Use `update_page_markdown` for Notion's native markdown update endpoint:

```python
helper.update_page_markdown(
    page_id,
    "insert_content",
    content="\n## Decision\nShip the MVP.",
    after="## Notes",
)
```

Supported commands:

- `update_content`: requires `content_updates=[...]`.
- `replace_content`: requires `new_str=...`.
- `insert_content`: requires `content=...`; optional `after=...`.
- `replace_content_range`: requires `content=...` and `content_range=...`.

Set `allow_deleting_content=True` only when intentionally replacing or deleting existing content.

## Custom Conversion

The default converter tries `notion_blockify` when available and falls back to internal conversion. Provide a custom adapter when an app needs stricter conversion:

```python
from notionhelper import ConverterAdapter

class MyAdapter:
    def markdown_to_blocks(self, markdown: str) -> list[dict]:
        ...

    def blocks_to_markdown(self, blocks: list[dict]) -> str:
        ...

helper.set_converter_adapter(MyAdapter())
```
