{"id":51,"library":"notion-client","title":"Notion Python SDK","description":"Official Python client for the Notion API, maintained by the community (ramnes/notion-sdk-py). Current version is 2.7.0 (Oct 2025). Notion API itself is versioned separately — the SDK version and the API version are two different things. Multiple breaking API versions have shipped in 2024-2026.","status":"active","version":"2.7.0","language":"python","source_language":"en","source_url":"https://github.com/ramnes/notion-sdk-py","tags":["notion","api","productivity","database","pages","python"],"install":[{"cmd":"pip install notion-client","lang":"bash","label":"Python (official community SDK)"}],"dependencies":[{"reason":"HTTP client used internally by notion-client.","package":"httpx","optional":false}],"imports":[{"note":"Package is notion-client on PyPI but imports as notion_client. Common confusion.","wrong":"from notion_client import notion","symbol":"Client","correct":"from notion_client import Client"},{"note":"Use AsyncClient in asyncio environments, not the sync Client.","wrong":"from notion_client import Client  # in async context","symbol":"AsyncClient","correct":"from notion_client import AsyncClient"},{"note":"notion-py (jamalex/notion-py) is an unofficial abandoned package using private Notion APIs. Do not use. Use notion-client instead.","wrong":"from notion.client import NotionClient","symbol":"notion-py (abandoned)","correct":"from notion_client import Client"}],"quickstart":{"code":"import os\nfrom notion_client import Client\n\nnotion = Client(auth=os.environ['NOTION_TOKEN'])\n\n# query a database\nresults = notion.databases.query(\n    database_id='YOUR_DATABASE_ID'\n)\n\n# retrieve a page\npage = notion.pages.retrieve(page_id='YOUR_PAGE_ID')\nprint(page['properties'])","lang":"python","description":"Minimal Notion read using notion-client 2.7.x."},"warnings":[{"fix":"Replace all uses of 'archived' with 'in_trash' in request bodies and response handling.","message":"API version 2026-03-11 (released Mar 11 2026) removes 'archived' field — replaced by 'in_trash'. Any code reading or writing 'archived' on pages, databases, or blocks will break when using this API version.","severity":"breaking","affected_versions":"API version >= 2026-03-11"},{"fix":"Replace after='block_id' with position={'type': 'after_block', 'after_block': {'id': 'block_id'}}","message":"API version 2026-03-11: Append block children endpoint no longer accepts flat 'after' string parameter. Now requires a 'position' object.","severity":"breaking","affected_versions":"API version >= 2026-03-11"},{"fix":"Find and replace all references to 'transcription' block type with 'meeting_notes'.","message":"API version 2026-03-11: 'transcription' block type renamed to 'meeting_notes'.","severity":"breaking","affected_versions":"API version >= 2026-03-11"},{"fix":"Fetch data_source_id from database.data_sources array and pass it when creating pages. Migrate database endpoints to /v1/data_sources.","message":"API version 2025-09-03: Multi-source databases introduced. /v1/databases endpoints now refer to the database container, not the data source. Integrations that create pages or define relations must now pass data_source_id.","severity":"breaking","affected_versions":"API version >= 2025-09-03"},{"fix":"Use notion.search() with filter={'value': 'database', 'property': 'object'} instead.","message":"notion.databases.list() raises APIResponseError: 'This API is deprecated'. The List databases endpoint was removed in API version 2022-02-22. Still widely referenced in tutorials.","severity":"breaking","affected_versions":"all current versions"},{"fix":"Remove any hardcoded secret_ prefix validation. Both secret_ and ntn_ tokens are valid.","message":"API token prefix changed from secret_ to ntn_ in September 2024. Code doing regex validation or prefix checks on tokens will reject new ntn_ tokens.","severity":"gotcha","affected_versions":"all"},{"fix":"Pin API version explicitly: Client(auth=token, notion_version='2026-03-11')","message":"SDK version and Notion API version are independent. notion-client 2.7.0 does not automatically use the latest API version. Default API version may lag behind latest.","severity":"gotcha","affected_versions":"all"},{"fix":"Use notion-client (pip install notion-client) — the official SDK.","message":"notion-py (PyPI: notion) is an unofficial package using private undocumented Notion APIs. It breaks without warning when Notion changes internals. Widely referenced in old tutorials.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure the `NOTION_TOKEN` environment variable is properly set in the execution environment before running the application.","message":"The `NOTION_TOKEN` environment variable is required for client authentication but is not set, leading to a KeyError.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T05:59:25.445Z","next_check":"2026-04-17T00:00:00.000Z","problems":[{"fix":"pip install notion-client","cause":"The 'notion-client' library has not been installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'notion_client'"},{"fix":"Verify your `NOTION_TOKEN` is correct and that your Notion integration has been granted access to the specific page or database you are trying to interact with.","cause":"The provided Notion API token is invalid, expired, or lacks the necessary permissions to access the requested resource.","error":"notion_client.errors.APIResponseError: API response returned a 401 status code: Unauthorized"},{"fix":"Access the data using `response['results']` or `response.get('results')` instead of `response.results`.","cause":"NotionResponse objects behave like dictionaries, and their content should be accessed using dictionary-style key lookups (e.g., `['results']`) or the `.get()` method.","error":"AttributeError: 'NotionResponse' object has no attribute 'results'"},{"fix":"Carefully review the official Notion API documentation for the specific endpoint (e.g., creating a page or updating properties) and ensure your Python dictionary matches the expected JSON structure.","cause":"The request body sent to the Notion API contains invalid data, is missing required fields, or has an incorrect structure for properties (e.g., wrong type for a property value).","error":"notion_client.errors.APIResponseError: API response returned a 400 status code: body failed validation. Fix and try again."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":8.2,"disk_size":"22.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":8.2,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.38,"mem_mb":9.5,"disk_size":"24.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":9.5,"disk_size":"25M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.55,"mem_mb":12.6,"disk_size":"16.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":12.6,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.58,"mem_mb":13,"disk_size":"15.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":13,"disk_size":"16M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":8.1,"disk_size":"21.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.19,"mem_mb":8.1,"disk_size":"22M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}