Skip to main content

Karakeep Python API Client

PyPI version

A community-developed Python client for the Karakeep API.

Disclaimer: This is an unofficial, community-driven project. The developers of Karakeep were not consulted during its creation. Use at your own discretion.

Table of Contents

Overview

This library provides a Python interface (both a class and a command-line tool) to interact with a Karakeep instance's API. The author also developed freshrss_to_karakeep, a Python script that periodically sends FreshRSS "favourite" articles to Karakeep (a bookmarking and read-it-later app, see Karakeep on GitHub).

The development process involved:

  1. Starting with the official Karakeep OpenAPI specification: karakeep-openapi-spec.json.
  2. Generating Pydantic data models from the specification using datamodel-code-generator.
  3. Using aider.chat, an AI pair programming tool, to write the KarakeepAPI client class, the Click-based CLI, and the initial Pytest suite.

Current Status & Caveats

  • Experimental Methods: The included Pytest suite currently only covers a subset of the available API methods (primarily 'get all' endpoints and client initialization). Methods not explicitly tested should be considered experimental.
  • Ongoing Development: The author intends to improve and validate methods as they are needed for personal use cases. Contributions and bug reports are welcome!
  • Updating process: I have local scripts that downloads the latest OpenAPI specs from karakeep's repo. I then visually inspect the diff, stage a few changes into git, then run aider --read karakeep_python_api/openapi_reference.json karakeep_python_api/karakeep_api.py karakeep_python_api/datatypes.py --message "As you can see from the git diff output, there was a small update to the openapi reference json file. Please update the python code to match this new update. Here is the git output: $(git --no-pager diff --staged) ".

API Method Coverage

The following table lists the public methods available in the KarakeepAPI class.

  • The "Pytest" column indicates whether the Python library method is covered by the automated test suite (tests/test_karakeep_api.py).
  • The "CLI" column indicates whether the corresponding CLI command for that method is tested within the Pytest suite (typically via subprocess). Methods or CLI commands marked with ❌ should be used with caution as their behavior has not been automatically verified within the test suite.
Method Name Pytest CLI Remarks
get_all_bookmarks ✅ ✅ Tested with pagination.
create_a_new_bookmark ✅ ❌ Pytest for type="link" via fixture and type="asset" via PDF test. CLI not directly tested.
search_bookmarks ✅ ✅ Seems to be nondeterministic and fails if using more than 3 words
get_a_single_bookmark ✅ ❌
delete_a_bookmark ✅ ❌
update_a_bookmark ✅ ✅ Tested for title updates.
get_bookmark_readable_content ✅ ❌ Chunk merging tested offline; live test reads a text bookmark.
summarize_a_bookmark ❌ ❌
attach_tags_to_a_bookmark ✅ ❌
detach_tags_from_a_bookmark ✅ ❌
get_highlights_of_a_bookmark ❌ ❌ Works from the CLI; not yet added to Pytest.
attach_asset ❌ ❌
replace_asset ❌ ❌
detach_asset ❌ ❌
get_all_lists ✅ ✅
create_a_new_list ✅ ❌
get_a_single_list ✅ ❌
delete_a_list ✅ ❌
update_a_list ❌ ❌
get_bookmarks_in_the_list ❌ ❌
add_a_bookmark_to_a_list ❌ ❌
remove_a_bookmark_from_a_list ❌ ❌
get_all_tags ✅ ✅
create_a_new_tag ❌ ❌
get_a_single_tag ✅ ❌
delete_a_tag ✅ ❌
update_a_tag ✅ ❌ No output validation due to server bug.
get_bookmarks_with_the_tag ❌ ❌
get_all_highlights ✅ ✅ Tested with pagination.
create_a_new_highlight ❌ ❌
get_a_single_highlight ❌ ❌
delete_a_highlight ❌ ❌ Works from the CLI; not yet added to Pytest.
update_a_highlight ❌ ❌
upload_a_new_asset ✅ ❌ Tested in PDF asset lifecycle test.
get_a_single_asset ✅ ❌ Tested in PDF asset lifecycle test.
get_asset_signed_url ✅ ❌ Tested in PDF asset lifecycle test (downloads without an API key).
get_current_user_info ✅ ❌ Pytest: Tested indirectly during client init. CLI not directly tested.
get_current_user_stats ✅ ✅
update_user ❌ ❌
get_all_backups ✅ ✅ Tested in backup lifecycle test.
trigger_a_new_backup ✅ ❌ Tested in backup lifecycle test.
get_a_single_backup ✅ ❌ Tested in backup lifecycle test.
delete_a_backup ✅ ❌ Tested in backup lifecycle test.
download_a_backup ✅ ❌ Tested in backup lifecycle test.
admin_trigger_recrawl ❌ ❌ Request body construction tested offline only.
admin_trigger_reindex ❌ ❌ Request body construction tested offline only.
admin_trigger_inference ❌ ❌ Request body construction tested offline only.

Installation

It is recommended to use uv for faster installation:

uv pip install karakeep-python-api

Alternatively, use standard pip:

pip install karakeep-python-api

Usage

This package can be used as a Python library or as a command-line interface (CLI).

Environment Variables

The client can be configured using the following environment variables:

  • KARAKEEP_PYTHON_API_ENDPOINT: Required. The full URL of your Karakeep API, including the /api/v1/ path (e.g., https://karakeep.domain.com/api/v1/ or https://try.karakeep.app/api/v1/).
  • KARAKEEP_PYTHON_API_KEY: Required. Your Karakeep API key (Bearer token).
  • KARAKEEP_PYTHON_API_VERIFY_SSL: Set to false to disable SSL certificate verification (default: true).
  • KARAKEEP_PYTHON_API_VERBOSE: Set to true to enable verbose debug logging for the client and CLI (default: false).
  • KARAKEEP_PYTHON_API_DISABLE_RESPONSE_VALIDATION: Set to true to disable Pydantic validation of API responses. The client will return raw dictionary/list data instead of Pydantic models (default: false).
  • KARAKEEP_PYTHON_API_ENSURE_ASCII: Set to true to escape non-ASCII characters in the JSON output (default: false, which means Unicode characters are kept).

Command Line Interface (CLI)

The CLI dynamically generates commands based on the API methods. You need to provide your API key and endpoint either via environment variables (recommended) or command-line options.

Basic Structure:

python -m karakeep_python_api [GLOBAL_OPTIONS] <COMMAND> [COMMAND_OPTIONS]

Getting Help:

# General help and list of commands
python -m karakeep_python_api --help

# Help for a specific command
python -m karakeep_python_api get-all-bookmarks --help

Examples:

# List all tags (requires env vars set)
python -m karakeep_python_api get-all-tags

# Get the first page of bookmarks with a limit, overriding env vars if needed
# Note: The /api/v1/ path will be automatically appended if not present
python -m karakeep_python_api --base-url https://karakeep.domain.com/api/v1/ --api-key YOUR_API_KEY get-all-bookmarks --limit 10

# Get all lists and pipe the JSON output to jq to extract the first list
python -m karakeep_python_api get-all-lists | jq '.[0]'

# Create a new bookmark from a link (body provided as JSON string)
python -m karakeep_python_api create-a-new-bookmark --data '{"type": "link", "url": "https://example.com"}'

# Get all tags and ensure ASCII output (e.g., for compatibility with systems that don't handle Unicode well)
python -m karakeep_python_api --ascii get-all-tags

# Dump the raw OpenAPI spec used by the client
python -m karakeep_python_api --dump-openapi-specification

Python Library

Import the KarakeepAPI class and instantiate it.

import os
from karakeep_python_api import KarakeepAPI, APIError, AuthenticationError, datatypes

# Ensure required environment variables are set
# Example: os.environ["KARAKEEP_PYTHON_API_ENDPOINT"] = "https://karakeep.domain.com/api/v1/"
# Example: os.environ["KARAKEEP_PYTHON_API_KEY"] = "your_secret_api_key"

try:
    # Initialize the client (reads from env vars by default)
    client = KarakeepAPI(
        # Optionally override env vars:
        # api_endpoint="https://karakeep.domain.com/api/v1/",
        # api_key="another_key",
        # verbose=True,
        # disable_response_validation=False
    )

    # Example: Get all lists
    all_lists = client.get_all_lists()
    if all_lists:
        print(f"Retrieved {len(all_lists)} lists.")
        # Access list properties (uses Pydantic models by default)
        print(f"First list name: {all_lists[0].name}")
        print(f"First list ID: {all_lists[0].id}")
    else:
        print("No lists found.")

    # Example: Get first page of bookmarks
    bookmarks_page = client.get_all_bookmarks(limit=5)
    print(f"\nRetrieved {len(bookmarks_page.bookmarks)} bookmarks.")
    if bookmarks_page.bookmarks:
        print(f"First bookmark title: {bookmarks_page.bookmarks[0].title}")
    if bookmarks_page.nextCursor:
        print(f"Next page cursor: {bookmarks_page.nextCursor}")


except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except APIError as e:
    print(f"An API error occurred: {e}")
except ValueError as e:
    # Handles missing API key/endpoint during initialization
    print(f"Configuration error: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

Community Scripts

Community Scripts are a bunch of scripts made to solve specific issues. They are made by the community so don't hesitate to submit yours or open an issue if you have a bug. They also serve as example of how to use the API.

They can be found in the ./community_scripts folder. Don't hesitate to submit yours, the contribution guidelines are in the community_scripts directory README.md file.

Community Script Description
Karakeep-Time-Tagger Automatically adds time-to-read tags (0-5m, 5-10m, etc.) to bookmarks based on content length analysis. Includes systemd service and timer files for automated periodic execution.
Karakeep-List-To-Tag Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list.
Omnivore2Karakeep-Highlights Imports highlights from Omnivore export data to Karakeep, with intelligent position detection and bookmark matching. Supports dry-run mode for testing.
Omnivore2Karakeep-Archived (Should not be needed anymore) Fixes the archived status of bookmarks imported from Omnivore by reading export data and updating Karakeep accordingly.
pocket2karakeep-archived by @youenchene (Should not be needed anymore) Fixes the archived status of bookmarks imported from Pocket by reading export data and updating Karakeep accordingly.
Karakeep-Archive-Before-Date by @youenchene Allow you to archive all not archived post before a given date
Freshrss-To-Karakeep Syncs some links from Freshrss to Karakeep
Karanki (WIP) Bidirectional sync between anki notes and highlights
Karakeep-remove-ai-tags by @youenchene Remove all tags attached by AI and not human attached

Development

  1. Clone the repository.

  2. Create a virtual environment and activate it.

  3. Install dependencies, including development tools (using uv recommended):

    uv pip install -e ".[dev]"
    
  4. Set the required environment variables (KARAKEEP_PYTHON_API_ENDPOINT, KARAKEEP_PYTHON_API_KEY) for running tests against a live instance.

  5. Run tests:

    pytest
    

This README was generated with assistance from aider.chat, and later kept up to date with Claude Code.

Metadata

Release files for karakeep-python-api 1.9.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for karakeep-python-api 1.9.1
File Size Uploaded Provenance Actions
karakeep_python_api-1.9.1.tar.gz 85.4 kB Without provenance Details for karakeep_python_api-1.9.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for karakeep-python-api 1.9.1
File Interpreter ABI Platform Actions
karakeep_python_api-1.9.1-py3-none-any.whl Python 3 none any Details for karakeep_python_api-1.9.1-py3-none-any.whl

Total release size: 154.2 kB

Release files / karakeep_python_api-1.9.1.tar.gz

Download URL karakeep_python_api-1.9.1.tar.gz
Size 85.4 kB
Tags Source
SHA-256 checksum
How to use checksums
64a658d14a67457d25b11715c207cbda8a4a21f7322a7469f16bdda6ce981e3a
BLAKE2b-256 checksum
How to use checksums
bf1670a14759f3c7713e482c227d7b237f4d99dea04c531b920bbfbafbcfd4eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.11

Release files / karakeep_python_api-1.9.1-py3-none-any.whl

Download URL karakeep_python_api-1.9.1-py3-none-any.whl
Size 68.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c6db8b09f53f8b6709b292cc11af66eff703e1947b4b7b7ac2cd691677842dc3
BLAKE2b-256 checksum
How to use checksums
bff864ca0e7557da947c0b097332ad80a4f8aa33270d2d5a8c770f95d9311667
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.11

Security for karakeep-python-api 1.9.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page