klibnotion
A Notion API client library for Kotlin and Java.
This library is written in Kotlin Multiplatform and can be used from the JVM (Kotlin and Java), Android, and MacOS native.
Several flavors of the client are available to match your needs:
Coroutines (
suspend) based: the default client for Kotlin projectsBlocking: useful for Java projects, or if you have your own async mechanism
Futurebased (JVM only): useful for Java projects
Usage
1/ Add the dependencies to your project
Gradle based projects
The artifact is hosted on the Maven Central repository.
2/ Use the client
The easiest way to see how to use it is to look at the samples:
Coroutines (Kotlin)
Blocking (Java)
Future (Java)
You can also explore the reference doc.
Get your API key
You will find your Internal Integration Token by following the instructions here.
Instantiate a NotionClient
To get other flavors of the client (Java):
Blocking:
BlockingNotionClient blockingClient = BlockingNotionClientUtils.asBlockingNotionClient(notionClient);Future:
FutureNotionClient futureClient = FutureNotionClientUtils.asFutureNotionClient(notionClient);
Use the NotionClient
The client gives access to several API areas:
Each area exposes related APIs, for instance: notionClient.pages.getPage.
Pagination
The APIs that are paginated all follow the same principle:
take a
Paginationobject as a parameter, which defines the page to retrievereturn a
ResultPage<T>with the result list but also a reference to the nextPaginationobjects (handy when retrieving several pages).
Content DSL
A small DSL is available on the page creation API, here's an example usage:
heading1("First section")
paragraph("Hello, World!")
heading1("Second section")
paragraph("This paragraph is bold", annotations = Annotations.BOLD) {
paragraph("Sub paragraph 1")
paragraph("Sub paragraph 2") {
paragraph("Sub sub paragraph") {
}
}
}
heading2("But then again")
heading3("Actually")
paragraph("That's the case")
heading3("But really")
paragraph(RichTextList().text("This ")
.text("word", Annotations(color = Color.RED))
.text(" is red"))
bullet("There's this,")
bullet("there's that,")
bullet("then there's...") {
paragraph("Will this work?")
}
bullet("indentation?") {
bullet("indentation? 2") {
bullet("indentation? 3")
}
}
number("First")
number("Second") {
number("Second second")
}
number("Third")
toDo("This one is checked", true)
toDo("This one is not checked", false)
toggle("This is a toggle!") {
paragraph("This first paragraph is inside the toggle")
paragraph("This second paragraph is inside the toggle")
heading3("This too!")
}
|
|---|
OAuth support
Build your
NotionClientwith anullAuthentication.Use
oAuth.getUserPromptUrito get a URI that will prompt users to agree to add your integration to their workspaceAfter agreeing and upon success, they will be redirected to a specific URI containing a code. Use
oAuth.extractCodeAndStateFromRedirectUrito extract the code from this URI.Exchange the code for an access token using
oAuth.getAccessTokenThe
NotionClientis updated with the token so you can now make authenticated calls. Securely save the token so you can pass it to theauthenticationnext time you build yourNotionClient.
See the sample for a working example.
Logging
To log HTTP requests/response, pass a HttpConfiguration to NotionClient.newInstance().
Several levels are available: NONE, INFO, HEADERS, BODY and ALL
Proxy
A proxy can be configured by passing a HttpConfiguration to NotionClient.newInstance().
Status
This library uses the
2026-03-11version of the Notion API.The Notion API is still evolving and there may be some changes that have not been implemented by this library yet.
Development on this library is not very active, however, pull requests are very welcome, and new versions will be published as needed.
If you want to contribute, it is recommended you first try an issue with the "good first issue" label.
Author and License
Note: this project is not officially related to or endorsed by Notion.