Description
<!-- markdownlint-disable -->  <div align="center"> <p> <a href="https://pypi.org/project/notion-client"><img src="https://img.shields.io/pypi/v/notion-client.svg" alt="PyPI"></a> <a href="tox.ini"><img src="https://img.shields.io/pypi/pyversions/notion-client" alt="Supported Python Versions"></a> <br/> <a href="LICENSE"><img src="https://img.shields.io/github/license/ramnes/notion-sdk-py" alt="License"></a> <a href="https://github.com/ambv/black"><img src="https://img.shields.io/badge/code%20style-black-black" alt="Code style"></a> <a href="https://codecov.io/github/ramnes/notion-sdk-py"><img src="https://codecov.io/gh/ramnes/notion-sdk-py/branch/main/graphs/badge.svg" alt="Coverage"></a> <a href="https://pypistats.org/packages/notion-client"><img src="https://img.shields.io/pypi/dm/notion-client" alt="Package downloads"></a> <br/> <a href="https://github.com/ramnes/notion-sdk-py/actions/workflows/quality.yml"><img src="https://github.com/ramnes/notion-sdk-py/actions/workflows/quality.yml/badge.svg" alt="Code Quality"></a> <a href="https://github.com/ramnes/notion-sdk-py/actions/workflows/test.yml"><img src="https://github.com/ramnes/notion-sdk-py/actions/workflows/test.yml/badge.svg" alt="Tests"></a> <a href="https://github.com/ramnes/notion-sdk-py/actions/workflows/docs.yml"><img src="https://github.com/ramnes/notion-sdk-py/actions/workflows/docs.yml/badge.svg" alt="Docs"></a> </p> </div> <!-- markdownlint-enable --> **_notion-sdk-py_ is a simple and easy to use client library for the official [Notion API](https://developers.notion.com/).** It is meant to be a Python version of the reference [JavaScript SDK](https://github.com/makenotion/notion-sdk-js), so usage should be very similar between both. 😊 (If not, please open an issue or PR!) <!-- markdownlint-disable --> ## Installation <!-- markdownlint-enable --> ```shell pip install notion-client ``` ## Usage > Use Notion's [Getting Started Guide](https://developers.notion.com/docs/getting-started) > to get set up to use Notion's API. Import and initialize a client using an **integration token** or an OAuth **access token**. ```python import os from notion_client import Client notion = Client(auth=os.environ["NOTION_TOKEN"]) ``` In an asyncio environment, use the asynchronous client instead: ```python from notion_client import AsyncClient notion = AsyncClient(auth=os.environ["NOTION_TOKEN"]) ``` Make a request to any Notion API endpoint. ```python from pprint import pprint list_users_response = notion.users.list() pprint(list_users_response) ``` > [!NOTE] > See the complete list of endpoints in the [API reference](https://developers.notion.com/reference). or with the asynchronous client: ```python list_users_response = await notion.users.list() pprint(list_users_response) ``` This would output something like: ```text {'results': [{'avatar_url': 'https://secure.notion-static.com/e6a352a8-8381-44d0-a1dc-9ed80e62b53d.jpg', 'id': 'd40e767c-d7af-4b18-a86d-55c61f1e39a4', 'name': 'Avocado Lovelace', 'object': 'user', 'person': {'email': 'avo@example.org'}, 'type': 'person'}, ...]} ``` All API endpoints are available in both the synchronous and asynchronous clients. Endpoint parameters are grouped into a single object. You don't need to remember which parameters go in the path, query, or body. ```python my_page = notion.data_sources.query( **{ "data_source_id": "897e5a76-ae52-4b48-9fdf-e71f5945d1af", "filter": { "property": "Landmark", "rich_text": { "contains": "Bridge", }, }, } ) ``` ### Handling errors If the API returns an unsuccessful response, an `APIResponseError` will be raised. The error contains properties from the response, and the most helpful is `code`. You can compare `code` to the values in the `APIErrorCode` object to avoid misspelling error codes. ```python import logging from notion_client import APIErrorCode, APIResponseError, Client try: notion = Client(auth=os.environ["NOTION_TOKEN"]) my_page = notion.data_sources.query( **{ "data_source_id": "897e5a76-ae52-4b48-9fdf-e71f5945d1af", "filter": { "property": "Landmark", "rich_text": { "contains": "Bridge", }, }, } ) except APIResponseError as error: if error.code == APIErrorCode.ObjectNotFound: # # For example: handle by asking the user to select a different data source # ... else: # Other error handling code print(error) ``` ### Logging The cli
Release History
| Version | Changes | Urgency | Date |
|---|---|---|---|
| 3.0.0 | Imported from PyPI (3.0.0) | Low | 4/21/2026 |
| 2.7.0 | ## What's Changed * Add generate random data example by @Sumeet213 in https://github.com/ramnes/notion-sdk-py/pull/292 * Prevent resource leaks in tests when failures occur by @Sumeet213 in https://github.com/ramnes/notion-sdk-py/pull/291 * Add support for `additional_data` and `request_id` fields in the `APIResponseError` class by @tsinglinrain in https://github.com/ramnes/notion-sdk-py/pull/293 * Add missing VCR cassettes for `additional_data` and `request_id` tests by @tsinglinrain in htt | Low | 10/31/2025 |
| 2.6.0 | ⚠️ Beware, `Notion-Version` has been upgraded to `2025-09-03`. This version of the SDK is not compatible with older versions of the API. See [Notion's upgrade guide](https://developers.notion.com/docs/upgrade-guide-2025-09-03) to learn more. ## What's Changed * Add `attachements` and `display_name` to body by @zubu007 in https://github.com/ramnes/notion-sdk-py/pull/281 * Add id extraction utilities for Notion URLs by @riwaht in https://github.com/ramnes/notion-sdk-py/pull/282 * Added data | Low | 10/23/2025 |
| 2.5.0 | ## What's Changed * Support file uploads by @tsinglinrain in https://github.com/ramnes/notion-sdk-py/pull/270 ## New Contributors * @tsinglinrain made their first contribution in https://github.com/ramnes/notion-sdk-py/pull/270 **Full Changelog**: https://github.com/ramnes/notion-sdk-py/compare/2.4.0...2.5.0 | Low | 8/26/2025 |
| 2.4.0 | ## What's Changed * Add `column` body param for block updates * Implement GitHub CI cron job to open issues on new Notion API Changelog by @MassimoGennaro in https://github.com/ramnes/notion-sdk-py/pull/244 * Fix tests and update cassettes by @ramnes in https://github.com/ramnes/notion-sdk-py/pull/248 * Token format update: secret_ → ntn_ by @rafeyrana in https://github.com/ramnes/notion-sdk-py/pull/246 * Fixed pytest scope warning by @chinmay29hub in https://github.com/ramnes/notion-sdk-py | Low | 6/17/2025 |
| 2.3.0 | ## What's Changed * Official support of Python 3.13 * Security update of httpx minimum version * Add `in_trash` property to PagesEndpoint, by @jjongguet in https://github.com/ramnes/notion-sdk-py/pull/236 * Repo update: we switched to Ruff, by @baydinvladislav in https://github.com/ramnes/notion-sdk-py/pull/229 * Example fix: `text` should be `rich_text`, by @yangxinyi-bigdata in https://github.com/ramnes/notion-sdk-py/pull/232 ## New Contributors * @baydinvladislav made their first con | Low | 12/18/2024 |
| 2.2.1 | Quick fix for iteration helpers that got broken in 2.2.0. | Low | 12/28/2023 |
| 2.2.0 | ## What's Changed * Icons and covers can now be removed from pages. (Thanks to @FlorianWilhelm for the nudge!) * Support of filter properties on page retrieve by @smarttommyau in https://github.com/ramnes/notion-sdk-py/pull/221 * Allow passing starting cursor in paginated helper by @smarttommyau in https://github.com/ramnes/notion-sdk-py/pull/222 ## New Contributors * @cbrenton made their first contribution in https://github.com/ramnes/notion-sdk-py/pull/211 * @smarttommyau made their fi | Low | 12/26/2023 |
| 2.1.0 | ## What's Changed * 100% Coverage 🥳 by @mutt0-ds in https://github.com/ramnes/notion-sdk-py/pull/168 * Fix docs reference for retrieve database endpoint by @estheruary in https://github.com/ramnes/notion-sdk-py/pull/170 * Add filter_properties in databases query by @sgskt in https://github.com/ramnes/notion-sdk-py/pull/181 * fix page share guide according to notion's new doc by @Yunlong-He in https://github.com/ramnes/notion-sdk-py/pull/188 * Upgrade GitHub Actions by @cclauss in https://g | Low | 11/5/2023 |
| 2.0.0 | This major version update mostly adds [new helpers](https://ramnes.github.io/notion-sdk-py/reference/helpers/), support for the [comments API](https://ramnes.github.io/notion-sdk-py/reference/api_endpoints/#notion_client.api_endpoints.CommentsEndpoint), more tests, and Python 3.11. ⚠️ Beware, `Notion-Version` has been upgraded to `2022-06-28` and it brings [breaking changes](https://developers.notion.com/changelog/releasing-notion-version-2022-06-28). Thanks to our new contributors, @ssred | Low | 12/10/2022 |
| 1.0.0 | Let's get out of beta and release 1.0.0! ⚠️ Beware, `Notion-Version` has been upgraded to `2022-02-22` and it brings [breaking changes](https://developers.notion.com/changelog/releasing-notion-version-2022-02-22). Thanks to our new contributor for this release, @sudosubin! **Full Changelog**: https://github.com/ramnes/notion-sdk-py/compare/0.9.0...1.0.0 | Low | 4/18/2022 |
| 0.9.0 | Adds support for the [recent Notion API changes](https://developers.notion.com/changelog) and timeout errors. It also doesn't send null values anymore (see issue #94). Thanks to this release contributors, @mutt0-ds and @nicobako! | Low | 2/5/2022 |
| 0.8.0 | Adds support for the [recent Notion API changes](https://developers.notion.com/changelog). | Low | 12/4/2021 |
| 0.7.1 | Release 0.7.1 | Low | 12/2/2021 |
| 0.7.0 | Adds support for the [recent Notion API changes](https://developers.notion.com/changelog). Beware, `Notion-Version` has been upgraded to `2021-08-16` and it brings [breaking changes](https://developers.notion.com/changelog/notion-version-2021-08-16). | Low | 10/5/2021 |
| 0.6.0 | Adds support for the [recent Notion API changes](https://developers.notion.com/changelog). Upgrading should be seamless from 0.4.0 onwards. | Low | 8/14/2021 |
| 0.5.0 | Mostly adds support for the recent Notion API changes, and per-function authentication. Upgrading from 0.4.0 should be seamless. Thanks to contributors of this release: @aahnik, @nlecoy, @mixeden and @Thompsonmina! | Low | 7/29/2021 |
| 0.4.0 | We now have error handling and complete type hinting, thanks to @Blue-Hope and @aahnik. Kudos to you two! > :warning: **Breaking change** — The client methods now return the response content directly, so you don't need to call `.json()` on results anymore. | Low | 5/28/2021 |
| 0.3.1 | All endpoints are now implemented! It still needs polishing but it's mostly functional. | Low | 5/28/2021 |
