karakeep Documentation

A self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy karakeep on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name karakeep -p 3000:3000 --restart always ghcr.io/karakeep-app/karakeep-chrome:release
Configured Services & Ports
⚙️ web
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
🔌 Ports: 3000:3000
⚙️ chrome
image: ghcr.io/karakeep-app/karakeep-chrome:release
⚙️ meilisearch
image: getmeili/meilisearch:v1.41.0
docker-compose.yml
yaml (docker-compose.yml)
services:
  web:
    image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
    restart: unless-stopped
    volumes:
      # By default, the data is stored in a docker volume called "data".
      # If you want to mount a custom directory, change the volume mapping to:
      # - /path/to/your/directory:/data
      - data:/data
    ports:
      - 3000:3000
    env_file:
      - .env
    environment:
      MEILI_ADDR: http://meilisearch:7700
      BROWSER_WEB_URL: http://chrome:9222
      # OPENAI_API_KEY: ...

      # You almost never want to change the value of the DATA_DIR variable.
      # If you want to mount a custom directory, change the volume mapping above instead.
      DATA_DIR: /data # DON'T CHANGE THIS
  chrome:
    image: ghcr.io/karakeep-app/karakeep-chrome:release
    restart: unless-stopped
    init: true
    command:
      - --disable-gpu
      - --disable-dev-shm-usage
      - --hide-scrollbars
      - --disable-blink-features=AutomationControlled
      - --window-size=1440,900
  meilisearch:
    image: getmeili/meilisearch:v1.41.0
    restart: unless-stopped
    env_file:
      - .env
    environment:
      MEILI_NO_ANALYTICS: "true"
    volumes:
      - meilisearch:/meili_data

volumes:
  meilisearch:
  data:

Technical Documentation: karakeep-app/karakeep

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (README.md)

Karakeep (previously Hoarder) is a self-hostable bookmark-everything app with a touch of AI for the data hoarders out there.

Features

  • Bookmark links, take simple notes and store images and pdfs.
  • Automatic fetching for link titles, descriptions and images.
  • Sort your bookmarks into lists.
  • Collaborate with others on the same list.
  • Full text & semantic search of all the content stored.
  • LLM-based automatic tagging and summarization. With supports for local models using ollama!
  • LLM Agents (e.g. OpenClaw, Hermes) friendly with powerful CLI, and official skills.
  • Rule-based engine for customized management.
  • OCR for extracting text from images.
  • Chrome plugin, Firefox addon, and Safari extension for quick bookmarking.
  • An iOS app, and an Android app.
  • Mobile offline reading.
  • Auto hoarding from RSS feeds.
  • REST API and multiple clients.
  • Multi-language support.
  • Mark and store highlights from your hoarded content.
  • Full page archival (using monolith) to protect against link rot.
  • Auto video archiving using yt-dlp.
  • Bulk actions support.
  • SSO support.
  • Dark mode support.
  • Self-hosting first.
  • Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • Automatic sync with browser bookmarks via floccus.

Documentation

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).

Stack

  • NextJS for the web app. Using app router.
  • Drizzle for the database and its migrations.
  • Better Auth for authentication.
  • tRPC for client->server communication.
  • Puppeteer for crawling the bookmarks.
  • OpenAI because AI is so hot right now.
  • Meilisearch for the full content search.

Why did I build it?

I browse reddit, twitter and hackernews a lot from my phone. I frequently find interesting stuff (articles, tools, etc) that I'd like to bookmark and read later when I'm in front of a laptop. Typical read-it-later apps usecase. Initially, I was using Pocket for that. Then I got into self-hosting and I wanted to self-host this usecase. I used memos for those quick notes and I loved it but it was lacking some features that I found important for that usecase such as link previews and automatic tagging (more on that in the next section).

I'm a systems engineer in my day job (and have been for the past 7 years). I didn't want to get too detached from the web development world. I decided to build this app as a way to keep my hand dirty with web development, and at the same time, build something that I care about and use every day.

Alternatives

  • memos: I love memos. I have it running on my home server and it's one of my most used self-hosted apps. It doesn't, however, archive or preview the links shared in it. It's just that I dump a lot of links there and I'd have loved if I'd be able to figure which link is that by just looking at my timeline. Also, given the variety of things I dump there, I'd have loved if it does some sort of automatic tagging for what I save there. This is exactly the usecase that I'm trying to tackle with Karakeep.
  • mymind: Mymind is the closest alternative to this project and from where I drew a lot of inspirations. It's a commercial product though.
  • raindrop: A polished open source bookmark manager that supports links, images and files. It's not self-hostable though.
  • Bookmark managers (mostly focused on bookmarking links):
    • Pocket (Dead): Pocket is what hooked me into the whole idea of read-it-later apps. I used it a lot. However, I recently got into home-labbing and became obsessed with the idea of running my services in my home server. Karakeep is meant to be a self-hosting first app. Mozilla recently announced that it's shutting down pocket.
    • Linkwarden: An open-source self-hostable bookmark manager that I ran for a bit in my homelab. It's focused mostly on links and supports collaborative collections.
    • Wallabag: Wallabag is a well-established open source read-it-later app written in php.
    • Shiori: Shiori is meant to be an open source pocket clone written in Go.

Translations

Translations live in apps/web/lib/i18n/locales, one translation.json per language, with English (en) as the source. To fix or improve a translation, open a pull request that edits the relevant file.

Karakeep Cloud ☁️

If you're not comfortable with self-hosting, you can use our managed Karakeep cloud at cloud.karakeep.app. Cloud subscriptions support the development of Karakeep.

Support

If you're enjoying using Karakeep, drop a ⭐️ on the repo!

Community Channels

License

Karakeep is licensed under AGPL-3.0 and owned by Localhost Labs Ltd.

Star History


README (`docs/README.md`)

Website

This website is built using Docusaurus, a modern static website generator.

Installation

text
$ yarn

Local Development

text
$ yarn start

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

Build

text
$ yarn build

This command generates static content into the build directory and can be served using any static contents hosting service.

Deployment

Using SSH:

text
$ USE_SSH=true yarn deploy

Not using SSH:

text
$ GIT_USER=<Your GitHub username> yarn deploy

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.


Docs 01 Getting Started 01 Intro (`docs/docs/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • Automatic fetching for link titles, descriptions and images.
  • Sort your bookmarks into lists.
  • Collaborate with others on the same list.
  • Full text & semantic search of all the content stored.
  • LLM-based automatic tagging and summarization. With supports for local models using ollama!
  • LLM Agents (e.g. OpenClaw, Hermes) friendly with powerful CLI, and official skills.
  • Rule-based engine for customized management.
  • OCR for extracting text from images.
  • Chrome plugin, Firefox addon, and Safari extension for quick bookmarking.
  • An iOS app, and an Android app.
  • Mobile offline reading.
  • Auto hoarding from RSS feeds.
  • REST API and multiple clients.
  • Multi-language support.
  • Mark and store highlights from your hoarded content.
  • Full page archival (using monolith) to protect against link rot.
  • Auto video archiving using yt-dlp.
  • Bulk actions support.
  • SSO support.
  • Dark mode support.
  • Self-hosting first.
  • Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • Automatic sync with browser bookmarks via floccus.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.28.0 01 Intro (`docs/versioned_docs/version-v0.28.0/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • 🔗 Bookmark links, take simple notes and store images and pdfs.
  • ⬇️ Automatic fetching for link titles, descriptions and images.
  • 📋 Sort your bookmarks into lists.
  • 🔎 Full text search of all the content stored.
  • ✨ AI-based (aka chatgpt) automatic tagging and summarization. With supports for local models using ollama!
  • 🤖 Rule-based engine for customized management.
  • 🎆 OCR for extracting text from images.
  • 🔖 Chrome plugin and Firefox addon for quick bookmarking.
  • 📱 An iOS app, and an Android app.
  • 📰 Auto hoarding from RSS feeds.
  • 🔌 REST API and multiple clients.
  • 🌐 Multi-language support.
  • 🖍️ Mark and store highlights from your hoarded content.
  • 🗄️ Full page archival (using monolith) to protect against link rot.
  • ▶️ Auto video archiving using yt-dlp.
  • ☑️ Bulk actions support.
  • 🔐 SSO support.
  • 🌙 Dark mode support.
  • 💾 Self-hosting first.
  • ⬇️ Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • 🔄 Automatic sync with browser bookmarks via floccus.
  • [Planned] Offline reading on mobile, semantic search across bookmarks, ...

⚠️ This app is under heavy development.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.29.0 01 Intro (`docs/versioned_docs/version-v0.29.0/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • 🔗 Bookmark links, take simple notes and store images and pdfs.
  • ⬇️ Automatic fetching for link titles, descriptions and images.
  • 📋 Sort your bookmarks into lists.
  • 🔎 Full text search of all the content stored.
  • ✨ AI-based (aka chatgpt) automatic tagging and summarization. With supports for local models using ollama!
  • 🤖 Rule-based engine for customized management.
  • 🎆 OCR for extracting text from images.
  • 🔖 Chrome plugin and Firefox addon for quick bookmarking.
  • 📱 An iOS app, and an Android app.
  • 📰 Auto hoarding from RSS feeds.
  • 🔌 REST API and multiple clients.
  • 🌐 Multi-language support.
  • 🖍️ Mark and store highlights from your hoarded content.
  • 🗄️ Full page archival (using monolith) to protect against link rot.
  • ▶️ Auto video archiving using yt-dlp.
  • ☑️ Bulk actions support.
  • 🔐 SSO support.
  • 🌙 Dark mode support.
  • 💾 Self-hosting first.
  • ⬇️ Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • 🔄 Automatic sync with browser bookmarks via floccus.
  • [Planned] Offline reading on mobile, semantic search across bookmarks, ...

⚠️ This app is under heavy development.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.30.0 01 Getting Started 01 Intro (`docs/versioned_docs/version-v0.30.0/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • 🔗 Bookmark links, take simple notes and store images and pdfs.
  • ⬇️ Automatic fetching for link titles, descriptions and images.
  • 📋 Sort your bookmarks into lists.
  • 👥 Collaborate with others on the same list.
  • 🔎 Full text search of all the content stored.
  • ✨ AI-based (aka chatgpt) automatic tagging and summarization. With supports for local models using ollama!
  • 🤖 Rule-based engine for customized management.
  • 🎆 OCR for extracting text from images.
  • 🔖 Chrome plugin and Firefox addon for quick bookmarking.
  • 📱 An iOS app, and an Android app.
  • 📰 Auto hoarding from RSS feeds.
  • 🔌 REST API and multiple clients.
  • 🌐 Multi-language support.
  • 🖍️ Mark and store highlights from your hoarded content.
  • 🗄️ Full page archival (using monolith) to protect against link rot.
  • ▶️ Auto video archiving using yt-dlp.
  • ☑️ Bulk actions support.
  • 🔐 SSO support.
  • 🌙 Dark mode support.
  • 💾 Self-hosting first.
  • ⬇️ Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • 🔄 Automatic sync with browser bookmarks via floccus.
  • [Planned] Offline reading on mobile, semantic search across bookmarks, ...

⚠️ This app is under heavy development.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.31.0 01 Getting Started 01 Intro (`docs/versioned_docs/version-v0.31.0/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • 🔗 Bookmark links, take simple notes and store images and pdfs.
  • ⬇️ Automatic fetching for link titles, descriptions and images.
  • 📋 Sort your bookmarks into lists.
  • 👥 Collaborate with others on the same list.
  • 🔎 Full text search of all the content stored.
  • ✨ AI-based (aka chatgpt) automatic tagging and summarization. With supports for local models using ollama!
  • 🤖 Rule-based engine for customized management.
  • 🎆 OCR for extracting text from images.
  • 🔖 Chrome plugin and Firefox addon for quick bookmarking.
  • 📱 An iOS app, and an Android app.
  • 📰 Auto hoarding from RSS feeds.
  • 🔌 REST API and multiple clients.
  • 🌐 Multi-language support.
  • 🖍️ Mark and store highlights from your hoarded content.
  • 🗄️ Full page archival (using monolith) to protect against link rot.
  • ▶️ Auto video archiving using yt-dlp.
  • ☑️ Bulk actions support.
  • 🔐 SSO support.
  • 🌙 Dark mode support.
  • 💾 Self-hosting first.
  • ⬇️ Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • 🔄 Automatic sync with browser bookmarks via floccus.
  • [Planned] Offline reading on mobile, semantic search across bookmarks, ...

⚠️ This app is under heavy development.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.32.0 01 Getting Started 01 Intro (`docs/versioned_docs/version-v0.32.0/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • 🔗 Bookmark links, take simple notes and store images and pdfs.
  • ⬇️ Automatic fetching for link titles, descriptions and images.
  • 📋 Sort your bookmarks into lists.
  • 👥 Collaborate with others on the same list.
  • 🔎 Full text search of all the content stored.
  • ✨ LLM-based automatic tagging and summarization. With supports for local models using ollama!
  • 🤖 LLM Agents (e.g. OpenClaw, Hermes) friendly with powerful CLI, and official skills.
  • ⚙️ Rule-based engine for customized management.
  • 🎆 OCR for extracting text from images.
  • 🔖 Chrome plugin, Firefox addon, and Safari extension for quick bookmarking.
  • 📱 An iOS app, and an Android app.
  • 📰 Auto hoarding from RSS feeds.
  • 🔌 REST API and multiple clients.
  • 🌐 Multi-language support.
  • 🖍️ Mark and store highlights from your hoarded content.
  • 🗄️ Full page archival (using monolith) to protect against link rot.
  • ▶️ Auto video archiving using yt-dlp.
  • ☑️ Bulk actions support.
  • 🔐 SSO support.
  • 🌙 Dark mode support.
  • 💾 Self-hosting first.
  • ⬇️ Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • 🔄 Automatic sync with browser bookmarks via floccus.
  • [Planned] Offline reading on mobile, semantic search across bookmarks, ...

⚠️ This app is under heavy development.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.33.0 01 Getting Started 01 Intro (`docs/versioned_docs/version-v0.33.0/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • Automatic fetching for link titles, descriptions and images.
  • Sort your bookmarks into lists.
  • Collaborate with others on the same list.
  • Full text & semantic search of all the content stored.
  • LLM-based automatic tagging and summarization. With supports for local models using ollama!
  • LLM Agents (e.g. OpenClaw, Hermes) friendly with powerful CLI, and official skills.
  • Rule-based engine for customized management.
  • OCR for extracting text from images.
  • Chrome plugin, Firefox addon, and Safari extension for quick bookmarking.
  • An iOS app, and an Android app.
  • Mobile offline reading.
  • Auto hoarding from RSS feeds.
  • REST API and multiple clients.
  • Multi-language support.
  • Mark and store highlights from your hoarded content.
  • Full page archival (using monolith) to protect against link rot.
  • Auto video archiving using yt-dlp.
  • Bulk actions support.
  • SSO support.
  • Dark mode support.
  • Self-hosting first.
  • Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • Automatic sync with browser bookmarks via floccus.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Versioned Docs Version V0.34.0 01 Getting Started 01 Intro (`docs/versioned_docs/version-v0.34.0/01-getting-started/01-intro.md`)


slug: /

Introduction

Karakeep (previously Hoarder) is an open source "Bookmark Everything" app that uses AI for automatically tagging the content you throw at it. The app is built with self-hosting as a first class citizen.

Features

  • Automatic fetching for link titles, descriptions and images.
  • Sort your bookmarks into lists.
  • Collaborate with others on the same list.
  • Full text & semantic search of all the content stored.
  • LLM-based automatic tagging and summarization. With supports for local models using ollama!
  • LLM Agents (e.g. OpenClaw, Hermes) friendly with powerful CLI, and official skills.
  • Rule-based engine for customized management.
  • OCR for extracting text from images.
  • Chrome plugin, Firefox addon, and Safari extension for quick bookmarking.
  • An iOS app, and an Android app.
  • Mobile offline reading.
  • Auto hoarding from RSS feeds.
  • REST API and multiple clients.
  • Multi-language support.
  • Mark and store highlights from your hoarded content.
  • Full page archival (using monolith) to protect against link rot.
  • Auto video archiving using yt-dlp.
  • Bulk actions support.
  • SSO support.
  • Dark mode support.
  • Self-hosting first.
  • Bookmark importers from Chrome, Pocket, Linkwarden, Omnivore, Tab Session Manager.
  • Automatic sync with browser bookmarks via floccus.

Demo

You can access the demo at https://try.karakeep.app. Login with the following creds:

text
email: [email protected]
password: demodemo

The demo is seeded with some content, but it's in read-only mode to prevent abuse.

About the name

The name Karakeep is inspired by the Arabic word "كراكيب" (karakeeb), a colloquial term commonly used to refer to miscellaneous clutter, odds and ends, or items that may seem disorganized but often hold personal value or hidden usefulness. It evokes the image of a messy drawer or forgotten box, full of stuff you can't quite throw away—because somehow, it matters (or more likely, because you're a hoarder!).


Docs 01 Getting Started 02 Screenshots (`docs/docs/01-getting-started/02-screenshots.md`)

Screenshots

Homepage

Homepage (Dark Mode)

Tags

Lists

Bookmark Preview

Settings

Sharing


Docs 02 Installation 01 Docker (`docs/docs/02-installation/01-docker.md`)

Docker

Requirements

  • Docker
  • Docker Compose

1. Create a new directory

Create a new directory to host the compose file and env variables.

This is where you’ll place the docker-compose.yml file from the next step and the environment variables.

For example you could make a new directory called "karakeep-app" with the following command:

text
mkdir karakeep-app

2. Download the compose file

Download the docker compose file provided here directly into your new directory.

text
wget https://raw.githubusercontent.com/karakeep-app/karakeep/main/docker/docker-compose.yml

3. Populate the environment variables

To configure the app, create a .env file in the directory and add this minimal env file:

text
KARAKEEP_VERSION=release
NEXTAUTH_SECRET=super_random_string
MEILI_MASTER_KEY=another_random_string
NEXTAUTH_URL=http://localhost:3000

You should change the random strings. You can use openssl rand -base64 36 in a separate terminal window to generate the random strings. You should also change the NEXTAUTH_URL variable to point to your server address.

Using KARAKEEP_VERSION=release will pull the latest stable version. You might want to pin the version instead to control the upgrades (e.g. KARAKEEP_VERSION=0.10.0). Check the latest versions here.

Persistent storage and the wiring between the different services is already taken care of in the docker compose file.

Keep in mind that every time you change the .env file, you'll need to re-run docker compose up.

If you want more config params, check the config documentation here.

4. Setup OpenAI

To enable automatic tagging, you'll need to configure OpenAI. This is optional though but highly recommended.

  • Follow OpenAI's help to get an API key.
  • Add the OpenAI API key to the env file:
text
OPENAI_API_KEY=<key>

Learn more about the costs of using openai here.

If you want to use a different AI provider (e.g. Ollama for local inference), check out the different AI providers guide.

5. Start the service

Start the service by running:

text
docker compose up -d

Then visit http://localhost:3000 and you should be greeted with the Sign In page.

[Optional] 6. Enable optional features

Check the configuration docs for extra features to enable such as full page archival, full page screenshots, inference languages, etc.

[Optional] 7. Setup quick sharing extensions

Go to the quick sharing page to install the mobile apps and the browser extensions. Those will help you hoard things faster!

Updating

Updating Karakeep will depend on what you used for the KARAKEEP_VERSION env variable.

  • If you pinned the app to a specific version, bump the version and re-run docker compose up -d. This should pull the new version for you.
  • If you used KARAKEEP_VERSION=release, you'll need to force docker to pull the latest version by running docker compose up --pull always -d.

If your custom Compose file still uses the old Alpine Chrome image, follow the
Chrome image migration guide.

Note that if you want to upgrade/migrate Meilisearch versions, refer to the troubleshooting page.


Docs 02 Installation 02 Unraid (`docs/docs/02-installation/02-unraid.md`)

Unraid

You can use Docker Compose Manager plugin to deploy Karakeep using the official docker compose file provided here. After creating the stack, you'll need to setup some env variables similar to that from the docker compose installation docs here.

Community Apps

:::info
The community application template is maintained by the community.
:::

Karakeep can be installed on Unraid using the community application plugins. Karakeep is a multi-container service, and because unraid doesn't natively support that, you'll have to install the different pieces as separate applications and wire them manually together.

Here's a high level overview of the services you'll need:

  • Karakeep (Support post): Karakeep's main web app.
  • Browserless (Support post): The chrome headless service used for fetching the content. Karakeep's official docker compose doesn't use browserless, but it's currently the only headless chrome service available on unraid, so you'll have to use it.
  • MeiliSearch (Support post): The search engine used by Karakeep. It's optional but highly recommended. If you don't have it set up, search will be disabled.

Docs 02 Installation 03 Archlinux (`docs/docs/02-installation/03-archlinux.md`)

Arch Linux

Installation

Karakeep on AUR is not maintained by the karakeep official.

  1. Install karakeep

    shell
    paru -S karakeep
  2. (Optional) Install optional dependencies

    shell
    # karakeep-cli: karakeep cli tool
    paru -S karakeep-cli
    
    # ollama: for automatic tagging
    sudo pacman -S ollama
    
    # yt-dlp: for download video
    sudo pacman -S yt-dlp

    You can use Open-AI instead of ollama. If you use ollama, you need to download the ollama model. Please refer to: https://ollama.com/library.

  3. Set up

    Environment variables can be set in /etc/karakeep/karakeep.env according to configuration page. The environment variables that are not specified in /etc/karakeep/karakeep.env need to be added by yourself.

  4. Enable service

    shell
    sudo systemctl enable --now karakeep.target

    Then visit http://localhost:3000 and you should be greated with the sign in page.

Services and Ports

karakeep.target include 3 services: karakeep-web.service, karakeep-works.service, karakeep-browser.service.

  • karakeep-web.service: Provide karakeep webui service, uses 3000 port by default.

  • karakeep-workers.service: Provide karakeep workers service, no port.

  • karakeep-browser.service: Provide browser headless service, uses 9222 port by default.

Now karakeep depends on meilisearch, and karakeep-workers.service wants meilisearch.service, starting karakeep.target will start meilisearch.service at the same time.

How to Migrate from Hoarder to Karakeep

The PKGBUILD has been fully updated to replace all references to hoarder with karakeep. If you want to preserve your existing hoarder data during the upgrade, please follow the steps below:

1. Stop the old services

shell
sudo systemctl stop hoarder-web.service hoarder-worker.service hoarder-browser.service
sudo systemctl disable --now hoarder.target

2. Uninstall Hoarder
After uninstalling, you can manually remove the old hoarder user and group if needed.

shell
paru -R hoarder

3. Rename the old data directory

shell
sudo mv /var/lib/hoarder /var/lib/karakeep

4. Install Karakeep

shell
paru -S karakeep

5. Fix ownership of the data directory

shell
sudo chown -R karakeep:karakeep /var/lib/karakeep

6. Set Karakeep
Edit /etc/karakeep/karakeep.env according to configuration page. The environment variables that are not specified in /etc/karakeep/karakeep.env need to be added by yourself.

Or you can copy old hoarder env file to karakeep:

shell
sudo cp -f /etc/hoarder/hoarder.env /etc/karakeep/karakeep.env

7. Start Karakeep

shell
sudo systemctl enable --now karakeep.target

Docs 02 Installation 04 Kubernetes (`docs/docs/02-installation/04-kubernetes.md`)

Kubernetes

Requirements

  • A kubernetes cluster
  • kubectl
  • kustomize

1. Get the deployment manifests

You can clone the repository and copy the /kubernetes directory into another directory of your choice.

2. Populate the environment variables and secrets

To configure the app, copy the .env_sample to .env and change to your specific needs.

You should also change the NEXTAUTH_URL variable to point to your server address.

Using KARAKEEP_VERSION=release will pull the latest stable version. You might want to pin the version instead to control the upgrades (e.g. KARAKEEP_VERSION=0.10.0). Check the latest versions here.

To see all available configuration options check the documentation.

To configure the neccessary secrets for the application copy the .secrets_sample file to .secrets and change the sample secrets to your generated secrets.

Note: You should change the random strings. You can use openssl rand -base64 36 to generate the random strings.

3. Setup OpenAI

To enable automatic tagging, you'll need to configure OpenAI. This is optional though but highly recommended.

  • Follow OpenAI's help to get an API key.
  • Add the OpenAI API key to the .env file:
text
OPENAI_API_KEY=<key>

Learn more about the costs of using openai here.

If you want to use a different AI provider (e.g. Ollama for local inference), check out the different AI providers guide.

4. Deploy the service

Deploy the service by running:

text
make deploy

5. Access the service

via LoadBalancer IP

By default, these manifests expose the application as a LoadBalancer Service. You can run kubectl get services to identify the IP of the loadbalancer for your service.

Then visit http://<loadbalancer-ip>:3000 and you should be greated with the Sign In page.

Note: Depending on your setup you might want to expose the service via an Ingress, or have a different means to access it.

Via Ingress

If you want to use an ingress, you can customize the sample ingress in the kubernetes folder and change the host to the DNS name of your choice.

After that you have to configure the web service to the type ClusterIP so it is only reachable via the ingress.

If you have already deployed the service you can patch the web service to the type ClusterIP with the following command:

kubectl -n karakeep patch service web -p '{"spec":{"type":"ClusterIP"}}'

Afterwards you can apply the ingress and access the service via your chosen URL.

Setting up HTTPS access to the Service

To access karakeep securely you can configure the ingress to use a preconfigured TLS certificate. This requires that you already have the needed files, namely your .crt and .key file, on hand.

After you have deployed the karakeep manifests you can deploy your certificate for karakeep in the karakeep namespace with this example command. You can name the secret however you want. But be aware that the secret name in the ingress definition has to match the secret name.

$ kubectl --namespace karakeep create secret tls karakeep-web-tls --cert=/path/to/crt --key=/path/to/key

If the secret is successfully created you can now configure the Ingress to use TLS via this changes to the spec:

yaml
spec:
  tls:
  - hosts:
      - karakeep.example.com
    secretName: karakeep-web-tls

Note: Be aware that the hosts have to match between the tls spec and the HTTP spec.

[Optional] 6. Setup quick sharing extensions

Go to the quick sharing page to install the mobile apps and the browser extensions. Those will help you hoard things faster!

Updating

Edit the KARAKEEP_VERSION variable in the kustomization.yaml file and run make clean deploy.

If you have chosen release as the image tag you can also destroy the web pod, since the deployment has an ImagePullPolicy set to always the pod always pulls the image from the registry, this way we can ensure that the newest release image is pulled.


Docs 02 Installation 06 Debuntu (`docs/docs/02-installation/06-debuntu.md`)

Debian 12/Ubuntu 24.04

:::warning
This script is a stripped-down version of those found in the Proxmox Community Scripts repo. It has been adapted to work on baremetal Debian 12 or Ubuntu 24.04 installs only. Any other use is not supported and you use this script at your own risk.
:::

Requirements

  • Debian 12 (Buster) or
  • Ubuntu 24.04 (Noble Numbat)

The script will download and install all dependencies (except for Ollama), install Karakeep, do a basic configuration of Karakeep and Meilisearch (the search app used by Karakeep), and create and enable the systemd service files needed to run Karakeep on startup. Karakeep and Meilisearch are run in the context of their low-privilege user environments for more security.

The script functions as an update script in addition to an installer. See Updating.

1. Download the script from the [Karakeep repository](https://github.com/karakeep-app/karakeep/blob/main/karakeep-linux.sh)

text
wget https://raw.githubusercontent.com/karakeep-app/karakeep/main/karakeep-linux.sh

2. Run the script

This script must be run as root, or as a user with sudo privileges.

text
If this is a fresh install, then run the installer by using the following command:

```shell
bash karakeep-linux.sh install
```

3. Create an account/sign in

text
Then visit `http://localhost:3000` and you should be greated with the Sign In page.

Updating

This script must be run as root, or as a user with sudo privileges.

text
If Karakeep has previously been installed using this script, then run the updater like so:

```shell
 bash karakeep-linux.sh update
```

Services and Ports

karakeep.target includes 4 services: meilisearch.service, karakeep-web.service, karakeep-workers.service, karakeep-browser.service.

  • meilisearch.service: Provides full-text search, Karakeep Workers service connects to it, uses port 7700 by default.

  • karakeep-web.service: Provides the karakeep web service, uses 3000 port by default.

  • karakeep-workers.service: Provides the karakeep workers service, no port.

  • karakeep-browser.service: Provides the headless browser service, uses 9222 port by default.

Configuration, ENV file, database locations

During installation, the script created a configuration file for meilisearch, an ENV file for Karakeep, and located config paths and database paths separate from the installation path of Karakeep, so as to allow for easier updating. Their names/locations are as follows:

  • /etc/meilisearch.toml - a basic configuration for meilisearch, that contains configs for the database location, disabling analytics, and using a master key, which prevents unauthorized connections.

  • /var/lib/meilisearch - Meilisearch DB location.

  • /etc/karakeep/karakeep.env - The Karakeep ENV file. Edit this file to configure Karakeep beyond the default. The web service and the workers service need to be restarted after editing this file:

    shell
    sudo systemctl restart karakeep-workers karakeep-web
  • /var/lib/karakeep - The Karakeep database location. If you delete the contents of this folder you will lose all your data.

Still Running Hoarder?

There is a way to upgrade. Please see Hoarder to Karakeep Migration


Docs 02 Installation 07 Minimal Install (`docs/docs/02-installation/07-minimal-install.md`)

Minimal Installation

:::warning
Unless necessary, prefer the full installation to leverage all the features of Karakeep. You'll be sacrificing a lot of functionality if you go with the minimal installation route.
:::

Karakeep's default installation has a dependency on Meilisearch for the full text search, Chrome for crawling and OpenAI/Ollama for AI tagging. You can however run Karakeep without those dependencies if you're willing to sacrifice those features.

  • If you run without meilisearch, the search functionality will be completely disabled.
  • If you run without chrome, crawling will still work, but you'll lose ability to take screenshots of websites and websites with javascript content won't get crawled correctly.
  • If you don't setup OpenAI/Ollama, AI tagging will be disabled.

Those features are important for leveraging Karakeep's full potential, but if you're running in constrained environments, you can use the following minimal docker compose to skip all those dependencies:

yaml
services:
  web:
    image: ghcr.io/karakeep-app/karakeep:release
    restart: unless-stopped
    volumes:
      - data:/data
    ports:
      - 3000:3000
    environment:
      DATA_DIR: /data
      NEXTAUTH_SECRET: super_random_string
volumes:
  data:

Or just with the following docker command:

base
docker run -d \
  --restart unless-stopped \
  -v data:/data \
  -p 3000:3000 \
  -e DATA_DIR=/data \
  -e NEXTAUTH_SECRET=super_random_string \
  ghcr.io/karakeep-app/karakeep:release

:::warning
You MUST change the super_random_string to a true random string which you can generate with openssl rand -hex 32.
:::

Check the configuration docs for extra features to enable such as full page archival, full page screenshots, inference languages, etc.


Docs 02 Installation 08 Truenas (`docs/docs/02-installation/08-truenas.md`)

TrueNAS

Karakeep is available directly from TrueNAS's app catalog (link).


Docs 02 Installation 09 Cloud Hosting (`docs/docs/02-installation/09-cloud-hosting.md`)

Karakeep Cloud

:::tip
If you want to use Karakeep without running your own servers, the hosted cloud option is the fastest way to start.
:::

Karakeep Cloud is the fully managed version of Karakeep operated by the core team. It handles hosting, updates, monitoring, and backups for you, so you can focus on saving content instead of maintaining infrastructure.

Get started

  1. Visit cloud.karakeep.app and create an account.
  2. Follow the onboarding flow to create your workspace.
  3. Install the browser extension or mobile apps from the quick sharing page and start saving links immediately.

Docs 02 Installation 10 Pikapods (`docs/docs/02-installation/10-pikapods.md`)

PikaPods

:::info
Note: PikaPods shares some of its revenue from hosting Karakeep with the maintainer of this project.
:::

PikaPods offers managed paid hosting for many open source apps, including Karakeep.
Server administration, updates, migrations and backups are all taken care of, which makes it well suited
for less technical users. As of Nov 2024, running Karakeep there will cost you ~$3 per month.

Requirements

  • A PikaPods account. Can be created for free here. You get an initial welcome credit of $5.

1. Choose app

Choose Karakeep from their list of apps or use this direct link. This will either
open a new dialog to add a new Karakeep pod or ask you to log in.

2. Add settings

There are a few settings to configure in the dialog:

  • Basics: Give the pod a name and choose a region that's near you.
  • Env Vars: Here you can disable signups or set an OpenAI API key. All settings are optional.
  • Resources: The resources your Karakeep pod can use. The defaults are fine, unless you have a very large collection.

3. Start pod and add user

After hitting Add pod it will take about a minute for the app to fully start. After this you can visit
the pod's URL and add an initial user under Sign Up. After this you may want to disable further sign-ups
by setting the pod's DISABLE_SIGNUPS Env Var to true.


Docs 03 Configuration 01 Environment Variables (`docs/docs/03-configuration/01-environment-variables.md`)

Configuration

The app is mainly configured by environment variables. All the used environment variables are listed in packages/shared/config.ts. The most important ones are:

Name Required Default Description
PORT No 3000 The port on which the web server will listen. DON'T CHANGE THIS IF YOU'RE USING DOCKER, instead changed the docker bound external port.
WORKERS_PORT No 0 (Random Port) The port on which the worker will export its prometheus metrics on /metrics. By default it's a random unused port. If you want to utilize those metrics, fix the port to a value (and export it in docker if you're using docker).
WORKERS_HOST No 127.0.0.1 Host to listen to for requests to WORKERS_PORT. You will need to set this if running in a container, since localhost will not be reachable from outside
WORKERS_ENABLED_WORKERS No Not set Comma separated list of worker names to enable. If set, only these workers will run. Valid values: crawler,inference,search,adminMaintenance,video,feed,assetPreprocessing,webhook,ruleEngine,backup. All available workers are listed in apps/workers/index.ts.
WORKERS_DISABLED_WORKERS No Not set Comma separated list of worker names to disable. Takes precedence over WORKERS_ENABLED_WORKERS.
LOG_LEVEL No debug The application log level; one of "debug", "info", "warn" (good choice for a production environment), or "error".
DATA_DIR Yes Not set The path for the persistent data directory. This is where the db lives. Assets are stored here by default unless ASSETS_DIR is set.
ASSETS_DIR No Not set The path where crawled assets will be stored. If not set, defaults to ${DATA_DIR}/assets.
NEXTAUTH_URL Yes Not set The address of your server (e.g. https://karakeep.example.com). It's used to build the links in emails and the OAuth callback URL, and an https address makes authentication cookies secure-only. Sign-ins from other addresses are controlled by AUTH_TRUSTED_ORIGINS.
NEXTAUTH_SECRET Yes Not set Random string used to secure authentication cookies and tokens. Generate one with openssl rand -base64 36.
AUTH_TRUSTED_ORIGINS No * Comma-separated list of origins (e.g. https://karakeep.example.com) allowed to sign in and to be redirected to after authentication, on top of NEXTAUTH_URL. * stands for whatever address the request was sent to, so that Karakeep keeps working when it's reached at an address other than NEXTAUTH_URL (e.g. a LAN IP). It doesn't allow other sites. Set it to an empty string to only allow NEXTAUTH_URL.
MEILI_ADDR No Not set The address of meilisearch. If not set, Search will be disabled. E.g. (http://meilisearch:7700)
MEILI_MASTER_KEY Only in Prod and if search is enabled Not set The master key configured for meilisearch. Not needed in development environment. Generate one with openssl rand -base64 36 | tr -dc 'A-Za-z0-9'
MAX_ASSET_SIZE_MB No 50 Sets the maximum allowed asset size (in MB) to be uploaded
DISABLE_NEW_RELEASE_CHECK No false If set to true, latest release check will be disabled in the admin panel.
RATE_LIMITING_ENABLED No false If set to true, API rate limiting will be enabled.
CRAWLER_DOMAIN_RATE_LIMIT_WINDOW_MS No Not set Time window in milliseconds for per-domain crawler rate limiting.
CRAWLER_DOMAIN_RATE_LIMIT_MAX_REQUESTS No Not set Maximum crawler requests allowed per domain inside the configured window.
DB_WAL_MODE No false Enables WAL mode for the sqlite database. This should improve the performance of the database. There's no reason why you shouldn't set this to true unless you're running the db on a network attached drive. This will become the default at some time in the future.
SEARCH_NUM_WORKERS No 50 Number of concurrent workers for search indexing tasks. Increase this if you have a high volume of content being indexed for search.
SEARCH_JOB_TIMEOUT_SEC No 30 How long to wait for a search indexing job to finish before timing out. Increase this if you have large bookmarks with extensive content that takes longer to index.
WEBHOOK_NUM_WORKERS No 1 Number of concurrent workers for webhook delivery. Increase this if you have multiple webhook endpoints or high webhook traffic.
ASSET_PREPROCESSING_NUM_WORKERS No 1 Number of concurrent workers for asset preprocessing tasks (image processing, OCR, etc.). Increase this if you have many images or documents that need processing.
ASSET_PREPROCESSING_JOB_TIMEOUT_SEC No 60 How long to wait for an asset preprocessing job to finish before timing out. Increase this if you have large images or PDFs that take longer to process.
RULE_ENGINE_NUM_WORKERS No 1 Number of concurrent workers for rule engine processing. Increase this if you have complex automation rules that need to be processed quickly.
MAX_RSS_FEEDS_PER_USER No 1000 The maximum number of RSS feeds a user can create.
MAX_WEBHOOKS_PER_USER No 100 The maximum number of webhooks a user can create.

Asset Storage

Karakeep supports two storage backends for assets: local filesystem (default) and S3-compatible object storage. S3 storage is automatically detected when an S3 endpoint is passed.

Name Required Default Description
ASSET_STORE_S3_ENDPOINT No Not set The S3 endpoint URL. Required for S3-compatible services like MinIO. Setting this enables S3 storage.
ASSET_STORE_S3_REGION No Not set The S3 region to use.
ASSET_STORE_S3_BUCKET Yes when using S3 Not set The S3 bucket name where assets will be stored.
ASSET_STORE_S3_ACCESS_KEY_ID Yes when using S3 Not set The S3 access key ID for authentication.
ASSET_STORE_S3_SECRET_ACCESS_KEY Yes when using S3 Not set The S3 secret access key for authentication.
ASSET_STORE_S3_FORCE_PATH_STYLE No false Whether to force path-style URLs for S3 requests. Set to true for MinIO and other S3-compatible services.

:::info
When using S3 storage, make sure the bucket exists and the provided credentials have the necessary permissions to read, write, and delete objects in the bucket.
:::

:::warning
Switching between storage backends after data has been stored will require manual migration of existing assets. Plan your storage backend choice carefully before deploying.
:::

Authentication / Signup

By default, Karakeep uses the database to store users, but it is possible to also use OAuth.
The flags need to be provided to the web container.

:::info
Only OIDC compliant OAuth providers are supported! For information on how to set it up, consult the documentation of your provider.
:::

:::info
When setting up OAuth, the allowed redirect URLs configured at the provider should be set to <KARAKEEP_ADDRESS>/api/auth/callback/custom where <KARAKEEP_ADDRESS> is the address you configured in NEXTAUTH_URL (for example: https://try.karakeep.app/api/auth/callback/custom).
:::

Name Required Default Description
DISABLE_SIGNUPS No false If enabled, no new signups will be allowed and the signup button will be disabled in the UI
DISABLE_PASSWORD_AUTH No false If enabled, only signups and logins using OAuth are allowed and the signup button and login form for local accounts will be disabled in the UI
EMAIL_VERIFICATION_REQUIRED No false Whether email verification is required during user signup. If enabled, users must verify their email address before they can use their account. If you enable this, you must configure SMTP settings.
OAUTH_AUTO_REDIRECT No false If enabled and password authentication is disabled, automatically redirect to the OAuth provider instead of showing the login page. Useful when OAuth is the only authentication method available.
OAUTH_WELLKNOWN_URL No Not set The "wellknown Url" for openid-configuration as provided by the OAuth provider
OAUTH_CLIENT_SECRET No Not set The "Client Secret" as provided by the OAuth provider. Leave it unset for a public client, which authenticates with PKCE only.
OAUTH_CLIENT_ID No Not set The "Client ID" as provided by the OAuth provider
OAUTH_SCOPE No "openid email profile" "Full list of scopes to request (space delimited)"
OAUTH_TOKEN_ENDPOINT_AUTH_METHOD No client_secret_basic How Karakeep authenticates to the provider's token endpoint. Either client_secret_basic or client_secret_post. Set it to client_secret_post if your provider doesn't support client_secret_basic. Ignored when OAUTH_CLIENT_SECRET isn't set.
OAUTH_PROVIDER_NAME No "Custom Provider" The name of your provider. Will be shown on the signup page as "Sign in with <name>"
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING No false Whether existing accounts in karakeep stored in the database should automatically be linked with your OAuth account. Only enable it if you trust the OAuth provider!

For more information on OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING, check the Better Auth account-linking documentation.

Inference Configs (For automatic tagging)

Either OPENAI_API_KEY or OLLAMA_BASE_URL need to be set for automatic tagging to be enabled. Otherwise, automatic tagging will be skipped.

:::warning

  • The quality of the tags you'll get will depend on the quality of the model you choose.
  • You might want to tune the INFERENCE_CONTEXT_LENGTH as the default is quite small. The larger the value, the better the quality of the tags, but the more expensive the inference will be (money-wise on OpenAI and resource-wise on ollama).
    :::
Name Required Default Description
OPENAI_API_KEY No Not set The OpenAI key used for automatic tagging. More on that in here.
OPENAI_BASE_URL No Not set If you just want to use OpenAI you don't need to pass this variable. If, however, you want to use some other openai compatible API (e.g. azure openai service), set this to the url of the API.
OPENAI_PROXY_URL No Not set HTTP proxy server URL for OpenAI API requests (e.g., http://proxy.example.com:8080).
OPENAI_TIMEOUT_SEC No Not set Timeout for OpenAI API requests in seconds. If unset, the OpenAI SDK default of 10 minutes is used. The HTTP headers/body timeouts are set to the same value. Note that the OpenAI SDK retries timed-out requests up to 2 times by default. Increase this alongside INFERENCE_JOB_TIMEOUT_SEC when slow inference providers need more time.
OPENAI_SERVICE_TIER No Not set Set to auto, default, or flex. Flex processing provides lower costs in exchange for slower response times and occasional resource unavailability. See OpenAI Flex Processing and Chat Service Tier for more details.
OPENAI_REASONING_EFFORT No Not set Set to none, minimal, low, medium, high or xhigh. Controls the reasoning effort in reasoning models. See OpenAI: How Reasoning Works.
OLLAMA_BASE_URL No Not set If you want to use ollama for local inference, set the address of ollama API here.
OLLAMA_KEEP_ALIVE No Not set Controls how long the model will stay loaded into memory following the request (examples: "5m" for 5 minutes, "-1m" to keep the model loaded indefinitely, "0" to unload the model instantly after processing is complete).
SEMANTIC_SEARCH_ENABLED No true Enables the hybrid and semantic bookmark search modes. Experimental. EMBEDDING_ENABLE_AUTO_INDEXING must also be enabled.
INFERENCE_TEXT_MODEL No gpt-6-luna The model to use for text inference. You'll need to change this to some other model if you're using ollama.
INFERENCE_IMAGE_MODEL No gpt-4o-mini The model to use for image inference. You'll need to change this to some other model if you're using ollama and that model needs to support vision APIs (e.g. llava).
EMBEDDING_ENABLE_AUTO_INDEXING No enabled if using OpenAI Whether bookmark embedding generation and vector indexing are enabled. This is enabled by default if you're using the default OpenAI settings (i.e. no Ollama, no OpenAI base URL override). Otherwise, you need to manually enable it after configuring the embedding model and its dimensions.
EMBEDDING_OPENAI_API_KEY No OPENAI_API_KEY The API key used for OpenAI-compatible embedding requests. If unset, embedding requests use OPENAI_API_KEY.
EMBEDDING_OPENAI_BASE_URL No OPENAI_BASE_URL The OpenAI-compatible API base URL used for embedding requests. If unset, embedding requests use OPENAI_BASE_URL.
EMBEDDING_TEXT_MODEL No text-embedding-3-small The model to be used for generating embeddings for the text.
EMBEDDING_TEXT_MODEL_DIMENSION_OVERRIDE No Not set Requests this output dimension from embedding models that support configurable dimensions. When set, it must match EMBEDDING_DIMENSIONS, or Karakeep will fail to start.
EMBEDDING_CONTEXT_LENGTH No 8000 The max number of characters that will be passed to the embedding model. If the bookmark content is larger than this size, it will be truncated before embedding generation.
EMBEDDING_DIMENSIONS No 1536 The embedding vector dimensions expected by the vector store. This must match the embedding model or provider configuration.
EMBEDDING_NUM_WORKERS No 1 Number of concurrent workers for embedding generation and vector indexing tasks. Increase this if you have multiple embedding requests and want to process them in parallel.
EMBEDDING_JOB_TIMEOUT_SEC No 60 How long to wait for an embedding generation and vector indexing job to finish before timing out. Increase this if your embedding provider or vector store is slow.
INFERENCE_CONTEXT_LENGTH No 2048 The max number of tokens that we'll pass to the inference model. If your content is larger than this size, it'll be truncated to fit. The larger this value, the more of the content will be used in tag inference, but the more expensive the inference will be (money-wise on openAI and resource-wise on ollama). Check the model you're using for its max supported content size.
INFERENCE_MAX_OUTPUT_TOKENS No 2048 The maximum number of tokens that the inference model is allowed to generate in its response. This controls the length of AI-generated content like tags and summaries. Increase this if you need longer responses, but be aware that higher values will increase costs (for OpenAI) and processing time.
INFERENCE_USE_MAX_COMPLETION_TOKENS No Read description [OpenAI Only] Whether to use the newer max_completion_tokens parameter instead of the deprecated max_tokens parameter. Set to true if using GPT-5 models which require this. If using the default openai configuration (with 5.6 luna) this will be set to true, else defaults to false.
INFERENCE_LANG No english The language in which the tags will be generated.
INFERENCE_NUM_WORKERS No 1 Number of concurrent workers for AI inference tasks (tagging and summarization). Increase this if you have multiple AI inference requests and want to process them in parallel.
INFERENCE_ENABLE_AUTO_TAGGING No true Whether automatic AI tagging is enabled or disabled.
INFERENCE_ENABLE_AUTO_SUMMARIZATION No false Whether automatic AI summarization is enabled or disabled.
INFERENCE_JOB_TIMEOUT_SEC No 30 How long to wait for the inference job to finish before timing out. If you're running ollama without powerful GPUs, you might want to increase the timeout a bit.
INFERENCE_FETCH_TIMEOUT_SEC No 300 [Ollama Only] How long to wait for the ollama server to start responding, and between streamed response chunks. If your ollama server takes longer than the default 5mins to start responding, you might want to increase this timeout.
INFERENCE_SUPPORTS_STRUCTURED_OUTPUT No Not set [DEPRECATED] Whether the inference model supports structured output or not. Use INFERENCE_OUTPUT_SCHEMA instead. Setting this to true translates to INFERENCE_OUTPUT_SCHEMA=structured, and to false translates to INFERENCE_OUTPUT_SCHEMA=plain.
INFERENCE_OUTPUT_SCHEMA No structured Possible values are "structured", "json", "plain". Structured is the preferred option, but if your model doesn't support it, you can use "json" if your model supports JSON mode, otherwise "plain" which should be supported by all the models but the model might not output the data in the correct format.

:::info

  • You can append additional instructions to the prompt used for automatic tagging, in the AI Settings (in the User Settings screen)
  • You can use the placeholders $tags, $aiTags, $userTags in the prompt. These placeholders will be replaced with all tags, ai generated tags or human created tags when automatic tagging is performed (e.g. [karakeep, computer, ai])
    :::

Crawler Configs

Name Required Default Description
CRAWLER_NUM_WORKERS No 1 Number of allowed concurrent crawling jobs. By default, we're only doing one crawling request at a time to avoid consuming a lot of resources.
BROWSER_WEB_URL No Not set The browser's http debugging address. The worker will talk to this endpoint to resolve the debugging console's websocket address. If you already have the websocket address, use BROWSER_WEBSOCKET_URL instead. If neither BROWSER_WEB_URL nor BROWSER_WEBSOCKET_URL are set, the worker will use plain http requests skipping screenshotting and javascript execution.
BROWSER_WEBSOCKET_URL No Not set The websocket address of browser's debugging console. If you want to use browserless, use their websocket address here. If neither BROWSER_WEB_URL nor BROWSER_WEBSOCKET_URL are set, the worker will use plain http requests skipping screenshotting and javascript execution.
BROWSER_CONNECT_ONDEMAND No false If set to false, the crawler will proactively connect to the browser instance and always maintain an active connection. If set to true, the browser will be launched on demand only whenever a crawling is requested. Set to true if you're using a service that provides you with browser instances on demand.
CRAWLER_DOWNLOAD_BANNER_IMAGE No true Whether to cache the banner image used in the cards locally or fetch it each time directly from the website. Caching it consumes more storage space, but is more resilient against link rot and rate limits from websites.
CRAWLER_STORE_SCREENSHOT No true Whether to store a screenshot from the crawled website or not. Screenshots act as a fallback for when we fail to extract an image from a website. You can also view the stored screenshots for any link.
CRAWLER_FULL_PAGE_SCREENSHOT No false Whether to store a screenshot of the full page or not. Disabled by default, as it can lead to much higher disk usage. If disabled, the screenshot will only include the visible part of the page
CRAWLER_SCREENSHOT_TIMEOUT_SEC No 5 How long to wait for the screenshot finish before timing out. If you are capturing full-page screenshots of long webpages, consider increasing this value.
CRAWLER_STORE_PDF No false Whether to store a PDF snapshot of the crawled page. Disabled by default, as it can lead to much higher disk usage. When enabled, a PDF version of each crawled page will be captured and stored as an asset, which can be viewed in the bookmark preview.
CRAWLER_FULL_PAGE_ARCHIVE No false Whether to store a full local copy of the page or not. Disabled by default, as it can lead to much higher disk usage. If disabled, only the readable text of the page is archived.
CRAWLER_FULL_PAGE_ARCHIVE_MAX_SIZE_MB No 0 Maximum size in MB for a stored full-page archive. Archives larger than this are discarded instead of saved, since media-rich pages can produce 1GB+ files that never render. 0 disables the limit.
CRAWLER_JOB_TIMEOUT_SEC No 60 How long to wait for the crawler job to finish before timing out. If you have a slow internet connection or a low powered device, you might want to bump this up a bit
CRAWLER_NAVIGATE_TIMEOUT_SEC No 30 How long to spend navigating to the page (along with its redirects). Increase this if you have a slow internet connection
CRAWLER_CHALLENGE_WAIT_SEC No 15 When a page turns out to be a bot-protection challenge that clears by itself (e.g. Cloudflare's "Just a moment..." page), how long to wait for it to clear before capturing the page. Set to 0 to disable.
CRAWLER_BROWSER_TIMEZONE No Not set IANA timezone (e.g. America/New_York) that the crawler's browser reports to websites. Bot-protection services flag browsers whose timezone doesn't match their IP's location, so if you crawl through a proxy, set this to the proxy's location. When not set, the browser uses its own timezone (usually UTC in containers).
CRAWLER_PREFLIGHT_USER_AGENT No Not set The User-Agent header to send on the crawler's preflight request (the plain HTTP request that determines a link's content type and extracts early preview metadata before the full crawl). If not set, no User-Agent header is sent.
CRAWLER_PARSE_TIMEOUT_SEC No 60 How long to wait for the HTML parsing subprocess (metadata extraction + readability) to finish before timing out.
CRAWLER_PARSER_MEM_LIMIT_MB No 512 Maximum heap size in MB for the HTML parsing subprocess. If the parser OOMs on large pages, increase this value. The subprocess is isolated so an OOM won't crash the main worker.
CRAWLER_VIDEO_DOWNLOAD No false Whether to download videos from the page or not (using yt-dlp)
CRAWLER_VIDEO_DOWNLOAD_MAX_SIZE No 50 The maximum file size for the downloaded video. The quality will be chosen accordingly. Use -1 to disable the limit.
CRAWLER_VIDEO_DOWNLOAD_TIMEOUT_SEC No 600 How long to wait for the video download to finish
CRAWLER_VIDEO_DOWNLOAD_ON_DEMAND No Value of CRAWLER_VIDEO_DOWNLOAD Whether users can explicitly download the video of a single link bookmark (using yt-dlp) through the "Preserve Video" action. Defaults to the value of CRAWLER_VIDEO_DOWNLOAD, but can be set independently (e.g. enable on-demand downloads while keeping automatic downloads off). The size and timeout limits above still apply.
CRAWLER_ENABLE_ADBLOCKER No true Whether to enable an adblocker in the crawler or not. If you're facing troubles downloading the adblocking lists on worker startup, you can disable this.
CRAWLER_ENABLE_AUTOCONSENT No true Whether to automatically opt out of supported consent dialogs during browser-based crawls. When a consent management platform is detected, the crawler waits up to 3 seconds for the opt-out to finish before extracting content and capturing page assets. Set to false to disable this behavior.
CRAWLER_YTDLP_ARGS No [] Include additional yt-dlp arguments to be passed at crawl time separated by %%: https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#general-options
CRAWLER_MONOLITH_TIMEOUT_SEC No 5 How long to let monolith run when archiving the full page before timing out (in seconds). Increase this if bookmarks from slow servers frequently fail to archive. Monolith's own default is 120 seconds.
CRAWLER_MONOLITH_ARGS No [] Include additional monolith arguments to be passed when archiving a full page, separated by %%. For example, --no-fonts%%--no-audio%%--no-video to exclude web fonts, audio, and video from archives. Do not re-specify -t, -b, or -o as these are managed internally. See monolith options.
BROWSER_COOKIE_PATH No Not set Path to a JSON file containing cookies to be loaded into the browser context. The file should be an array of cookie objects, each with name and value (required), and optional fields like domain, path, expires, httpOnly, secure, and sameSite (e.g., [{"name": "session", "value": "xxx", "domain": ".example.com"}]).
HTML_CONTENT_SIZE_INLINE_THRESHOLD_BYTES No 5 * 1024 The thresholds in bytes after which larger assets will be stored in the assetdb (folder/s3) instead of inline in the database.

More info on BROWSER_COOKIE_PATH

BROWSER_COOKIE_PATH specifies the path to a JSON file containing cookies to be loaded into the browser context for crawling.

The JSON file must be an array of cookie objects, each with:

  • name: The cookie name (required).
  • value: The cookie value (required).
  • Optional fields: domain, path, expires, httpOnly, secure, sameSite (values: "Strict", "Lax", or "None").

Example JSON file:

json
[
  {
    "name": "session",
    "value": "xxx",
    "domain": ".example.com",
    "path": "/",
    "expires": 1735689600,
    "httpOnly": true,
    "secure": true,
    "sameSite": "Lax"
  }
]

OCR Configs

Karakeep uses tesseract.js to extract text from images by default. Alternatively, you can use an LLM-based OCR by enabling the OCR_USE_LLM flag. LLM-based OCR uses the configured inference model (OpenAI or Ollama) to extract text from images, which can provide better results for complex images but requires a configured inference provider.

Name Required Default Description
OCR_CACHE_DIR No $TEMP_DIR The dir where tesseract will download its models. By default, those models are not persisted and stored in the OS' temp dir.
OCR_LANGS No eng Comma separated list of the language codes that you want tesseract to support. You can find the language codes here. Set to empty string to disable OCR.
OCR_CONFIDENCE_THRESHOLD No 50 A number between 0 and 100 indicating the minimum acceptable confidence from tessaract. If tessaract's confidence is lower than this value, extracted text won't be stored.
OCR_USE_LLM No false If set to true, uses the configured inference model (OpenAI or Ollama) for OCR instead of Tesseract. This can provide better results for complex images but requires a configured inference provider (OPENAI_API_KEY or OLLAMA_BASE_URL). Falls back to Tesseract if no inference provider is configured.

Webhook Configs

You can use webhooks to trigger actions when bookmarks are created, changed or crawled.

Name Required Default Description
WEBHOOK_TIMEOUT_SEC No 5 The timeout for the webhook request in seconds.
WEBHOOK_RETRY_TIMES No 3 The number of times to retry the webhook request.

:::info

  • The WEBHOOK_TOKEN is used for authentication. It will appear in the Authorization header as Bearer token.

    text
    Authorization: Bearer <WEBHOOK_TOKEN>
  • The webhook will be triggered with the job id (used for idempotence), bookmark id, bookmark type, the user id, the url and the operation in JSON format in the body.

    json
    {
      "jobId": "123",
      "type": "link",
      "bookmarkId": "exampleBookmarkId",
      "userId": "exampleUserId",
      "url": "https://example.com",
      "operation": "crawled"
    }

    :::

SMTP Configuration

Karakeep can send emails for various purposes such as email verification during signup. Configure these settings to enable email functionality.

Name Required Default Description
SMTP_HOST No Not set The SMTP server hostname or IP address. Required if you want to enable email functionality.
SMTP_PORT No 587 The SMTP server port. Common values are 587 (STARTTLS), 465 (SSL/TLS), or 25 (unencrypted).
SMTP_SECURE No false Whether to use SSL/TLS encryption. Set to true for port 465, false for port 587 with STARTTLS.
SMTP_USER No Not set The username for SMTP authentication. Usually your email address.
SMTP_PASSWORD No Not set The password for SMTP authentication. For services like Gmail, use an app-specific password.
SMTP_FROM No Not set The "from" email address that will appear in sent emails. This should be a valid email address.

Proxy Configuration

If your Karakeep instance needs to connect through a proxy server, you can configure the following settings:

Name Required Default Description
CRAWLER_HTTP_PROXY No Not set HTTP proxy server URL for outgoing HTTP requests (e.g., http://proxy.example.com:8080). You can pass multiple comma separated proxies and the used one will be chosen at random. The proxy is used for crawling, RSS feed fetches and webhooks.
CRAWLER_HTTPS_PROXY No Not set HTTPS proxy server URL for outgoing HTTPS requests (e.g., http://proxy.example.com:8080). You can pass multiple comma separated proxies and the used one will be chosen at random. The proxy is used for crawling, RSS feed fetches and webhooks.
CRAWLER_NO_PROXY No Not set Comma-separated list of hostnames/IPs that should bypass the proxy (e.g., localhost,127.0.0.1,.local)
CRAWLER_ALLOWED_INTERNAL_HOSTNAMES No Not set By default, Karakeep blocks worker-initiated requests whose DNS resolves to private, loopback, link-local, or Tailscale CGNAT IP addresses. Use this to allowlist specific hostnames for internal access (e.g., internal.company.com, app-name.local). Supports domain wildcards by prefixing with a dot (e.g., .internal.company.com, .<tailnet-name>.ts.net). Passing . allowlists all domains. Note: Internal IP validation is bypassed when a proxy is configured for the URL as the local DNS resolver won't necessarily be the same as the one used by the proxy.

:::info
These proxy settings will be used by the crawler and other components that make outgoing HTTP requests.
:::

Monitoring

Karakeep supports distributed tracing and structured event logging via OpenTelemetry. When enabled, traces and logs are collected for tRPC API calls, background worker operations, and other key workflows. Karakeep also exports prometheus-based metrics.

Name Required Default Description
OTEL_TRACING_ENABLED No false Set to true to enable OpenTelemetry tracing. When disabled, all tracing operations are no-ops.
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT No Not set The OTLP HTTP endpoint to send traces to (e.g., http://jaeger:4318/v1/traces or http://otel-collector:4318/v1/traces). If not set, traces are logged to the console.
OTEL_SERVICE_NAME No karakeep The service name that will appear in your tracing backend. The actual service name will include a suffix (e.g., karakeep-api, karakeep-workers).
OTEL_SAMPLE_RATE No 1.0 The sampling rate for traces, between 0.0 and 1.0. A value of 1.0 means all traces are sampled, while 0.1 means only 10% of traces are sampled. Lower values reduce overhead and storage costs in production.
EVENT_LOGS_ENABLED No false Set to true to enable structured event logging. Event logs log various interesting events that happens through the system (e.g. login, bookmark creation, etc). Those can be very chatty. When enabled, they'll get logged to the console unless OTEL logs exporter is enabled.
OTEL_EVENT_LOGS_EXPORT_ENABLED No false Set to true to export event logs via OpenTelemetry OTLP. Requires EVENT_LOGS_ENABLED=true and OTEL_EXPORTER_OTLP_LOGS_ENDPOINT to be set.
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT No Not set The OTLP HTTP endpoint to send event logs to (e.g., http://otel-collector:4318/v1/logs).
PROMETHEUS_AUTH_TOKEN No Random Enable a prometheus metrics endpoint at /api/metrics. This endpoint will require this token being passed in the Authorization header as a Bearer token. If not set, a new random token is generated everytime at startup. This cannot contain any special characters or you may encounter a 400 Bad Request response.

Docs 03 Configuration 02 Different Ai Providers (`docs/docs/03-configuration/02-different-ai-providers.md`)

Configuring different AI Providers

Karakeep uses LLM providers for AI tagging and summarization. It also uses embedding models for stuff like semantic search. We support OpenAI-compatible providers and ollama. This guide will show you how to configure different providers.

Tagging and Summarization Models

OpenAI

If you want to use OpenAI itself, you just need to pass in the OPENAI_API_KEY environment variable.

text
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# You can change the default models by uncommenting the following lines, and choosing your model.
# INFERENCE_TEXT_MODEL=gpt-4.1-mini
# INFERENCE_IMAGE_MODEL=gpt-4o-mini
# EMBEDDING_TEXT_MODEL=text-embedding-3-small
# EMBEDDING_DIMENSIONS=1536
# EMBEDDING_TEXT_MODEL_DIMENSION_OVERRIDE=1536

Ollama

Ollama is a local LLM provider that you can use to run your own LLM server. You'll need to pass ollama's address to karakeep and you need to ensure that it's accessible from within the karakeep container (e.g. no localhost addresses).

Ollama provides two API endpoints:

  1. OpenAI-compatible API (Recommended) - Uses the /v1 chat endpoint which handles message formatting automatically
  2. Native Ollama API - Requires manual formatting for some models

This approach uses Ollama's OpenAI-compatible endpoint and is more reliable with various models:

text
OPENAI_API_KEY=ollama
OPENAI_BASE_URL=http://ollama.mylab.com:11434/v1

# Make sure to pull the models in ollama first. Example models:
INFERENCE_TEXT_MODEL=gemma3
INFERENCE_IMAGE_MODEL=llava
EMBEDDING_TEXT_MODEL=embeddinggemma
EMBEDDING_DIMENSIONS=768
EMBEDDING_CONTEXT_LENGTH=2048

Option 2: Native Ollama API

Alternatively, you can use the native Ollama API:

text
# MAKE SURE YOU DON'T HAVE OPENAI_API_KEY set, otherwise it takes precedence.

OLLAMA_BASE_URL=http://ollama.mylab.com:11434

# Make sure to pull the models in ollama first. Example models:
INFERENCE_TEXT_MODEL=gemma3
INFERENCE_IMAGE_MODEL=llava
EMBEDDING_TEXT_MODEL=embeddinggemma
EMBEDDING_DIMENSIONS=768
EMBEDDING_CONTEXT_LENGTH=2048

# If the model you're using doesn't support structured output, you also need:
# INFERENCE_OUTPUT_SCHEMA=plain

:::tip
If you experience issues with certain models (especially OpenAI's gpt-oss models or other models requiring specific chat formats), try using the OpenAI-compatible API endpoint instead.
:::

Gemini

Gemini has an OpenAI-compatible API. You need to get an api key from Google AI Studio. You also need to set up a billing account, even if using the free tier.

text
OPENAI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
OPENAI_API_KEY=YOUR_API_KEY

# Example models:
INFERENCE_TEXT_MODEL=gemini-2.5-flash-lite
INFERENCE_IMAGE_MODEL=gemini-2.5-flash-lite
EMBEDDING_TEXT_MODEL=gemini-embedding-2
EMBEDDING_DIMENSIONS=3072

OpenRouter

text
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_API_KEY=YOUR_API_KEY

# Example models:
INFERENCE_TEXT_MODEL=meta-llama/llama-4-scout
INFERENCE_IMAGE_MODEL=meta-llama/llama-4-scout
EMBEDDING_TEXT_MODEL=openai/text-embedding-3-small

Perplexity

text
OPENAI_BASE_URL=https://api.perplexity.ai
OPENAI_API_KEY=YOUR_PERPLEXITY_API_KEY
INFERENCE_TEXT_MODEL=sonar-pro
INFERENCE_IMAGE_MODEL=sonar-pro

Azure

Azure has an OpenAI-compatible API.

You can get your API key from the Overview page of the Azure AI Foundry Portal or via "Keys + Endpoints" on the resource in the Azure Portal.

:::warning
The model name is the deployment name you specified when deploying the model, which may differ from the base model name.
:::

text
# Deployed via Azure AI Foundry:
OPENAI_BASE_URL=https://{your-azure-ai-foundry-resource-name}.cognitiveservices.azure.com/openai/v1/

# Deployed via Azure OpenAI Service:
OPENAI_BASE_URL=https://{your-azure-openai-resource-name}.openai.azure.com/openai/v1/

OPENAI_API_KEY=YOUR_API_KEY
INFERENCE_TEXT_MODEL=YOUR_DEPLOYMENT_NAME
INFERENCE_IMAGE_MODEL=YOUR_DEPLOYMENT_NAME

Cloudflare

Cloudflare supports OpenAI compatible endpoints. You can generate an API Token from the Cloudflare dashboard (Workers AI).

text
OPENAI_BASE_URL=https://api.cloudflare.com/client/v4/accounts/{your-account-id}/ai/v1
OPENAI_API_KEY=Your Cloudflare Workers AI Token

# Example models:
INFERENCE_TEXT_MODEL=@cf/meta/llama-3.1-8b-instruct-fast
INFERENCE_IMAGE_MODEL=@cf/meta/llama-3.2-11b-vision-instruct
EMBEDDING_TEXT_MODEL=@cf/google/embeddinggemma-300m
EMBEDDING_DIMENSIONS=768
EMBEDDING_CONTEXT_LENGTH=2048
INFERENCE_OUTPUT_SCHEMA=json

Embedding Models

Karakeep uses embedding models for stuff like semantic search and refining tag suggestions. Typically, when you configure an embedding model, you'll want to configure its default num dimensions and context length. Those are done via:

text
EMBEDDING_TEXT_MODEL=
EMBEDDING_DIMENSIONS=
EMBEDDING_CONTEXT_LENGTH=

Embeddings can use a different OpenAI-compatible provider. Set either override independently; any unset value falls back to its corresponding OPENAI_* setting.

text
EMBEDDING_OPENAI_API_KEY=embedding-provider-api-key
EMBEDDING_OPENAI_BASE_URL=https://embedding-provider.example.com/v1

For embedding models that support multiple output sizes, set EMBEDDING_TEXT_MODEL_DIMENSION_OVERRIDE to pass the requested dimensions to the provider. Its value must match EMBEDDING_DIMENSIONS, which configures the vector store, or Karakeep will fail to start:

text
EMBEDDING_TEXT_MODEL_DIMENSION_OVERRIDE=768
EMBEDDING_DIMENSIONS=768

Once you've configured an embedding model, you'll also want to enable auto-embedding generation for your bookmarks by:

text
EMBEDDING_ENABLE_AUTO_INDEXING=true

Note: Embeddings from different models are not compatible with each other. If you're to ever change the embedding model or the number of dimensions, you'll need to regenerate embeddings for all of your bookmarks.


Docs 04 Using Karakeep Advanced Workflows (`docs/docs/04-using-karakeep/advanced-workflows.md`)


Advanced workflows

Push Karakeep further with automation and integrations.

Rule engine

  • Create if-this-then-that style rules to auto-tag, favourite, or route bookmarks into lists based on metadata or content.
  • Useful for keeping inboxes tidy (e.g. auto-archive newsletters, auto-tag domains, or flag videos).

API

  • Use the API to script imports, syncs, or custom tools. Same surface area the apps use.
  • Great for integrating with personal scripts, cron jobs, or other services.

Webhooks

  • Subscribe to bookmark events and trigger your own systems when something is added, updated, or archived.
  • Pair with the API to build end-to-end automations (e.g. push new saves into a writing queue or a team chat).

Docs 04 Using Karakeep Bookmarking (`docs/docs/04-using-karakeep/bookmarking.md`)


Bookmarking

Everything in Karakeep starts as a bookmark. Here’s how the different types work and how to keep your home view tidy with favourites and archive.

Favourites

  • Star bookmarks you like so they sit in their own dedicated favourites view for quick return visits.
  • Handy for saved gems you want to re-open often like articles you enjoyed, references you come back to, or things worth sharing.

Archiving

  • Archive hides a bookmark from the homepage without deleting it.
  • Archived items stay searchable and keep all tags, highlights, and attachments.
  • Ideal for achieving inbox-zero style for your homepage.

Bookmark types

  • Links: URLs saved from the web or extension. Karakeep grabs metadata, previews, screenshots, and archives when configured.
  • Text: Quick notes or snippets you paste in. Great for ideas, quotes, or saving context alongside links.
  • Media: Images or PDFs you want to save for later. Karakeep automatically extracts content out of those files and makes them searchable.

Notes

  • Attach personal notes to any bookmark to capture context, reminders, or next steps.
  • Notes live with the bookmark and are searchable, so you can recall why something mattered.

Highlights

  • Save quotes, summaries, or TODOs while reading.
  • Highlights show up in the bookmark detail view/reader and are searchable, so you can jump straight to the key ideas.

Attachments

  • Store extra context alongside a bookmark: screenshots, page captures, videos, and files you upload.
  • Screenshots & archives: fallback when the original page changes or disappear.
  • Uploaded files: keep PDFs, notes, or supporting assets right with the link.
  • Manage attachments from the bookmark detail view: upload, download, or detach as needed.

Docs 04 Using Karakeep Import (`docs/docs/04-using-karakeep/import.md`)


Import your library

Karakeep supports importing bookmarks using the Netscape HTML Format, Pocket's new CSV format & Omnivore's JSONs. Titles, tags and addition date will be preserved during the import. An automatically created list will contain all the imported bookmarks.

:::info
All the URLs in the bookmarks file will be added automatically, you will not be able to pick and choose which bookmarks to import!
:::

Import from Chrome

  • Open Chrome and go to chrome://bookmarks
  • Click on the three dots on the top right corner and choose Export bookmarks
  • This will download an html file with all of your bookmarks.
  • To import the bookmark file, go to the settings and click "Import Bookmarks from HTML file".

Import from Firefox

  • Open Firefox and click on the menu button (☰) in the top right corner.
  • Navigate to Bookmarks > Manage bookmarks (or press Ctrl + Shift + O / Cmd + Shift + O to open the Bookmarks Library).
  • In the Bookmarks Library, click the Import and Backup button at the top. Select Export Bookmarks to HTML... to save your bookmarks as an HTML file.
  • To import a bookmark file, go back to the Import and Backup menu, then select Import Bookmarks from HTML... and choose your saved HTML file.

Import from Pocket

  • Go to the Pocket export page and follow the instructions to export your bookmarks.
  • Pocket after a couple of minutes will mail you a zip file with all the bookmarks.
  • Unzip the file and you'll get a CSV file.
  • To import the bookmark file, go to the settings and click "Import Bookmarks from Pocket export".

Import from Omnivore

  • Follow Omnivore's documentation to export your bookmarks.
  • This will give you a zip file with all your data.
  • The zip file contains a lot of JSONs in the format metadata_*.json. You can either import every JSON file manually, or merge the JSONs into a single JSON file and import that.
  • To merge the JSONs into a single JSON file, you can use the following command in the unzipped directory: jq -r '.[]' metadata_*.json | jq -s > omnivore.json and then import the omnivore.json file. You'll need to have the jq tool installed.

Import using the CLI

:::warning
Importing bookmarks using the CLI requires some technical knowledge and might not be very straightforward for non-technical users. Don't hesitate to ask questions in github discussions or discord though.
:::

If you can get your bookmarks in a text file with one link per line, you can use the following command to import them using the karakeep cli:

text
while IFS= read -r url; do
    karakeep --api-key "<KEY>" --server-addr "<SERVER_ADDR>" bookmarks add --link "$url"
done < all_links.txt

Docs 04 Using Karakeep Lists (`docs/docs/04-using-karakeep/lists.md`)


Lists

Lists are the core organizational layer in Karakeep. Every saved item can sit in multiple lists so you can group links by project, topic, or audience without duplicating them.

Manual lists

  • Curated sets you add bookmarks to by hand. Great for projects, reading queues, or hand-picked collections.
  • Can be private (visible only to you) or public (share a read-only link).
  • Can be collaborative: invite people by email as viewers or editors. Editors can add their own bookmarks; viewers can browse. Your personal states (favourite/archive) stay yours even inside a shared list.

Smart lists

  • Auto-updating lists powered by a saved search query (e.g. #ai -archived).
  • Best for dynamic views like Youtube links added last week or All reddit links from r/selfhosted.

Docs 04 Using Karakeep Quick Sharing (`docs/docs/04-using-karakeep/quick-sharing.md`)


Quick capture and sharing

The whole point of Karakeep is making it easy to hoard the content. That's why there are a couple of

Mobile Apps

Browser Extensions

  • Chrome extension: here.

  • Firefox addon: here.

  • Community Extensions

  • Safari extension: App Store Link. For macOS and iOS to allow a simple way to add your bookmarks to your self hosted karakeep instance.


Docs 04 Using Karakeep Search Query Language (`docs/docs/04-using-karakeep/search-query-language.md`)


Search Query Language

Karakeep provides a search query language to filter and find bookmarks. Here are all the supported qualifiers and how to use them:

Basic Syntax

  • Use spaces to separate multiple conditions (implicit AND)
  • Use and/or keywords for explicit boolean logic
  • Prefix qualifiers with - or ! to negate them (e.g., -is:archived or !is:archived)
  • Use parentheses () for grouping conditions (note that groups can't be negated)

Qualifiers

Here's a comprehensive table of all supported qualifiers:

Qualifier Description Example Usage
is:fav Favorited bookmarks is:fav
is:archived Archived bookmarks -is:archived
is:tagged Bookmarks that has one or more tags is:tagged
is:inlist Bookmarks that are in one or more lists is:inlist
has:notes Bookmarks that have a non-empty note has:notes
has:highlights Bookmarks that have one or more highlights has:highlights
is:link, is:text, is:media Bookmarks that are of type link, text or media is:link
is:broken Bookmarks with broken/failed links (crawl failures or non-2xx status codes) is:broken
url:<value> Match bookmarks with URL substring url:example.com
title:<value> Match bookmarks with title substring title:example
Supports quoted strings for titles with spaces title:"my title"
#<tag> or tag:<tag> Match bookmarks with specific tag #important or tag:important
Supports quoted strings for tags with spaces #"work in progress" or tag:"work in progress"
list:<name> Match bookmarks in specific list list:reading
Supports quoted strings for list names with spaces list:"to review"
after:<date> Bookmarks created on or after date (YYYY-MM-DD) after:2023-01-01
before:<date> Bookmarks created on or before date (YYYY-MM-DD) before:2023-12-31
feed:<name> Bookmarks imported from a particular rss feed feed:Hackernews
source:<value> Match bookmarks from a specific source. Valid values: api, web, cli, mobile, extension, singlefile, rss, import source:rss -source:web
age:<time-range> Match bookmarks based on how long ago they were created. Use < or > to indicate the maximum / minimum age of the bookmarks. Supported units: d (days), w (weeks), m (months), y (years). age:<1d age:>2w age:<6m age:>3y

Examples

plaintext
# Find favorited bookmarks from 2023 that are tagged "important"
is:fav after:2023-01-01 before:2023-12-31 #important

# Find archived bookmarks that are either in "reading" list or tagged "work"
is:archived and (list:reading or #work)

# Find bookmarks that are not tagged or not in any list
-is:tagged or -is:inlist

# Find bookmarks that have notes but no highlights
has:notes -has:highlights

# Find bookmarks with "React" in the title
title:React

Combining Conditions

You can combine multiple conditions using boolean logic:

plaintext
# Find favorited bookmarks from 2023 that are tagged "important"
is:fav after:2023-01-01 before:2023-12-31 #important

# Find archived bookmarks that are either in "reading" list or tagged "work"
is:archived and (list:reading or #work)

# Find bookmarks that are not favorited and not archived
-is:fav -is:archived

# Using ! as an alias for negation
!is:fav !is:archived

# Using tag: as an alias for #
tag:important tag:"work in progress"

Any text not part of a qualifier will be treated as a full-text search:

plaintext
# Search for "machine learning" in bookmark content
machine learning

# Combine text search with qualifiers
machine learning is:fav

Docs 04 Using Karakeep Tags (`docs/docs/04-using-karakeep/tags.md`)


Tags

Tags are lightweight labels you can attach to any bookmark to add meaning without rigid folders.

  • Use tags to capture topics, sources, people, or workflow states (e.g. ai, design, to-read).
  • Combine multiple tags to filter or build smart lists; tags travel with a bookmark wherever it appears.
  • AI tags might look a little messy, but the extra labels make finding things easier. Use tags for broad discovery and lists when you want a clean, hand-picked setup.

Docs 05 Integrations 02 Command Line (`docs/docs/05-integrations/02-command-line.md`)

Command Line Tool (CLI)

Karakeep comes with a simple CLI for those users who want to do more advanced manipulation.

Features

  • Manipulate bookmarks, lists and tags
  • Mass import/export of bookmarks

Installation (NPM)

text
npm install @karakeep/cli

Installation (Docker)

text
docker run --rm ghcr.io/karakeep-app/karakeep-cli:release --help

Usage

text
karakeep
text
Usage: karakeep [options] [command]

A CLI interface to interact with the karakeep api

Options:
  --api-key <key>       the API key to interact with the API (env: KARAKEEP_API_KEY)
  --server-addr <addr>  the address of the server to connect to (env: KARAKEEP_SERVER_ADDR)
  --json                to output the result as JSON
  -V, --version         output the version number
  -h, --help            display help for command

Commands:
  auth                  authentication commands
  bookmarks             manipulating bookmarks
  lists                 manipulating lists
  tags                  manipulating tags
  whoami                returns info about the owner of this API key
  help [command]        display help for command

And some of the subcommands:

text
karakeep bookmarks
text
Usage: karakeep bookmarks [options] [command]

Manipulating bookmarks

Options:
  -h, --help             display help for command

Commands:
  add [options]          creates a new bookmark
  get <id>               fetch information about a bookmark
  update [options] <id>  updates bookmark
  list [options]         list all bookmarks
  delete <id>            delete a bookmark
  help [command]         display help for command
text
karakeep lists
text
Usage: karakeep lists [options] [command]

Manipulating lists

Options:
  -h, --help                 display help for command

Commands:
  list                       lists all lists
  delete <id>                deletes a list
  add-bookmark [options]     add a bookmark to list
  remove-bookmark [options]  remove a bookmark from list
  help [command]             display help for command

Obtaining an API Key

To use the CLI, you'll need to get an API key from your karakeep settings. You can validate that it's working by running:

text
karakeep --api-key <key> --server-addr <addr> whoami

For example:

text
karakeep --api-key mysupersecretkey --server-addr https://try.karakeep.app whoami
{
  id: 'j29gnbzxxd01q74j2lu88tnb',
  name: 'Test User',
  email: '[email protected]'
}

You can also store the server address and API key in
$XDG_CONFIG_HOME/karakeep/config.json. If XDG_CONFIG_HOME is not set, the
CLI reads ~/.config/karakeep/config.json.

json
{
  "serverAddr": "https://try.karakeep.app",
  "apiKey": "mysupersecretkey"
}

Command-line options take precedence over environment variables, and
environment variables take precedence over the config file.
If no server address is provided, the CLI defaults to
https://cloud.karakeep.app.

To create or update this file interactively, run:

bash
karakeep auth init

Other clients

There also exists a non-official, community-maintained, python package called karakeep-python-api that can be accessed from the CLI, but is not official.


Docs 05 Integrations 03 Mcp (`docs/docs/05-integrations/03-mcp.md`)

Model Context Protocol Server (MCP)

Karakeep comes with a Model Context Protocol server that can allow LLMs (like claude and codex) to interact with your karakeep data.

Supported Tools

Bookmarks

  • Searching bookmarks (search-bookmarks)
  • Reading a bookmark (get-bookmark, get-bookmark-content)
  • Creating text and URL bookmarks (create-bookmark)
  • Updating a bookmark (update-bookmark)
  • Deleting a bookmark (delete-bookmark)

Lists

  • Listing all lists (get-lists)
  • Retrieving a single list (get-list)
  • Creating a list (create-list)
  • Updating a list (update-list) — name, icon, description, parentId, query, public; field constraints (length caps, smart-query validation) are inherited from the shared schema
  • Deleting a list (delete-list) — child lists are NOT deleted with the parent; they keep their parentId pointing at the deleted list
  • Adding and removing bookmarks from lists (add-bookmark-to-list, remove-bookmark-from-list)

Tags

  • Listing tags with filters / pagination (get-tags)
  • Retrieving a single tag with usage counts (get-tag)
  • Renaming a tag (update-tag)
  • Deleting a tag (delete-tag) — bookmarks that had the tag are not deleted
  • Listing the bookmarks attached to a tag (get-tag-bookmarks)
  • Attaching and detaching tags on bookmarks (attach-tag-to-bookmark, detach-tag-from-bookmark)

Usage with Claude Desktop

From NPM:

json
{
  "mcpServers": {
    "karakeep": {
      "command": "npx",
      "args": [
        "@karakeep/mcp"
      ],
      "env": {
        "KARAKEEP_API_ADDR": "https://cloud.karakeep.app",
        "KARAKEEP_API_KEY": "<YOUR_TOKEN>"
      }
    }
  }
}

From Docker:

json
{
  "mcpServers": {
    "karakeep": {
      "command": "docker",
      "args": [
        "run",
        "-e",
        "KARAKEEP_API_ADDR=https://cloud.karakeep.app",
        "-e",
        "KARAKEEP_API_KEY=<YOUR_TOKEN>",
        "ghcr.io/karakeep-app/karakeep-mcp:latest"
      ]
    }
  }
}

Usage with Codex Desktop

  1. Get an API Key from your Karakeep settings page.
  2. Go to Codex Settings > Integrations > Plugins > Add > Add MCP Server.
  3. Use the following configuration, replacing the placeholder with your API key.

Demo

Adding Text Bookmarks

Adding URL Bookmarks


Docs 05 Integrations 05 Singlefile (`docs/docs/05-integrations/05-singlefile.md`)

Using Karakeep with SingleFile Extension

:::tip
The official Karakeep extension now also supports client-side crawling as an experimental feature (powered by SingleFile under the hood). If you only need to hoard pages from your own browser session, you may not need the standalone SingleFile extension anymore.
:::

Karakeep supports being a destination for the SingleFile extension. This has the benefit of allowing you to use the singlefile extension to hoard links as you're seeing them in the browser. This is perfect for websites that don't like to get crawled, has annoying cookie banner or require authentication.

Setup

  1. Install the SingleFile extension.
  2. In the extension settings, select Destinations.
  3. Select upload to a REST Form API.
  4. In the URL, insert the address: https://YOUR_SERVER_ADDRESS/api/v1/bookmarks/singlefile.
  5. In the authorization token field, paste an API key that you can get from your karakeep settings.
  6. Set data field name to file.
  7. Set URL field name to url.
  8. (Optional) Add ?ifexists=MODE to the URL where MODE is one of skip, overwrite, overwrite-recrawl, append, or append-recrawl. See "Handling Existing Bookmarks" section below for details.

Now, go to any page and click the singlefile extension icon. Once it's done with the upload, the bookmark should show up in your karakeep instance. Note that the singlefile extension doesn't show any progress on the upload. Given that archives are typically large, it might take 30+ seconds until the upload is done and starts showing up in Karakeep.

Importing an existing archive with the CLI

If you already have a SingleFile HTML archive, import it by passing both the
archive path and the original page URL:

bash
karakeep bookmarks import-singlefile page.html --url "https://example.com/page"

Use --if-exists MODE to control how an existing bookmark for the same URL is
handled. The supported modes are described below.

Handling Existing Bookmarks

When uploading a page that already exists in your archive (same URL), you can control the behavior by setting the ifexists query parameter in the upload URL. The available modes are:

  • skip (default): If the bookmark already exists, skip creating a new one
  • overwrite: Replace existing precrawled archive (only the most recent archive is kept)
  • overwrite-recrawl: Replace existing archive and queue a recrawl to update content
  • append: Add new archive version alongside existing ones
  • append-recrawl: Add new archive and queue a recrawl

To use these modes, append ?ifexists=MODE to your upload URL, replacing MODE with your desired behavior.

For example:
https://YOUR_SERVER_ADDRESS/api/v1/bookmarks/singlefile?ifexists=overwrite

In the singlefile extension, you probably will want to change the following settings for better experience:

  • Stylesheets > compress CSS content: on
  • Stylesheets > group duplicate stylesheets together: on
  • HTML content > remove frames: on

Also, you most likely will want to change the default MAX_ASSET_SIZE_MB in karakeep to something higher, for example 100.

:::info
Currently, we don't support screenshots for singlefile uploads, but this will change in the future.
:::


Docs 05 Integrations 06 Rss Feeds (`docs/docs/05-integrations/06-rss-feeds.md`)

RSS Feeds

Karakeep offers RSS feed integration, allowing you to both consume RSS feeds from external sources and publish your lists as RSS feeds for others to subscribe to.

Publishing RSS Feeds

You can publish any of your lists as an RSS feed, making it easy to share your bookmarks with others or integrate them into RSS readers.

Enabling RSS for a List

  1. Navigate to one of your lists
  2. Click on the list settings (three dots menu)
  3. Toggle the "RSS Feed" switch to enable it
  4. Copy the generated RSS feed URL

What Gets Published

RSS feeds include:

  • Links: Bookmarks of type "link" with their URL, title, description, and author
  • Assets: Uploaded files (PDFs, images) are included with a link to view them
  • Tags: Bookmark tags are exported as RSS categories
  • Dates: The bookmark creation date is used as the publication date

Note: Text notes are not included in RSS feeds as they don't have an associated URL.

Security Considerations

  • Each RSS feed requires a unique token for access
  • Tokens can be regenerated at any time, which will invalidate the old URL
  • Disabling RSS for a list immediately revokes access

Consuming RSS Feeds

Karakeep can automatically monitor RSS feeds and create bookmarks from new entries, making it perfect for staying up to date with blogs, news sites, and other content sources.

Adding an RSS Feed

  1. Go to Settings → RSS Feeds
  2. Click Add Feed
  3. Enter the feed details:
    • Name: A friendly name for the feed
    • URL: The RSS/Atom feed URL
    • Enabled: Toggle to enable/disable the feed
    • Import Tags: Enable to import RSS categories as bookmark tags

How It Works

  • Karakeep checks enabled RSS feeds every hour
  • New entries are automatically created as bookmarks
  • Duplicate entries are automatically detected and skipped

Docs 05 Integrations 07 Agentic Skills (`docs/docs/05-integrations/07-agentic-skills.md`)

Agentic Skills

Karakeep provides agentic skills that allow AI assistants to interact with your Karakeep instance. Skills teach AI assistants how to search, save, and organize your bookmarks through natural conversation.

Installation

ClawHub

The skill is available on ClawHub.

skills.sh

You can also install the skill using skills.sh:

bash
npx skills add karakeep-app/karakeep

Docs 06 Administration 01 Security Considerations (`docs/docs/06-administration/01-security-considerations.md`)

Security Considerations

If you're going to give app access to untrusted users, there's some security considerations that you'll need to be aware of given how the crawler works. The crawler is basically running a browser to fetch the content of the bookmarks. Any untrusted user can submit bookmarks to be crawled from your server and they'll be able to see the crawling result. This can be abused in multiple ways:

  1. Untrusted users can submit crawl requests to websites that you don't want to be coming out of your IPs.
  2. Crawling user controlled websites can expose your origin IP (and location) even if your service is hosted behind cloudflare for example.
  3. The crawling requests will be coming out from your own network, which untrusted users can leverage to crawl internal non-internet exposed endpoints.

To mitigate those risks, you can do one of the following:

  1. Limit access to trusted users
  2. Let the browser traffic go through some VPN with restricted network policies.
  3. Host the browser container outside of your network.
  4. Use a hosted browser as a service (e.g. browserless). Note: I've never used them before.

To mitigate some of the risks, Karakeep has basic Server-Side Request Forgery (SSRF) protections to avoid probing internal endpoints. However, those checks mitigate only some of the risks. If you want to harden your Karakeep instance, configure a crawler proxy that's running outside of your internal network.


Docs 06 Administration 02 FAQ (`docs/docs/06-administration/02-FAQ.md`)

Frequently Asked Questions (FAQ)

User Management

Lost password

If you are not an administrator

Administrators can reset the password of any user. Contact an administrator to reset the password for you.

  • Navigate to the Admin Settings page
  • Find the user in the Users List
  • In the Actions column, there is a button to reset the password
  • Enter a new password and press Reset
  • The new password is now set
  • If required, you can change your password again (so the admin does not know your password) in the User Settings

If you are an administrator

If you are an administrator and lost your password, you have to reset the password in the database.

To reset the password:

  • Acquire some kind of tools that helps you to connect to the database:
    • sqlite3 on Linux: run apt-get install sqlite3 (depending on your package manager)
    • e.g. dbeaver on Windows
  • Shut down Karakeep
  • Connect to the db.db database, which is located in the data directory you have mounted to your docker container:
    • by e.g. running sqlite3 db.db (in your data directory)
    • or going through e.g. the dbeaver UI to locate the file in the data directory and connecting to it
  • Update the password in the database by running:
    • update user set password='$2a$10$5u40XUq/cD/TmLdCOyZ82ePENE6hpkbodJhsp7.e/BgZssUO5DDTa', salt='' where email='<YOUR_EMAIL_HERE>';
    • (don't forget to put your email address into the command)
  • The new password for your user is now adminadmin.
  • Start Karakeep again
  • Log in with your email address and the password adminadmin and change the password to whatever you want in the User Settings

Adding another administrator

By default, the first user to sign up gets promoted to administrator automatically.

In case you want to grant those permissions to another user:

  • Navigate to the Admin Settings page
  • Find the user in the Users List
  • In the Actions column, there is a button to change the Role
  • Change the Role to Admin
  • Press Change
  • The new administrator has to log out and log in again to get the new role assigned

Adding new users, when signups are disabled

Administrators can create new accounts any time:

  • Navigate to the Admin Settings page
  • Go to the Users List
  • Press the Create User Button.
  • Enter the information for the user
  • Press create
  • The new user can now log in

Docs 06 Administration 03 Openai (`docs/docs/06-administration/03-openai.md`)

Tagging Costs

This service uses OpenAI for automatic tagging. This means that you'll incur some costs if automatic tagging is enabled. There are two type of inferences that we do:

Text Tagging

For text tagging, we use the gpt-6-luna model. This model is extremely cheap. Cost per inference varies depending on the content size per article. Though, roughly, You'll be able to generate tags for almost 6000+ bookmarks for less than $1.

Image Tagging

For image uploads, we use the gpt-4o-mini model for extracting tags from the image. You can learn more about the costs of using this model here. To lower the costs, we're using the low resolution mode (fixed number of tokens regardless of image size). You'll be able to run inference for 1000+ images for less than a $1.


Docs 06 Administration 05 Troubleshooting (`docs/docs/06-administration/05-troubleshooting.md`)

Troubleshooting

SqliteError: no such table: user

This usually means that there's something wrong with the database setup (more concretely, it means that the database is not initialized). This can be caused by multiple problems:

  1. Wiped DATA_DIR: Your DATA_DIR got wiped (or the backing storage dir changed). If you did this intentionally, restart the container so that it can re-initalize the database.
  2. Missing DATA_DIR: You're not using the default docker compose file, and you forgot to configure the DATA_DIR env var. This will result into the database getting set up in a different directory than the one used by the service.

Chrome Failed to Read DnsConfig

If you see this error in the logs of the chrome container, it's a benign error and you can safely ignore it. Whatever problems you're having, is unrelated to this error.

AI Tagging not working (when using OpenAI)

Check the logs of the container and this will usually tell you what's wrong. Common problems are:

  1. Typo in the env variable OPENAI_API_KEY name resulting into logs saying something like "skipping inference as it's not configured".
  2. You forgot to call docker compose up after configuring open ai.
  3. OpenAI requires pre-charging the account with credits before using it, otherwise you'll get an error like "insufficient funds".

AI Tagging not working (when using Ollama)

Check the logs of the container and this will usually tell you what's wrong. Common problems are:

  1. Typo in the env variable OLLAMA_BASE_URL name resulting into logs saying something like "skipping inference as it's not configured".
  2. You forgot to call docker compose up after configuring ollama.
  3. You didn't change the INFERENCE_TEXT_MODEL env variable, resulting into karakeep attempting to use gpt models with ollama which won't work.
  4. Ollama server is not reachable by the karakeep container. This can be caused by:
    1. Ollama server being in a different docker network than the karakeep container.
    2. You're using localhost as the OLLAMA_BASE_URL instead of the actual address of the ollama server. localhost points to the container itself, not the docker host. Check this stackoverflow answer to find how to correctly point to the docker host address instead.

Crawling not working

Check the logs of the container and this will usually tell you what's wrong. Common problems are:

  1. You changed the name of the chrome container but didn't change the BROWSER_WEB_URL env variable.

Upgrading Meilisearch - Migrating the Meilisearch db version

Meilisearch is the database used by karakeep for searching in your bookmarks. The version used by karakeep is 1.41.0 and it is advised not to upgrade it without good reasons. If you do, you might see errors like Your database version (x.x.x) is incompatible with your current engine version (x.x.x). To migrate data between Meilisearch versions, please follow our guide on https://www.meilisearch.com/docs/learn/update_and_migration/updating..

Luckily we can easily workaround this:

  1. Stop the Meilisearch container.
  2. Inside the Meilisearch volume bound to /meili_data, erase/rename the folder called data.ms.
  3. Launch Meilisearch again.
  4. Login to karakeep as administrator and go to (as of v0.24.1) Admin Settings > Background Jobs then click on Reindex All Bookmarks.
  5. When the reindexing has finished, Meilisearch should be working as usual.

If you run into issues, the official documentation can be found there.


Docs 06 Administration 06 Server Migration (`docs/docs/06-administration/06-server-migration.md`)

Migrating Between Servers

This guide explains how to migrate all of your data from one Karakeep server to another using the official CLI.

What the command does

The migration copies user-owned data from a source server to a destination server in this order:

  • User settings
  • Lists (preserving hierarchy and settings)
  • RSS feeds
  • AI prompts (custom prompts and their enabled state)
  • Webhooks (URL and events)
  • Tags (ensures tags by name exist)
  • Rule engine rules (IDs remapped to destination equivalents)
  • Bookmarks (links, text, and assets)
    • After creation, attaches the correct tags and adds to the correct lists

Notes:

  • Webhook tokens cannot be read via the API, so tokens are not migrated. Re‑add them on the destination if needed.
  • Asset bookmarks are migrated by downloading the original asset and re‑uploading it to the destination. Only images and PDFs are supported for asset bookmarks.
  • Link bookmarks on the destination may be de‑duplicated if the same URL already exists.

Prerequisites

  • Install the CLI:
    • NPM: npm install @karakeep/cli
    • Docker: docker run --rm ghcr.io/karakeep-app/karakeep-cli:release --help
  • Collect API keys and base URLs for both servers:
    • Source: --server-addr, --api-key
    • Destination: --dest-server, --dest-api-key

Quick start

text
karakeep --server-addr https://src.example.com --api-key <SOURCE_API_KEY> migrate \
  --dest-server https://dest.example.com \
  --dest-api-key <DEST_API_KEY>

The command is long‑running and shows live progress for each phase. You will be prompted for confirmation; pass --yes to skip the prompt.

Options

  • --server-addr : Source server base URL
  • --api-key <key>: API key for the source server
  • --dest-server : Destination server base URL
  • --dest-api-key <key>: API key for the destination server
  • --batch-size <n>: Page size for bookmark migration (default 50, max 100)
  • -y, --yes: Skip the confirmation prompt

What to expect

  • Lists are recreated parent‑first and retain their hierarchy.
  • Feeds, prompts, webhooks, and tags are recreated by value.
  • Rules are recreated after IDs (tags, lists, feeds) are remapped to their corresponding destination IDs.
  • After each bookmark is created, the command attaches the correct tags and adds it to the correct lists.

Caveats and tips

  • Webhook auth tokens must be re‑entered on the destination after migration.
  • If your destination already contains data, duplicate links may be de‑duplicated; tags and list membership are still applied to the existing bookmark.

Troubleshooting

  • If the command exits early, you can re‑run it, but note:
    • Tags and lists that already exist are reused.
    • Link de‑duplication avoids duplicate link bookmarks. Notes and assets will get re-created.
    • Rules, webhooks, rss feeds will get re-created and you'll have to manually clean them up afterwards.
    • The progress log indicates how far it got.
  • Use a smaller --batch-size if your source or destination is under heavy load.

Docs 06 Administration 07 Legacy Container Upgrade (`docs/docs/06-administration/07-legacy-container-upgrade.md`)

Legacy Container Upgrade

Karakeep's 0.16 release consolidated the web and worker containers into a single container and also dropped the need for the redis container. The legacy containers will stop being supported soon, to upgrade to the new container do the following:

  1. Remove the redis container and its volume if it had one.
  2. Move the environment variables that you've set exclusively to the workers container to the web container.
  3. Delete the workers container.
  4. Rename the web container image from hoarder-app/hoarder-web to hoarder-app/hoarder.
diff
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index cdfc908..6297563 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,7 +1,7 @@
 version: "3.8"
 services:
   web:
-    image: ghcr.io/hoarder-app/hoarder-web:${KARAKEEP_VERSION:-release}
+    image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
     restart: unless-stopped
     volumes:
       - data:/data
@@ -10,14 +10,10 @@ services:
     env_file:
       - .env
     environment:
-      REDIS_HOST: redis
       MEILI_ADDR: http://meilisearch:7700
+      BROWSER_WEB_URL: http://chrome:9222
+      # OPENAI_API_KEY: ...
       DATA_DIR: /data
-  redis:
-    image: redis:7.2-alpine
-    restart: unless-stopped
-    volumes:
-      - redis:/data
   chrome:
     image: ghcr.io/karakeep-app/karakeep-chrome:release
     restart: unless-stopped
@@ -37,24 +33,7 @@ services:
       MEILI_NO_ANALYTICS: "true"
     volumes:
       - meilisearch:/meili_data
-  workers:
-    image: ghcr.io/hoarder-app/hoarder-workers:${KARAKEEP_VERSION:-release}
-    restart: unless-stopped
-    volumes:
-      - data:/data
-    env_file:
-      - .env
-    environment:
-      REDIS_HOST: redis
-      MEILI_ADDR: http://meilisearch:7700
-      BROWSER_WEB_URL: http://chrome:9222
-      DATA_DIR: /data
-      # OPENAI_API_KEY: ...
-    depends_on:
-      web:
-        condition: service_started

 volumes:
-  redis:
   meilisearch:
   data:

Docs 06 Administration 08 Hoarder To Karakeep Migration (`docs/docs/06-administration/08-hoarder-to-karakeep-migration.md`)

Hoarder to Karakeep Migration

Hoarder is rebranding to Karakeep. Due to github limitations, the old docker image might not be getting new updates after the rebranding. You might need to update your docker image to point to the new karakeep image instead by applying the following change in the docker compose file.

diff
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index cdfc908..6297563 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,7 +1,7 @@
 version: "3.8"
 services:
   web:
-    image: ghcr.io/hoarder-app/hoarder:${HOARDER_VERSION:-release}
+    image: ghcr.io/karakeep-app/karakeep:${HOARDER_VERSION:-release}

You can also change the HOARDER_VERSION environment variable but if you do so remember to change it in the .env file as well.

Migrating a Baremetal Installation

If you previously used the Debian/Ubuntu install script to install Hoarder, there is an option to migrate your installation to Karakeep.

bash
bash karakeep-linux.sh migrate

This will migrate your installation with no user input required. After the migration, the script will also check for an update.


Docs 06 Administration 09 Chrome Image Migration (`docs/docs/06-administration/09-chrome-image-migration.md`)

Migrating to the Karakeep Chrome Image

Karakeep now publishes its own tested Chrome image instead of relying on the
unmaintained Alpine Chrome image. If you maintain a custom Compose file, update
the chrome service with the following diff:

diff
services:
   chrome:
-    image: gcr.io/zenika-hub/alpine-chrome:124
+    image: ghcr.io/karakeep-app/karakeep-chrome:release
     restart: unless-stopped
+    init: true
     command:
-      - --no-sandbox
       - --disable-gpu
       - --disable-dev-shm-usage
-      - --remote-debugging-address=0.0.0.0
-      - --remote-debugging-port=9222
       - --hide-scrollbars
       - --disable-blink-features=AutomationControlled
       - --window-size=1440,900

Removing the remote-debugging arguments is required. The new image's entrypoint
starts Chrome on an internal port and forwards container port 9222; overriding
that port conflicts with the forwarding setup. The entrypoint also supplies
--no-sandbox, so removing the duplicate Compose argument does not enable the
Chromium sandbox.

The connection used by Karakeep does not change:

yaml
environment:
  BROWSER_WEB_URL: http://chrome:9222

After editing the Compose file, pull and recreate the services:

bash
docker compose pull chrome
docker compose up -d chrome

The migration does not change Karakeep data or require a database migration.
The release tag follows the browser image promoted for stable Karakeep
deployments. To control browser upgrades independently, replace release with
an immutable versioned tag from the
Karakeep Chrome package.


Docs 07 Community 01 Community Projects (`docs/docs/07-community/01-community-projects.md`)

Community Projects

This page lists community projects that are built around Karakeep, but not officially supported by the development team.

:::warning
This list comes with no guarantees about security, performance, reliability, or accuracy. Use at your own risk.
:::

Raycast Extension

By @luolei.

A user-friendly Raycast extension that seamlessly integrates with Karakeep, bringing powerful bookmark management to your fingertips. Quickly save, search, and organize your bookmarks, texts, and images—all through Raycast's intuitive interface.

Get it here.

By @Kyzcreig

An Alfred workflow for inline bookmark search — type kk <query> and see live results (title, tags, URL) directly in Alfred, using Karakeep's full query language (is:fav, #tag, list:, age:). Enter opens the original URL; Cmd-Enter opens the bookmark in Karakeep. Responses are cached per-query so typing stays lag-free.

Get it here.

Alfred Workflow

By @yinan-c

An Alfred workflow to quickly hoard stuff or access your hoarded bookmarks!

Get it here.

Obsidian Plugin

By @jhofker

An Obsidian plugin that syncs your Karakeep bookmarks with Obsidian, creating markdown notes for each bookmark in a designated folder.

Get it here, or install it directly from Obsidian's community plugin store (link).

Telegram Bot

By @Madh93

A Telegram Bot for saving bookmarks to Karakeep directly through Telegram.

Get it here.

Hoarder's Pipette

By @DanSnow

A chrome extension that injects karakeep's bookmarks into your search results.

Get it here.

Karakeep-Python-API

By @thiswillbeyourgithub

A python package to simplify access to the karakeep API. Can be used as a library or from the CLI. Aims for feature completeness and high test coverage but do check its feature matrix before relying too much on it.

Its repository also hosts the Community Script, for example:

Community Script Description Documentation
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. Link
Karakeep-List-To-Tag Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list. Link
Omnivore2Karakeep-Highlights Imports highlights from Omnivore export data to Karakeep, with intelligent position detection and bookmark matching. Supports dry-run mode for testing. Link

Get it here.

FreshRSS_to_Karakeep

By @thiswillbeyourgithub

A python script to automatically create Karakeep bookmarks from your FreshRSS favourites/saved RSS item. Made to be called periodically. Based on the community project Karakeep-Python-API above, by the same author.

Get it here.

karakeep-sync

By @sidoshi

Sync links from Hacker News upvotes, Reddit Saves to Karakeep for centralized bookmark management.

Get it here

Home Assistant Integration

By @sli-cka

A custom integration that brings Karakeep data into Home Assistant. It exposes your Karakeep statistics data (like lists, bookmarks, tag, etc.) as Home Assistant entities, enabling dashboards, automations, and notifications based on your Karakeep data.

Get it here

karaclean

By @lmgarret

A Docker sidecar that automatically cleans up Karakeep bookmarks based on declarative YAML rules.

Get it here

Karatui

By @bercribe.

A terminal user interface for Karakeep. Supports keyboard driven tag and list management of bookmarks, with suggestions populated from your server.

Get it here

wdoc

By @thiswillbeyourgithub

Ask questions about your Karakeep bookmarks. wdoc is a Retrieval-Augmented Generation tool (CLI and Python library) that turns your saved content into a searchable, queryable knowledge base, with recently added native Karakeep support on top of 20+ other filetypes.

Get it here.

Quick Capture - Supasend (Quick Capture app for Karakeep)

By @pradeepb28.

Supasend aims to remove the friction between the thought in your brain and the app in which you capture. Think of its like a Quick capture app for your second brain apps including Karakeep. You can capture photos and links in Karakeep from Supasend faster.

Get it here.
Download: Download

KaraClone

By @gowinder.

A from-scratch reimplementation of the Karakeep server API that runs entirely on the Cloudflare Workers free tier (D1, R2, Queues, Workers AI, Cron). It's aimed at people who want to self-host their bookmarks but don't have a VPS or home server: no machine to patch, no container to run, no backups to script.

The official clients (mobile app and browser extension) log in with a server URL + API key, unmodified. Bookmarks are persisted immediately on save; title extraction, AI tagging, and summaries run asynchronously in a background queue.

:::note
This is a server-side implementation that targets the internal tRPC API used by the official clients, which — unlike the public REST API — carries no compatibility guarantees. It tracks specific client versions (currently Mobile 1.11.0 / Extension 1.2.11); clients newer than that may or may not work against it.
:::

Get it here (AGPL-3.0).


Docs 07 Community 02 Community Channels (`docs/docs/07-community/02-community-channels.md`)

Community Channels

Stay connected with the Karakeep team and community for updates, support, and feature discussions.

Discord

  • Join the official server: discord.gg/NrgeYywsFh
  • Great for getting help, sharing setups, and chatting with the team and other users.

Twitter / X

  • Follow @karakeep_app for release announcements, tips, and product news.
  • DM or tag us with feedback or things you'd like to see next.

Docs 08 Development 01 Setup (`docs/docs/08-development/01-setup.md`)

Setup

Quick Start

For the fastest way to get started with development, use the one-command setup script:

bash
./start-dev.sh

This script will automatically:

  • Start Meilisearch in Docker (on port 7700)
  • Start headless Chrome in Docker (on port 9222)
  • Install dependencies with pnpm install if needed
  • Start both the web app and workers in parallel
  • Provide cleanup when you stop with Ctrl+C

Prerequisites:

  • Docker installed and running
  • pnpm installed (see manual setup below for installation instructions)

The script will output the running services:

Press Ctrl+C to stop all services and clean up Docker containers.

Alternatively, you can use Docker Compose to run the full stack in containers — see Docker Compose Details below.

Manual Setup

Karakeep uses node version 24. To install it, you can use nvm [^1]

text
$ nvm install 24

Verify node version using this command:

text
$ node --version
v24.0.0

Karakeep also makes use of corepack[^2]. If you have node installed, then corepack should already be
installed on your machine, and you don't need to do anything. To verify the corepack is installed run:

text
$ command -v corepack
/home/<user>/.nvm/versions/node/v22.14.0/bin/corepack

To enable corepack run the following command:

text
$ corepack enable

Then, from the root of the repository, install the packages and dependencies using:

text
$ pnpm install

Output of a successful pnpm install run should look something like:

text
Scope: all 20 workspace projects
Lockfile is up to date, resolution step is skipped
Packages: +3129
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 0, reused 2699, downloaded 0, added 3129, done

devDependencies:
+ @karakeep/prettier-config 0.1.0 <- tooling/prettier

. prepare$ husky
└─ Done in 45ms
Done in 5.5s

You can now continue with the rest of this documentation.

First Setup

  • You'll need to prepare the environment variables for the dev env.
  • Easiest would be to set it up once in the root of the repo and then symlink it in each app directory (e.g. /apps/web, /apps/workers) and also /packages/db.
  • Start by copying the template by cp .env.sample .env.
  • The most important env variables to set are:
    • DATA_DIR: Where the database and assets will be stored. This is the only required env variable. You can use an absolute path so that all apps point to the same dir.
    • NEXTAUTH_SECRET: Random string used to secure authentication cookies and tokens. Generate one with openssl rand -base64 36. Logging in will not work if this is missing!
    • MEILI_ADDR: If not set, search will be disabled. You can set it to http://127.0.0.1:7700 if you run meilisearch using the command below.
    • OPENAI_API_KEY: If you want to enable auto tag inference in the dev env.
  • run pnpm run db:migrate in the root of the repo to set up the database.

Dependencies

Meilisearch

Meilisearch is the provider for the full text search (and at some point embeddings search too). You can get it running with docker run -p 7700:7700 getmeili/meilisearch:v1.41.0.

Mount persistent volume if you want to keep index data across restarts. You can trigger a re-index for the entire items collection in the admin panel in the web app.

Chrome

The worker app will automatically start headless chrome on startup for crawling pages. You don't need to do anything there.

Web App

  • Run pnpm web in the root of the repo.
  • Go to http://localhost:3000.

NOTE: The web app kinda works without any dependencies. However, search won't work unless meilisearch is running. Also, new items added won't get crawled/indexed unless workers are running.

Workers

  • Run pnpm workers in the root of the repo.

Mobile App (iOS & Android)

Prerequisites

To build and run the mobile app locally, you'll need:

  • For iOS development:

    • macOS
    • Xcode installed from the App Store
    • iOS Simulator (comes with Xcode)
  • For Android development:

    • Android Studio installed
    • Android SDK configured
    • Android Emulator or physical device

For detailed setup instructions, refer to the Expo documentation.

Updating from an Older Version

If you are returning to mobile development after a significant update to the source (e.g. Expo version bump or major dependency changes), the build may fail with stale artifacts in workspace node_modules. Run a clean wipe before reinstalling:

bash
pnpm run clean:workspaces
pnpm install
pnpm --filter @karakeep/mobile clean:prebuild

Then continue with the prebuild and run steps below.

Quick Start

sh
# ios
pnpm ios

# android
pnpm android

More details below if you want to understand what's going on.

Details

The app has three variants: development, preview, and release.

Variant Description Expo Dev Tools Command (iOS) Command (Android)
Development (default) Requires the expo devserver to be running. Uses a separate bundle ID so it can be installed alongside the production app. Yes pnpm ios pnpm android
Preview Standalone app that doesn't require the expo devserver. Uses its own bundle ID. No pnpm --filter @karakeep/mobile ios:preview pnpm --filter @karakeep/mobile android:preview
Release Standalone app using the production bundle ID. Closest to a production build. No pnpm --filter @karakeep/mobile ios:release pnpm --filter @karakeep/mobile android:release

In 90% of the cases, you'll want to use the development variant.

Note: Changing the code will hot reload the app. However, installing new packages requires restarting the expo server.

Browser Extension

  • cd apps/browser-extension
  • pnpm dev
  • This will start the extension dev server on http://localhost:5174 and generate a dist package.
  • Go to chrome://extensions in Chrome or Brave and enable developer mode.
  • Press Load unpacked and point it to the apps/browser-extension/dist directory.
  • The extension will pop up in the extension list.

In dev mode, opening and closing the plugin menu should reload the code.

Docker Compose Details

If you prefer to run the full stack inside Docker, follow these steps:

  1. (Optional) Copy the sample env file whenever you need to override the defaults or commit real secrets:
bash
cp .env.sample .env
  • Even if you skip this step, the compose file injects sensible defaults: DATA_DIR=/data, MEILI_ADDR=http://meilisearch:7700, NEXTAUTH_URL=http://localhost:3000, and NEXTAUTH_SECRET=super-secure-nextauth-secret.
  • When you're ready, set at least NEXTAUTH_SECRET (use openssl rand -base64 36) and any optional keys like OPENAI_API_KEY inside .env so they override the defaults.
  • The stack automatically mounts /data inside the containers, so you only need to change DATA_DIR if you prefer a host path.
  1. Start every dependency, install packages, and run migrations in one go:
bash
docker compose -f docker/docker-compose.dev.yml up
  • The prep service creates DATA_DIR (if missing), runs pnpm install --frozen-lockfile, and then pnpm run db:migrate the first time (and whenever you restart the stack) so the rest of the services always have dependencies ready.
  • The web and workers services run pnpm web and pnpm workers respectively using the same code that lives on your host machine, so hot reload works out of the box.
  1. Tail the dev logs when needed:
bash
docker compose logs -f web workers
  1. Stop everything with docker compose down. Re-run with --build if you change Node dependencies or the Dockerfile.

This setup exposes:

Meilisearch runs as an internal service only (no host port exposed).

docker compose -f docker/docker-compose.dev.yml up starts five services:

  • prep: installs dependencies and runs database migrations before anything else boots.
  • web: runs pnpm web with hot reload enabled (polling watchers are turned on for reliable Mac/Windows file sync).
  • workers: runs pnpm workers so crawlers, importers, and background jobs behave the same way as in local dev.
  • meilisearch: exposes http://localhost:7700 with analytics disabled and persistent data stored in the meilisearch Docker volume.
  • chrome: provides the remote-debuggable Chrome instance required by the workers on http://localhost:9222.

All application containers mount your checkout into /app and share two volumes: node_modules (so dependencies live inside Linux containers) and pnpm-store (to keep the pnpm cache). If you ever need a clean slate you can remove them with:

bash
docker compose -f docker/docker-compose.dev.yml down -v

Every environment value is defined with ${VAR:-default} syntax, so the stack boots even if .env is missing; create the file only when you want to override something like NEXTAUTH_SECRET or MEILI_MASTER_KEY.

You can override the default /data mount by editing DATA_DIR in .env and binding a host directory via a regular Docker volume mapping. Any other environment variable defined in .env is automatically propagated to the Node services.

[^1]: nvm is a node version manager. You can install it following these
instructions
.

[^2]: corepack is an experimental tool to help with managing versions of your
package managers.


Docs 08 Development 02 Directories (`docs/docs/08-development/02-directories.md`)

Directory Structure

Apps

Directory Description
apps/web The main web app
apps/workers The background workers logic
apps/mobile The react native based mobile app
apps/browser-extension The browser extension
apps/landing The landing page of karakeep.app

Shared Packages

Directory Description
packages/db The database schema and migrations
packages/trpc Where most of the business logic lies built as TRPC routes
packages/shared Shared code between the different apps, such as loggers and configs
packages/shared-server Shared server-only services, such as queues and asset storage
packages/plugins Implementations of pluggable services, including filesystem and S3 storage

Toolings

Directory Description
tooling/typescript The shared tsconfigs
tooling/eslint ESlint configs
tooling/prettier Prettier configs
tooling/tailwind Shared tailwind configs

Docs 08 Development 03 Database (`docs/docs/08-development/03-database.md`)

Database Migrations

  • The database schema lives in packages/db/schema.ts.
  • Changing the schema, requires a migration.
  • You can generate the migration by running pnpm run db:generate --name description_of_schema_change in the root dir.
  • You can then apply the migration by running pnpm run db:migrate.

Drizzle Studio

You can start the drizzle studio by running pnpm run db:studio in the root of the repo.


Docs 08 Development 04 Architecture (`docs/docs/08-development/04-architecture.md`)

Architecture

  • Webapp: NextJS based using sqlite for data storage.
  • Workers: Consume the jobs from sqlite based job queue and executes them, there are three job types:
    1. Crawling: Fetches the content of links using a headless chrome browser running in the workers container.
    2. OpenAI: Uses OpenAI APIs to infer the tags of the content.
    3. Indexing: Indexes the content in meilisearch for faster retrieval during search.

Docs Api Add Bookmark To List.Api (`docs/docs/api/add-bookmark-to-list.api.mdx`)


id: add-bookmark-to-list title: "Add a bookmark to a list" sidebar_label: "Add a bookmark to a list" hide_title: true hide_table_of_contents: true api: eJzFVm2LGzcQ/iuD8iUxe/alpDTsh4LTNnBNKEfio5SLwePVrFexVlIk7Z0ds9Af0V/YX1JG+2I7uaYtlPbT+bQzo2eemXlGB2EdeYzKmispcoFSvrB2W6PfLuxrFaLIhKRQeOXYRuRiLiUgrHsjiBYQajQNatAqxCksKhVgjAoqgJJUOxvJRPj9198ApVRmA2gAtSeU+wvnKfDXMWqFAYwFKksq4lRkIuImiPxWMKQglpkIVDRexb3Ibw9iTejJz5tYifx22S4z4dBjTZF8SAahqKhGkR9E3DsSuQjRK7P5LLlFRdAY9aEhBm2iKhV5sCXEirr0RCZoh7XTHEWRknq339T3759/Y3cfv652MdriOQNWMZkw4Csp2kx4+tAoT1Lk0TeUCYM1G+jOIBOKATiMlWizfwnxwOc/Rj30wBeRr49GZ+iX7BGcNYECJ/DV5TP+c477JwuFNWNPnKKFewzcJCS5uwbmITRFQSGUjdb7KcN6dvn087g3BptYWa8+khwjv0j9AdFuKTVkrUJQZpOBMneolczAeqCd4ySZqx5ZYp92ceY0cn5fqsqR3lMEom3bhPQBBrgz+N4xbWMjlLYxn0JA57Qq0jTN3gf7MBC7fk8FT6vzPHtRddwXVtJfN9EcaiwqZeiC5xHXmoC8tx7YPXFdUwi4+VuhqqZG82mg3n8q2rN+uu0AHuMvjz34AzsmAtP9sbIsUK5JSXKj5WLGjRFmh26G2tlAZZgdjs3ZClYLfzdoQeO1yMUBpfQUQjtDp2Z3T0Um7tArhpyI6z93ZSux0VHkoorRhXw2i34/3aLHLZGbonMPTmUfYZjFV709dFg4sRMZe8v17G4+FbORbb6Z80hmPHvJSGT9j5fW18gIf/x5kShWprTszll3kJ5OL6eXJyM+4plfX32Gf/yoAiAE0uVFZUNMBR2Y7TRcAlf6QsULjZF8yk4V1K+B+fUVoNb2PsDeNjzONRrcHIOELA13yIAVPoNKbSqtNhWfYAiU/hoJayy2jQvgvN14rGuMqkAWgnfmnXn0CJguVr9uTPhwrjWQkc4qEwP0LQd4rgWO75CgTCrRat4PbgqygopQkp/CL7aBAg1syPBWI15dnNmW9lB6W5/X957WcHMFjZHkYTJ5SzEqswnwbfJ5RfswmQywr3GjzAg5KcIRc2icsz5C0fhg/cUaGaobPeBOIay6j6tE0kqrWsUVfGjI7+G4ArkYBIMmgzKFbiRxZVeGdvG7PkSpSHeaybSAioCh42W4ZAzJlSwpFlX6zkEYGE1hDivTaL2CO9QNQWn9+R3KSK4RpcBcD0+86GvrE8BGxzBwM+wgWOwdBT4cTkKqxprAGurGyxMBT0rI35kLmEy0MtvJJOUyh5s3r092i4oV2NTnqKHweK9JQk0RJUacdu4s+qN7En/gI1Zo6k1Scw42BhqnLfLGKpUmeKxqbnLr4fr7l0+SgDobYo1Ju/v1+dBDSj/w4jocd8H/9fjqNOhkFbZZJ6OHXolv0zMmiEzk43tmHHE+PXkrLDPBWsJOhwM39Y3XbcvHqW/5BXfU4qTYUgX+LUVeog70BX4ev+lXyxP4M9z9IZp9knzd8H8iE1vaH19j/AL7D289YaddtpnohCfl3hnMi4JcPHE9jb48WY/XNwuRCTxfHp8sixT3QUCHQ2exYHFs2xFfEkuG1rZ/AKDKROU= sidebar_class_name: "put api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Add a bookmark to a list"}

<MethodEndpoint
method={"put"}
path={"/lists/{listId}/bookmarks/{bookmarkId}"}
context={"endpoint"}

Add a bookmark to a manual list. This operation is idempotent — adding an already-present bookmark has no effect.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the bookmark was added to the list successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List or bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Admin Update User.Api (`docs/docs/api/admin-update-user.api.mdx`)


id: admin-update-user title: "Update a user (admin)" sidebar_label: "Update a user (admin)" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "put api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update a user (admin)"}

<MethodEndpoint
method={"put"}
path={"/admin/users/{userId}"}
context={"endpoint"}

Update a user's role, bookmark quota, storage quota, or browser crawling setting. Requires admin role. You cannot update your own user account via this endpoint.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The fields to update. All fields are optional — only provided fields will be changed.","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["user","admin"]},"bookmarkQuota":{"type":"integer","nullable":true,"minimum":0},"storageQuota":{"type":"integer","nullable":true,"minimum":0},"browserCrawlingEnabled":{"type":"boolean","nullable":true}},"description":"User update data","example":{"role":"admin","bookmarkQuota":1000,"storageQuota":5000000000}}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"User updated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the update was successful."}},"required":["success"]}}}},"400":{"description":"Bad request — invalid input data or attempted to update own user.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"403":{"description":"Forbidden — admin access required.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"404":{"description":"User not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Attach Asset To Bookmark.Api (`docs/docs/api/attach-asset-to-bookmark.api.mdx`)


id: attach-asset-to-bookmark title: "Attach asset to a bookmark" sidebar_label: "Attach asset to a bookmark" hide_title: true hide_table_of_contents: true api: eJzdV9uKG0cQ/ZWi/WKLWckODjF6CMg3srFJlr0QwnpBpZkaTVs93ePuHmllMZCPyBfmS0LVXKRdrY0hhEBeFm1PdXXVqepzqnfKVeQxamdPMzVVGCOmxSwEipfupXOrEv1KJSqjkHpdsZ2aqplYAULlaa1dHcwW6so4zCgD5M0QHSAsOgdjuCyo+1DWIcKC9va59iHCWiPEguDs14tLmIhpALJZ5bSNY5WoiMugpteqDyqom0QFSmuv41ZNr3dqQejJz+pYqOn1TXOTqAo9lhTJBzEIaUElqulOxW1FaqpC9Nouj9LjYGurP9UEOiMbda7Jg8slwCEnlSi6xbIy7EmTzsztdlluPr74wd1+/r64jdGlLzhwHcWkD/w0U02iPH2qtadMTaOvKVEWSzZa7I0SpTmYCmOhOBneQSG+dNmWUzgOucX39DWgzYAzlCJIqTjY1NlINvJerCqjU6n65GNgBw+A4xYfKY0qUZXnHomaAn/V2bcBePq6R+yLTTJmIOTXpbg7dku2LrnoRtvVT7E0r7ocEhVST2RD4STCLFedp4vD9QVaS/60xCWpROW1MWe4pJlPC73mlbXOyLFdh7r0vWRMqceNoWxvWwfyV134fNgaI3petyvrNpa78RgEqUJqMASdd4BD7jzEQocBgzvdcM0AH6Jy0zStRaicDW0Nvnv67GstsMHQ1Z0yCHWaUgic/PZfboP/UzWbROXa0C9yLY9TsbUxuOB7zdf320r4/KGqXVmsY+G8/kwZ/PXHn3JjXgqTQXQrsqADlDoEbZcJaLtGo7MEnAe6rfi8ezWNdBsnlUH9cDX3tRio6zAC1Uf6/DjSnr/Augi5q+39o/9JO6UuexDne7oDJaaFtnTiCTPGH8h754G3C5uUFAL3xze4KuoS7X1H3f7jWykB7v3f7Hn9DW8U4OT8WDgW0soFyZLZe6omfU+GyW5P8U2nc3wByK97maq9UVO1wyzzFEIzwUpP1s+4wdFrjlUQ6z63dcqxNlFNVRFjFaaTSfTb8Qo9roiqMVbVgwzdeehp+l1nD20snNGBwl5wIduTD3V2gJlPlovMZixkYsS3UX68db5EjvDn3y4FW26Q872ivenbsWWWfdUOCOWINxqWyNzxJgavzezZ+On46YHsDmnNzk6PYBg+Mh1DIJOfFC5EaYi+TtouRVG5U050PDEYyQtIOiWebHRg34DGuE2AratZd0u0uNw7CQkYHWJIgOeYBAq9LIxeFrzSNkEihywwXdVVgMq7pceyxKhTZOb+YD/YR4+AUeeJpL1mvDgzZpiTAnQtC3iXQyo+IwNtpdLzWXfhxckcCsKM/Bh+dzWkaGFJlmdCArSS2Yq2kHtX3m2TDS3g6hRqm5GH0eiCYtR2GeBH2fOOtmE06sM+w6W2Q8jvdYgHMYe6qpyPkNY+OH+yQA61GnbIaDhvP84FpLnRpY5z+FST38J+yGvHzF4pQdvU1BlxZeeWbuOrzkWuybRcy7CAjoChxaU/ZHDJlcwppoV8ZyccGI1hBnOWgDms0dQkmn7nDG0zrhGJY66HJ7AOSuclwNrE0GMz8Cp3eeDFYcSVaiwInKX2lnpqZ4ow/WBPYDTiGzEaSS4zuDp/P/QbbHQswEmfo4FO/6CkiBlGHLfbWSyG7SIawEvM8NSZSHP2NvZwajcEjzWLMYvR2eu3T4SAmfdKFO7vRtr+sXD8LLh/HXd7NflvnhgtzRxIaJO0bLzriPx6GC6YtKd3pvWOy28SxRTCtrsd9/KVN03Dy9Ku/DTZM7nwfaYD/87UNEcT6CugPD7vFOkJfCncbhHtVgTD1PyfStSKtnefFw2POO3Nlyhag45aT4Rx9w6OpL1J+h2zNKUqftX25kAXGXyZ0dpXTCm6rzxuVCJ/Jdi2b0VsZG2nDNplLcKuWp+sIXhXgu5JjmT1IBy7XWtxydzYNAM6wpUMTNP8Dd4ASw8= sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Attach asset to a bookmark"}

<MethodEndpoint
method={"post"}
path={"/bookmarks/{bookmarkId}/assets"}
context={"endpoint"}

Attach a previously uploaded asset to a bookmark. The asset must be uploaded first via the POST /assets endpoint.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The asset ID and type to attach.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The ID of the previously uploaded asset."},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"],"description":"The type classification for this asset."}},"required":["id","assetType"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"201":{"description":"The asset was attached successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Attach Tags To Bookmark.Api (`docs/docs/api/attach-tags-to-bookmark.api.mdx`)


id: attach-tags-to-bookmark title: "Attach tags to a bookmark" sidebar_label: "Attach tags to a bookmark" hide_title: true hide_table_of_contents: true api: eJzVV9uO2zYQ/ZUB89DE0NqbIkUDPRRwboCbIF0kXhTFZgGPxbHEmCIVkrKtGAb6Ef3Cfkk7lCV7126QFnmpH9YWNTOcy5kzs1thK3IYlDUTKVKBIWBWTDH3U/vM2mWJbikSIclnTlUsJlIxjkJgDYF1UFpHEDD3ECwgzPdaQ2ArkKGBOYGSZIJaKJIwb2DyghUNljSEyQKQ1eMjKA+VsyslSQIaCaGItkFa8ua7ALRRPiSgAqyV1mw5c4SBpetgSwwqQ62boUgEuyTSG9GF4cVtIjxltVOhEenNVswJHblxHQqR3tzubhNRocOSAjkfBXxWUIki3YrQVCRS4YNTJj9JyLQgqI36VB8F6sAuovt9QkQiaINlpdmSIiX1psnL9cenP9rN5x+KTQg2e8qOqxBFOscnUuwS4ehTrRxJkQZXUyI4XSIV84NQIhQ7U2EoBAfDGuTDMysbDuHU5b5osZ5DeMlV5WyXtQ9Q4IqAVCjIAcIsYD6RM65b+/AWS5pxTJk1gUzgK7CqtMoimkYfPd9zJod2/pGyIBJROcZeUOTj21iuXgqdw4ZDClT6r9Jm/N4v1C7C4G1M1Zl3beAknzXnakymLhlAqEQiirpEwwiStMBaB5Huj3b8OS7PTRvKbXfuK2t86+X3l5fnKzF54Tu4tEUpMMCaHEHn4jfMdGfyK7L9X/AeMP/XUJ/G8p0ksvd0n8wnl49P83dtsA6Fderz3+Ty5+9/RCeexdaGYJdkmFRK5b0yeQLKrFArmTCQaVPxTfdSG2gTRpVGdT6pB3j0AR57IDpPn5x62jU0GBtgYWvzLauaWXkG5CfUDSVmhTJ04QglzjUBOWcdsPqQe6Ik7zH/KlOxAe4b2usPxf1iRgcP9m8P1X/Jil0jlRQKy6Oosj5GyXSWilFHdH60PXDebhR7jXndrTrWrp0WqdiilI68342wUqPVY5GIFTrFnrZd0L5uq9S3dAiVT0ej4JrhEh0uiaohVtXZDthb6HD/ei8PrS8cz9HAec9lbG8+Hjt9kvlmjiOKMa9HIZHsf7yyrkT28OdfpzGzDI93B4J/2YGxI9KbnhMP9eup8HB0zIAdod3ueJIsLBvjpLYRPx5eDi+PWrYPd3w1OUlP/1J5QPCkFxeF9SHCpKueMnkc8YyfCxUuNAZyMXkqoyFMC+XZNqDWdu2hsTXPqhIN5gcjPgGtfPBJ5M0ECpUXWuUFn6D3FL+NhDlmy7qKy0XusDwsCh/MB/PgAXA1mMja5uPDsdZARlZWmeBhD2TAu8xS8R0SlIkImI33NBCNzKAglOSG8Jut4x6Uk+FdiwBNjGxJDSycLe/CZ01zuJ5AbSQ5GAzeUwjK5B5+ijqvqfGDQef2FebK9C6/UT4c+ezrqrIuQFY7b93FHNnVqteAlUKYtS9nMUkzrUoVZvCpJtfAYRfiYhB0kwyUyXQtiSs7M7QJz/cmFop0y8CcFt7R0Ld56S7pTXIlFxR43SgI2Ag7RkMYw8zUWs9ghbomWFh39w5lJNeIomGuhyMwtt1BHflaB9/lpmfbaVOR58N+E+y20rjBcvc6IuBG9OkHcwGDgVZmORjEWMZw/e5NjzdYq1CAjThHDZnDtSYJJQWUGHDYqvMI6dXjKAE+Yt6nvUgEZydjoK60RV56F0oTPFQlg9w6uHrx6lGkZWZD7s50221++y38dPO+343bw4j5v6zuLSceTeJd0tL6dj8PbvrFl9k/vbMFt+tXIphxWHK7ZehfO73b8XFENy/8h4EQ6VIqz7+lSBeoPX0hiQ/f7cfaI/gnZ7u9yjRx7uian0QiltTcXdoj27ZEEb1oBZ63d10wdI8MnOwHu6TTGGcZVeGLsrdHw/Xql/dTHi77/w3KuDwIh2uRxL/R2RbmcWbFs63QaPI6bgeitcmjCO9OsnuTqx1F59Kx3bYSU6bS3a7PTqRWTsxu9xcThBgt sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Attach tags to a bookmark"}

<MethodEndpoint
method={"post"}
path={"/bookmarks/{bookmarkId}/tags"}
context={"endpoint"}

Attach one or more tags to a bookmark. Tags can be identified by ID or name. If a tag name is provided and the tag doesn't exist, it will be created automatically.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The tags to attach. Each tag must have either a tagId or a tagName.","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"object","properties":{"tagId":{"type":"string"},"tagName":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"],"default":"human"}}}}},"required":["tags"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The IDs of the tags that were attached.","content":{"application/json":{"schema":{"type":"object","properties":{"attached":{"type":"array","items":{"type":"string","description":"The unique identifier of the tag.","example":"ieidlxygmwj87oxz5hxttoc8","title":"TagId"}}},"required":["attached"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Check Bookmark Url.Api (`docs/docs/api/check-bookmark-url.api.mdx`)


id: check-bookmark-url title: "Check if a URL exists in bookmarks" sidebar_label: "Check if a URL exists in bookmarks" hide_title: true hide_table_of_contents: true api: eJzVVtuOGzcM/RVCeUmMWXtT9GkeAjhJU2wToEGyi6LYLGB6RM8o1kiKqNldxzDQj+gX9ksKai7rvfSh6FOfPNaFPDwkD7VXPlDEZLw706pUVUPV9rX32xbj9iJaVShNXEUT5Igq1Rs5AGYDCBefPoBhQBsJ9Q7Wwy3Sc7hgYuBuzSkaV0OLqWrkI3nYGKehQqeNxkRcQGrIgfOxRWu+E4tZhuemdj7fbZAb2ESsW3KJAZ2GFNFY2WOL3BC/gI2PQLdYJah8GzAa9m6uCpWwZlVeqjEiVleFYqq6aNJOlZd7tSaMFJddalR5eXW4KlTAiC0lipwPcNVQi6rcq7QLpErVx/SImPOGMiPJQyYRsEbjOAHdGk6CdiSI5+pQqEjfOhNJqzLFjv6TtUI5bAValxNmxMC3juJOSTyROHjHxBLDD6en8nPf2a/rr1QlME6bCrPxm4ZSQ1FyM6b5OL2r8c+ZXsneynXWrqQqnE+w8Z3TgqryLpFL4hBDsNm4d4uvLF6fYNZnHKpQIUpVJtNjvnP2VBbENa4t/TOPZ2/Bb3Ioj8grwEcQC4L9KFgJ4yhgdbiXsMtjSFeHg+z+ePryMbEXDrvU+Gi+k4a//vgzu3idKw6S35ITX61hNq4uwLhrtEZnTHQbxNcDFhPdpkWwaJ7mb+KEbrENQsk9BOrQQ20pNV6avaZMNkrtq8VUUItccSd9MTHF67EVZKVUe9Q6EvNhgcEsrl+qQl1jNJKDnK5hu2djg51NqlRNSoHLxSLF3XyLEbdEYY4hPNlGg4Uxa++H89BjkTCOuvizsDAUylEvT6SIZ4kjH1PlcEgVw8c7ER5B+Mtv5znNxm28XJeoe0gv56fzUxETkzKnE57lx7NH+KdNUUZgspuTxnMSdqaKkgoUHRPdPDHpxGKimKMzFc3hvDEstgGt9TcMO9+JDrTosL4zwgVYw0kEFGsuoDF1Y03dyAoyU/51GtZYbbvAEKKvI7YtJlOhtbv5F/fFPXsGQhe5NDSnLC6tBXI6eCOCO5Q94P3CDeJDg3E5RavlUGXZyAoaQk1xDr/7TrQeanIyZQjQ5ci2tINN9O39/N7QGi7OoHOaIsxmnylJszK8ynfe045nsxH2R6yNmyB/MCKNE2buQvAxQdVF9vFkjQI1TDfg2iCs+s1VJmllTWvSCrJqwt0EkGQQjAoKxlW20ySZXTm6TW8GExtDtm9woQVMAuSel9HJZDKPQEpVk/fFiACjOSxHFb1G21GeaPd8DOpM2bDkIxI4D62PGWBnE4/cjNMOzneBWBan+ZezsSbwjvr2ikQgncLlF3cCs5k1bjub5ViWWQ3HeoMbkxrwuc7RQhXxxpKGlhJqTDjvr4tCTdezUoEsiaDScCQX53jGQResR00aNsYSPDetFLmP8PHtuxd5UAbPqcWseMOYe/AGyarOUopTbzxsy/2div7fXjC9ih0p/6HohXg/KPfdNJKw77T7qlCiPHJgv5cWuIj2cJDl/m0giq4NizJpVW7Q8sPpecza80/D+HsB//Jt8mQEW9pN75Vc8KpU+bUyjpL8GitULyQZa39lWVUU0tGtRy8LsTKNuJ9/OleFwvsj4cEIyNaHLXS7I9v7fX/iXCTvcFAj7iyB6iCj/2/jS/aa sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Check if a URL exists in bookmarks"}

<MethodEndpoint
method={"get"}
path={"/bookmarks/check-url"}
context={"endpoint"}

Check if a URL is already bookmarked. Uses substring matching to find candidates, then normalizes URLs (ignoring hash fragments and trailing slashes) for exact comparison.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Object indicating whether the URL is bookmarked. bookmarkId is null if not found.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string","nullable":true,"description":"The ID of the existing bookmark, or null if the URL is not bookmarked."}},"required":["bookmarkId"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Create Backup.Api (`docs/docs/api/create-backup.api.mdx`)


id: create-backup title: "Trigger a new backup" sidebar_label: "Trigger a new backup" hide_title: true hide_table_of_contents: true api: eJzFVsGO2zYQ/ZUBc0hraO2k6EmHAt60KbZJ0UXjRVFsFvBYHEuMKVLhkLvrGAL6Ef3CfkkxlOy1Nz701pMEznD4ZubNI3fKdxQwGu+utCpVFQgjXWK1SZ0qlCaugunErEq1CKauKQCCowdYJ2sBq8onF2GVd0xh0dD4D4ZhiKYBeeuqJnjnE9st/PPX35CY4OefFjAbvHm2G36udA/RQ9VQtQETGThiTDxVhYpYsypv1YCO1V2hmKoUTNyq8nanVoSBwjzFRpW3d/1doQJx5x0Tq3Knvnv1Wj6nKQ2xBqDGO3hAhjikSfokHb/6RFWUrALFFBxpeDCxAYSXHTltXP3yCGvlXSQX5UDsOmuqHH72ieXUneKqoRblL247UqUaoqtCdUEaEs2A2egjH47BuFr1hUpM4eq8CZkpnrMVyiVrcWVJlTEk6oux2Xoez0Zi84WODC61KwpiWHm/aTFs3kjnz3oMdTiHgVxqpYdjyVShOFUVMatCrdHYFEjd9YWiEHz4lZixpv+QSy+9/pxMIC3RjVaHIj2V5DjhMb3nyRyg3/W9BP3+HGduHKbY+GC+kM5cjg3BZSYfRL8hJyRpDbNxdQHG3aM1ugAfgB47gfiMIJEe46yzaM5T46l2j9h2kvIJAtUPUFuKjZcR7jxnIqHMgdrPl6RG4Z4C51lJwapS7VDrQMz9DDszu3+tCnWPwUhhc/dG81CCNSYbVamaGDsuZ7MYttMNBtwQdVPszshFQzBGAL/OVXo3+sOARbAfTfEHSX04+XiWD5WQkyWP7KbK0UmamH/e+tCiIPzlj4WSkhi39rJdsh4gvZ6+mr4SKTExF/KAZ3599RX+g9EwIDDZ9UXjOUp1YE8b42pApyEQ6gsTLyxGCjk7U5Hoh2GJDWitf2DY+iTq1qLD+ikIF2ANRy5AJK6AxtSNNXUjK5m88nV6VCKGLvg6YNtiNBVau51+dB/dixcg5SIXR7GRxbm1QE533rgowpVHBPCUrZ2cocG43KLlfKRWDrKEhlBTmMKfPkGFDmpycmEQoMuZbWgL6+Db0/4+0ApuriA5TQEmkw8Uo3E1ww95zzva8mSyh32NtXEHyO8NxyPMnLrOhwhVCuzDxQoFanfYAfcGYTkYl7lIS2taE5fwOVHYQocBW4oUeBDz/Y0AxlU2aZLOLh09xjdjiLUhO0y1lAVMBLkRpC77Qw4hpZNrilWT7RJEgNEU5rAUfVrCPdpEsPbh9AzjtPSIcmDpRyBwHlofMsBkI+9rczlSBBbbjlgW9yucu7Ei8I6G8QpEIJPC5Ud3AZOJNW4zmeRc5nDz+/sD34aLy2eeo4Uq4IMlDS1F1BhxOmwXWTpsz/IEsgTORxpdMjn3Pg5SZz1q0rA2luAb0wrJfYDrH99+O5V7QaSpxSxzDvMInz4pVmffHbsnsfzfnyCDEB0pttzGoqW7UXBv1erpeSJyIUu7nfD2Jti+l+VMTXmjPMltfrEUahi2rNAb2qpSzauKuph12SY5+qvXhAjoQfuvf/uwkBvvVDef6WQOP5rQbY+C73aDx0J0oe9VMaLIOqF6uRT/Bbudlic= sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Trigger a new backup"}

<MethodEndpoint
method={"post"}
path={"/backups"}
context={"endpoint"}

Trigger a new full account backup. The backup is created asynchronously — use GET /backups/{backupId} to check its status.

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"201":{"description":"Backup creation was triggered. The backup object is returned with a 'pending' status.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"assetId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"size":{"type":"number"},"bookmarkCount":{"type":"number"},"status":{"type":"string","enum":["pending","success","failure"]},"errorMessage":{"type":"string","nullable":true}},"required":["id","userId","assetId","createdAt","size","bookmarkCount","status"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Create Bookmark.Api (`docs/docs/api/create-bookmark.api.mdx`)


id: create-bookmark title: "Create a new bookmark" sidebar_label: "Create a new bookmark" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Create a new bookmark"}

<MethodEndpoint
method={"post"}
path={"/bookmarks"}
context={"endpoint"}

Create a new bookmark. The bookmark type (link, text, or asset) is determined by the type field in the request body. For link bookmarks, if the URL already exists, the existing bookmark is returned with a 200 status.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The bookmark to create.","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"title":{"type":"string","nullable":true,"maxLength":1000},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"note":{"type":"string"},"summary":{"type":"string"},"createdAt":{"type":"string","nullable":true},"crawlPriority":{"type":"string","enum":["low","normal"]},"importSessionId":{"type":"string"},"source":{"type":"string","enum":["api","web","cli","mobile","extension","singlefile","rss","import"]}}},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string","format":"uri"},"precrawledArchiveId":{"type":"string"}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string"},"sourceUrl":{"type":"string"}},"required":["type","assetType","assetId"]}]}]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A bookmark with this URL already exists. The existing bookmark is returned.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}}}},"201":{"description":"The bookmark was created successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}}}},"400":{"description":"Bad request — invalid input data.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Create Highlight.Api (`docs/docs/api/create-highlight.api.mdx`)


id: create-highlight title: "Create a new highlight" sidebar_label: "Create a new highlight" hide_title: true hide_table_of_contents: true api: eJztV9tuGzcQ/ZUB89BWWF1S5GkfCig31E2AGImNonAMaLQ70jLikgzJta0KC/Qj+oX9kna4V9lKkAc/FEXfFkty5syZ4ZnhQRhLDoM0+iwXqcgcYaCf5bZQclsEkYicfOak5R0iFS/iOiBouoVAdwGKbi8YDQhrY3Ylut0MeiMe0BHktJGacljvISvQYRbIgdlsPAUPtzIUUkMoqDfwnYfM6EA6AOocfGWtcQEyo4yDzORSb2ciEQG3XqRXYvAmrhPhKaucDHuRXh3EmtCRW1ahEOnVdX2dCEefK/Lhucn3Ij3cC/GioFFQwUDDSQJSZ6piv0c44exl0jDRBpNEvCaaQ9UAnmsTiOG2IbFXtFbJLFI//+TZ9UH4rKAS+SvsLYlUmPUnyjgN1nGigiTPq51zzlm/1wcn9VbUifABXXgX4YzWdVWuyfE66fwrqxHxQ7t8rCqZ6z0pZW4F85iLRGwdkRaJWKuKmPycNlipINJuY50IJuiUSV0phWtFIg2uojoRTNQ3bKybJEpGkF6N+TiOfhxri6L1cV3XjRVvjfYNrT8unp6uh6YE8qEu/s/l4+UyEfJ06JUn9wVW2oQsTwB5hNqIiHr/Y2/XiQgyMPRBcURTSc8Wi4fF8xxzaNUG/vrjT5D6BpXMe+EzDkrpPYtKhxk2klTuH7HCMpOfzMMx1CWUmBVS09QR5pwfIOcasaUZk16S97j9JlNFVaK+b6g9P3uQoghwsD8i+RUf7Ak+cTsvNVahME7+/k9vYYZZm59HxYdgdqRB+o7ipKM/Yd7pzrL/ezxzGcytQnma4eH+3GFpI8Qxgh7psxOl0DUMbQJsTKUHvN5SJjeSu2NfrJAb8nEv3Un/mILznyiH6D8UhocWa3yMErnDi3kxjAI8Cbgbcj4OApVTIhUHzHNH3tdztHJ+81Qk4gadZGCRnna5SWCnfkUI1qfzeXD72Q4d7ojsDK19ECt3i9YCmE3M7pt2PzRYGP5oRPnAWWs7wWhQ6TllzxxH3CbSdhNLdPx4bVyJjPCXXy8ikVwN74f55lVXp8eNZkjVUX9ZHPWTRd8/hjbRiP9Iy6PGj5RZ6o1hb8x6Q8nT2WK2EEMSez6W52cP+OsXpQcET2ozLYwPsWy6AFgtecbieprKMFXIsySzKzOawUUhPdsGZMwe9qbiMa5EjdvBiE9ASc/jGo+QydDaeYDzwyC3xmxXWQ/Wma3DssQgM1RqP/uoP+onT4DTRTq0l5F/LpUC0rk1UgffyTrgsSpZ9pFDO/Sulq2ERCMrKAhzcjP4zVSQoYYtaZ7SCVDHyHa0h40z5XF93dIaLs+g0jk5mEw+UAhSbz38FM+8ob2fTDrY57iVuof8VvowwtwP25Xzxk3XyFBtfwJuJMKqWVxFklZKljKs4HNFbg8WHZYUyHlOBkE3Y7UTNHFmV5ruwovWROx4UQ2ZFpAB0De8dE56k5zJDYWsiOtshIHRDJaw4rliBTeoKoKNccc+pM45RxQNcz4cgTZQGhcBVir4jpteqS/2ljz/7P74mI01gdHUXG9HBHxTffpRT2EyUVLvJpMYyxIu378d3gn8xhk9CxzeKsqhpIA5Bpw1x/l69cdjG2reFvH90GyJxdnt0VBZZTCPY4Mi+F6WXOTGwfnL1z9EmWZ1LDF2CI1RQo4eccWX3nqHod/8C599jTiOujXPi6zvh7YPXIni6EnIKsJ/Dwcu50un6pp/x4rld+HQBeIrMRHNHYyNY0d7JqHBNeWqiE2DZ+T0YSuuk+7EMsvIhq/uvR71sfN3Hy5Y2NtnaRn7tHAYx3O8FakQiWgqKPaL+O8gFOptFRuxaGxyG8DjLnKva8So2iXU+xHCw6HZccEqVdciaUOJqiVqfjX9DdD6rAk= sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Create a new highlight"}

<MethodEndpoint
method={"post"}
path={"/highlights"}
context={"endpoint"}

Create a new text highlight on a bookmark. Highlights are defined by character offsets within the bookmark's content and support color coding.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The highlight to create, including the bookmark ID, text offsets, and optional color/note.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true}},"required":["bookmarkId","startOffset","endOffset","text","note"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"201":{"description":"The created highlight.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}}}},"400":{"description":"Bad request — invalid offsets or missing required fields.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found — the specified bookmarkId does not exist.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Create List.Api (`docs/docs/api/create-list.api.mdx`)


id: create-list title: "Create a new list" sidebar_label: "Create a new list" hide_title: true hide_table_of_contents: true api: eJzNV19vGzcM/yqE+pIal4szbC9+GOBkLdC1wII2wTCkBkzf0T7VOkmVdHE844B9iH3CfZKBuj8+O266AR2wl8QnkRT5I/UjtRPGksMgjX6Ti4nIHGGgd9IHkYicfOak5U0xEddxCxA0bWBhzLpEtwYlfUiBFTxkqGFBUKKuUMFZJ+MBHQHmOeVAj1bJTAa1fQnGgS/RhWPJEkNWUA5YBVNikBkqtYXFFhA8ocsK+FyR275MRSICrryY3IvogJglwlNWORm2YnK/EwtCR25ahUJM7mf1LBGOPlfkw5XJt2KyO4rwtqAYDwQDDRApvO695B2fAMI8Hj+HpSSVg/TARqWjvJFuw2/FO+Gy8gG0CQyQp8C+Z0YH0oH9QMuwxDRcfPLszE74rKAS+VfYWhITYRafKOO8WMdJC5I872osaSDlg5N6JRJRSv2O9Ipjv0xEiY/913hcHyX3We3xgfYPUVtmp9TqpF14ao90VXKiGnREIiKonLGcllipICbdXp2ICNrXgqoTYdGRDly5T0V1pRQuFIlJcBXVdZN8zhP7EVFr45jVdbPtrdG+QfW78eXpAmkKI28K/9tlUZ6IoU6+kNyvp+8o+GcS9i8g/M+z++Q8Wy2UzAaiC2MUoWYrBfprw/LGYTDOn5aqPLn3Rj3rtdlocvydy2D4x4OkTVxpz58dV4/MRXJQQgMce60TLg78mSUiyMCORfISTQ1+Px4/LbsrzKElLvjrjz9B6gdUMgepbRUgx4BwRukqTQZMBaX0XupVw5UJHBITbGQoAAdE+o3KODP5SagPA5pCiVkhNZ07wpwzDuScccDqKaetJO9x9Y9MFVWJ+thQq5+K48xFB/f2B1l4xYp9Gk7c/juNVSiMk79THvMQCoKr2GIgmDVp7gUt7EmXpIg8PdrYHw5xDvQYLqxCeRrhfZk+Ymmji0MPoqcRqVAYbt3WxKZtkclRXMT+wzeR3APx7bjficopMRE7zHNH3tcXaOXFwyUXPDrJ6MUcttsNAN3tLUKwfnJxEdw2XaPDNZFN0donCWGObC2AWUaM3rby0PjCng869QcOvDl52K97HPhkjiOK8eWOQiJpf7w2rkT28Odfb2O2uWTf79v8qw69rlN+qZL65YYq99+tHz23tfS1F9hT6IBXpV4aPpTBbw64TMfpWOwLrodlevPmiTf9pvRx7lHL88L4EEu8G5f4eqNmbsD8XIZzhYFcBFlmlMJtIT3bBlTKbDxsTcWTTYkaV3sjPulGFZ6lEijkqlByVcRZx3uK/3UOC8zWlfVgnVk5LPvBLP2oP+oXL4CzRjq0xMGLU6WAdG6N1KEfkgAPr4zlM5jKYqXMp219RyNzKAhzcin8Zqo4Xa5I87RKgDpGtqYtLJ0pD8tsQwu4ewOVzsnBaPSBQpB65eHHqPOWtn406ty+wZXUvcvMxAOffWWtcQGyynnjzhfIrtpeAx4kwrzZnEeQ5kqWMswbXgWLDksK5Dwng6AbMEDqTFU5cWbnmh7DdWuimSiZWhgWkAHQN7h0h/QmOZNLClkR99kIO0YpTGHObXQOD6gqgqVxh2dInXOOKBrmfDgCbaA0LjpYqeA7bK66If92a8nz4lU/qLezvtHU3HJHBHxR/OSjPofRSEm9Ho1iLFO4e/9u/2KIrcfEOkcFmcONohxKCsidLG3UmRt79ciRwEs8QVMrEouzk9FQWWWQnxhLqQjOZMlFbhzc/PT6ZWwpzI8l6gERHLxo1Ik3z25P1//T509DTYNOwiMPs/yubQT3QnVPI+YPXtjtuJDvnKprXm7p7H62bwPxtZSI5vbFzrEmZrzrBo1zrofYNVTFxz8ZGOqk05hmGdnwrOxs0MNufvlwy8zePs/KOE0IhxuRxL8TIRLR1E5sGHFtJxTqVRXHBdHY5D6Ah23kqG3EqNot1NuBh7tdI3HL/FTXImlDiXwlan4s/A0IJEx+ sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Create a new list"}

<MethodEndpoint
method={"post"}
path={"/lists"}
context={"endpoint"}

Create a new bookmark list. Lists can be manual (bookmarks are added explicitly) or smart (bookmarks are matched automatically by a search query).

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The list to create. For smart lists, a query field is required. For manual lists, query must not be set.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","minLength":0,"maxLength":500},"icon":{"type":"string"},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","minLength":1},"parentId":{"type":"string","nullable":true}},"required":["name","icon"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"201":{"description":"The created list.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","nullable":true},"public":{"type":"boolean"},"hasCollaborators":{"type":"boolean"},"userRole":{"type":"string","enum":["owner","editor","viewer","public"]}},"required":["id","name","icon","parentId","public","hasCollaborators","userRole"],"title":"List"}}}},"400":{"description":"Bad request — invalid input data (e.g., smart list missing query, or manual list with a query).","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Create Tag.Api (`docs/docs/api/create-tag.api.mdx`)


id: create-tag title: "Create a new tag" sidebar_label: "Create a new tag" hide_title: true hide_table_of_contents: true api: eJy9VlFvGzcM/iuE+rDWuNjtsKd7GOB2K9C1wILVwTCkAUyf6DvVOkmVeE5uxgH7EfuF+yUDdWfHSYNhD8NeYoeiyI/kx08+KB8oIhvv3mlVqioSMq2wVoXSlKpogpypUr3JJ4Dg6BYY6zmssAaHLSXASOB8bNGa30nDc46mbUkDOg2Vd3uKTBrYAzcEXaL4TYIQaUsxih1rSNxbejFXhWKskyqv1Uo+bwqVqOqi4V6V1we1IYwUlx03qry+GW4KFelLR4lfe92r8vAI86qhHF1QSvqxOslSecfkWK5gCNZUuQWLz0nuHVSqGmpRvnEfSJXKbz5TxapQIUrD2FCSUwl85pU4GlerYRhxmUhaSsleN8Mw2lPwLo3Xv3356mnQI9Dcmv8QrdFPYC3+ZRFGq+JBJd89Bf7KYceNj5kHf/3xZ5746zw1YL8jByZBa1Iyri7AuD1aowvwEeguSKpH5TLd8SJYNE8XOmEtFN1hGyw9QqCGEWpL3Hihd/AptwWFQGqRuSYUi3uKKTOsi1aV6oBaR0ppWGAwi/0rVag9RoMbO3ZyOh7r32JnWZWqYQ6pXCw49vMdRtwRhTmG8NUqyYSnCOC3uUXvJ38YsQjwM+5/lLrHzOcbcGqDZJY6spsqJydVTF/eymoKwp9+XeW5CnF+uV+cH4/NOxL6jBzGbb0cSING9K/mL+cvZVEN54afoC8v331V6unQJEBIZLcXjU8sjYSN97sW4864OitFJNQXhi8sMsXcCFPRHFaNSRIb0Fp/m6D3nexyiw7r+yCpAGsSp0J2JhXQmLqxpm7EgilR/nQaNljtuiDy4+uIbYtsKrS2n39yn9yzZyCdJcfTiolxaS2Q08EbxwmmlQB8yOogOTQYl6e5Xk4UzEHW0BBqinP4zXdQoYOanIguAbpc2Y562EbfPqTCLW3g6h10TlOE2ewjMRtXJ/g+33lPfZrNjrAvsTbuBPmDSXyGOXUh+MhQdTH5eLFBgRpON2BvENbj4To3aW1Na3gNXzqKPQSM2BJTTDIMgqOEgXGV7bToP6wd3fGbKcTWkB23X9oChgHT2JdjklNImeSWuGryuQQRYDSHJaxdZ+0a9mg7gq2PD3MYp2VGlAPLPPITBK2PGWBnOR1783qiCKz6QEmMR0vK09gQeEfjJkYikKVK5Sd3AbOZNW43m+ValnD1y4cT3+DWcAM+8xwtVBFvLWloiVEj43y8LvJ1up5lDMQEzjNNLpmcRx8HXbAeNWnYGkvw3LRCch/h8oe3L+aykCJhLbqzZX38Mj9ewsO9oP5/r/goTGfyPRSjth4m9b0eX/qbQokgyP+HgzDzKtphEHMmnzzz99qbH/1CjeuU5XpHvVQ11nchA85SbTvJ/tVbORTHG8uqosD/6Htz9m5c/vxxJXI6/cpovZY7EW9Vkf+WShVqJENW6Ww7KIuu7rAW3zGmiC8+1O5HWp2rmo7Q9WcID4fRYyWCMwyqmErJAqQGeZX/Bt1jblI= sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Create a new tag"}

<MethodEndpoint
method={"post"}
path={"/tags"}
context={"endpoint"}

Create a new tag. Tag names are normalized (trimmed and converted to the user's preferred tag style).

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The tag name to create.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"201":{"description":"The created tag.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Delete Backup.Api (`docs/docs/api/delete-backup.api.mdx`)


id: delete-backup title: "Delete a backup" sidebar_label: "Delete a backup" hide_title: true hide_table_of_contents: true api: eJylVttuGzcQ/ZUB85IIa8kuUiTYhwJK4wBugsJIbBSFI0Cj5Ug7FpfckFxZirBAP6Jf2C8phru62WlaoE9akTPDM5dzyK1yNXmM7OyVVrnSZCjSGyyWTa0ypSkUnmvZVrm6Jl+hJRvNBjpDQJglW0CrgWMADMEVjJE0oC9KXhHM2dBQZSriIqj8TnXRg5pkKlDReI4bld9t1YzQkx83sVT53aSdZKpGjxVF8iEZhKKkClW+VXFTk8pViJ7t4gnOm5KgsfylIWBNNvKcyYObQyypxyt4aI1VbSQOE2uz3iyqh/vXr9z664/lOkZXvBbQHJNJB/pKqzZTnr407EmrPPqGMmWxEpPZziRTLDBqjKWSNDyF2tlAQaD/cP5Sfk4R/+qgcDaSjfDXH38e4YQHDH2tNYSmKCiEeWPMZihAXp5fPI11a7GJpfP8lfQ+2ptUW4huSRY4QMUhsF1kwHaFhnUGzgOta0lLatOjSbWmdRzVBiWn7/XgUM5jBKpt24T0G1l3NQXrIsxdYx8fjHVtuEizOboP7tvHu9k9FVFlqvYyyZG7KhdO078PyhgqLEq2dOYJNc4MAXnvPIh7qnBFIeDiP4Uqmwrt40C9/1C1J3Nz1wE8xJ8cJu1SHFPZ0vmxdAdiSp4yVbkadfMRRtvd2LVK+ORXO7Y03qhcbVFrTyG0I6x5tLpQmVqhZ4GYCtVvd82ZY2OiylUZYx3y0Sj6zXCJHpdE9RDrp4ogTOsj7Pj1vreHDoskckT0T9K/7uRjuu+rKydLHslMOJWMVNZ/vHO+QkH4y283qaRs507cJesO0sXwfHh+RNw9nvH11RP8+00OgBDIzM9KF2Jq4My5ZYV+yXaR1E06e8bxzGAkn7LjgoZwU3KQ2IDGuIcAG9dAdFChxcUhSMjAcIghA1HBDEpelIYXpaxgCJR+re5ZH6D2buGxqjBygUL3z/azffYMpFyiaB0tZHFsDJDVtWMbA/QjBnjK+FrO0MA2tWg67umZgkyhJNTkh/C7a6BACwuycicQoE2ZLWkDc++q0/4+0Axur6CxmjwMBp8oRraLAD8ln/e0CYPBDvY1LtjuIX/gEI8wh6aunY9QND44fzZDgVrvPWDFCNNuc5qKNDVccZzCl4b8Bg6XhDSDYKe2wLYwjSbp7NTSOv7ch5gzmU4ZpSzAETB0ddkdsg8pnZxTLMq0L0EEGA1hDFPbGDOFFZqGYO786RlstfSIUmDphyewDirnE8DGxLCrzZt+ROBmU1OQxd1KSN2YEThLHb08EQhTQv7ZnsFgYNguB4OUyxhuP37Yzxs8cCzBpTlHA4XHB0MaKoqoMeKwcxdp37sniQdZEkWm3iQN587GQlMbh5p0utThOVcy5M7D9dt3L5Jg1i7ECpNW99fi29OXwmMObg+S/78fGJ2GHF1YbdbJ4LaXzbv+kg4qU/n+vp5kSlgv29utjN+tN20ry2nC5DVyUM2krZqDfGuVz9EE+k5Kzz/2ov8C/glhv4h2k8TZNPJPZWpJm+NXRTtpM9VRNWHotsdFQXU8cjyOPTm6QN5efri8uVSZwlPFfaSwKfQ3EW23ncWNKErb7gEmhRF0bfs3Y8WbRQ== sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a backup"}

<MethodEndpoint
method={"delete"}
path={"/backups/{backupId}"}
context={"endpoint"}

Permanently delete a backup and its associated archive file.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the backup was deleted successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Backup not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Delete Bookmark.Api (`docs/docs/api/delete-bookmark.api.mdx`)


id: delete-bookmark title: "Delete a bookmark" sidebar_label: "Delete a bookmark" hide_title: true hide_table_of_contents: true api: eJy1Vt1u2zYUfpUD9qY1FDsdOqzQxQB3TYGsxRC0CYYhNeBj8chiTZEsSSVWDQF7iD3hnmQ4lCzbadrtZleWyfPznb/vcCesI49RWXMpRS4kaYr0ytpNjX4jMiEpFF45FhC5uCJfoyETdQu9KCCsBmlAIwG1BhUDYAi2UBhJgsSI8DTiOmRQqXWl1bqKIWMRiuHZVGSCL0V+K/aOg1hkIlDReBVbkd/uxIrQk583sRL57aJbZMKhx5oi+ZAEQlFRjSLfidg6ErkI0Suz/iqE64qgMepzQ6AkmahKRR5sCbGiMRTGRFusnWZLipTU23Zd3396+ZPdfvmx2sZoi5cMXMUksgd+KUWXCU+fG+VJijz6hjJhsGah1UEoE4rBOIyV4GA8BWdNoMAB/HD+gn9Ocf9mobAmkonw959/naCFewxDOSSEpigohLLRup0ymBfnz7+2dmOwiZX16gvJ0d6rlGOIdkMGVIBahaDMOgNl7lArmYH1QFvHoXGGBjwp57SNM6eRo/peLQ5JPUYguq5LSB+Je59ZMDZCaRvz0DU6p1WRWnj2KdjHAdjVJyqiyITz3PBR9ZkurKR/b5k51FhUytCZJ5S40gTkvfXA6inHNYWA6/9kqmpqNA8NDfpT0Z10z20P8GB/cei4C1ZMiUv+Y2UP88txcmflYrbvkTDbHdqvEzxd/m4/O43XIhc7lNJTCN0MnZrdPReZuEOvGGZK1nDdl6jERkeRiypGF/LZLPp2ukGPGyI3RecenbvBwn7a3g7y0GPhYI7G/gPXsPd8PPxjhtkzx5HEeLqSkMiGjzfW18gIf/39OqVVmdKyOkfdQ3o+PZ+eHw3xiGd+dfkV/vFSBUAIpMuzyoaYirjPrDLrRIJc3TMVzzRG8ik6VdAUrisV2DaTpL0P0NoGooUaDa4PRkIGWgUmyG9RZpacrLDYNC6A83btsa4xqgJ56D+aj+bJE+B0Mb/1o8GHc62BjHRWmRhgaDPA07l37EOCMqlEy/kwpMnIEipCSX4Kf9gGCjSwJsPrgwBNimxDLZTe1qf1vacV3FxCYyR5mEw+UIzKrAP8nHTeUhsmkz3sK1wrM0J+p0I8whwa56yPUDQ+WH+2QobqRg24UwjL/nKZkrTUqlZxCZ8b8i0cVgYXg2DPuqBMoRtJXNmloW38ZTBRKtI9P3JaQEXA0Odl72Q0yZUsKRZVumcjDIymMIelabRewh3qhqC0/tSHMpJrRMkw18MTGAu19Qlgo2PY52bkwuvWUeDDcWGmaqwIrKF+vDwR8KSE/KM5g8lEK7OZTFIsc7h5/+5oe6hYgU19jhoKj/eaJNQUkTf3tFdngh/VE9EDHzEr0yCSmnMvY6Bx2qIkCaXSBE9VzU1uPVy9fvMskaazIdaY+HpYkK8fPikeTuHuQPz/31ukp5ejjdZlPUPuBla9HTd5EJnIj9b6IhNMCiyy23F33njddXycGpCfLgdSTdQrVeBvKfISdaDvxPv0/bAXnsG3UA6HaNrE3brhfyITG2pPnx/dostEP8sJRS8wLwpy8Uj12PriaMu8vnh3cX0hMoGnlPyAgpPpRzHtdr3ENVNO140QEwUxuq77BxUht/M= sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a bookmark"}

<MethodEndpoint
method={"delete"}
path={"/bookmarks/{bookmarkId}"}
context={"endpoint"}

Permanently delete a bookmark and all its associated data (tags, highlights, assets).

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the bookmark was deleted successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Delete Highlight.Api (`docs/docs/api/delete-highlight.api.mdx`)


id: delete-highlight title: "Delete a highlight" sidebar_label: "Delete a highlight" hide_title: true hide_table_of_contents: true api: eJytVsGO2zYQ/ZUBc0kMrb0pUjTQoYDT3aDbBGiQ7KIoNgt4LI4lxhSpkNSuFUNAP6Jf2C8phpJlee2kOfRkQxwO38x788itsBU5DMqaKylSIUlToF9VXmiVF0EkQpLPnKo4QqTiIq4DQrELgWUDKni4upiKRATMvUhvxZDBi7tEeMpqp0Ij0tutWBI6cvM6FCK9vWvvElGhw5ICOR8DfFZQiSLditBUJFLhg1MmP8JyXRDURn2uCZQkE9RKkQO7glDQHh+jog2WleZUipTUmyYvHz69/MluvvxYbEKw2UuGrkIMGaBfSdEmwtHnWjmSIg2upkQYLDmqGEUlQjGeCkMhuB5HvrLGk+cafjg/559j6F2r5aiTyoOjUDtDklFn1gQygXdjVWmVRZpmnzynONEmu/xEGVNWOSY1qA7A0tp1iW7N/D5uaZsIH9CF31crT2G0bupySY7XychvrGZWW3eKKjJ1yUJoSGv7ILgp3KjcERmRiKWuiZUhaYW1DiLdBbaJCLQJp1KaWmtcMkfMRJsIYwN9V6A6XXrtyX2lK5kjDCTnJ4C0B6K4Hff3sJvj3vVV9ZgjouH88Wl3J3Qo2pbPfHH+/FhINwbrUFinvpCEf/76O2r/VZwwCHZNhkVVKu+VyRNQ5h61kglYB7SpuIJHQmOUs0qjOi2xPb3DRI0RDEhfHCMdygFjA6xsbf5PkWdWnpTCIYY5lJgVytCZI5QsESDnrAPePmXeS/Ie8+9KVdQlmseJ+v3TI5VEgPv8I54veWPsXDw/FHZvxFwnu0oqZoNN+Nl2ZD4ti47c/c48a6dFKrYopSPv2xlWanb/XCTiHp1ioLFd/XLH0m4CixAqn85mwTXTNTpcE1VTrKqTxttn2Nntmz4eOixczsj3PzCLvRuN3H/oMZ/MdcQwkfZBbBPxz2vrSmSEv/1xHRurzMrydq66g/R8ej49H5n4gGf+7uoI/7CoPCB40quzwvoQadxNszI5oJHA/J6pcKYxkIvVqYymcF0oz7kB2bU8NLaGYKFEg/k+iU9AKx98AnwvJnur9wmg9xR/jYQlZuu68lA5mzssSwwqQ62b6Ufz0Tx5AtwuvuC64eCPc62BjKysMoFvjSg0wMPRr/gMCcpEihbzfk5jkgUUhJLcFP60NWRoICfDLwECNLGyNTWwcrY85PeBlnBzBbWR5GAy+UAhKJN7+DnueUONn0x2sN9hrswA+a3yYYTZ11VlXYCsdt66syUy1GrYAfcKYdEtLmKTFlqVKizgc02ugf2bgckg2N25oEyma0nM7MLQJvzSp1gp0p1FcltABUDf9WV3yJCSmVxRyIq4zkkYGE1hDgu+WxZwj7omWFl3eIYykjmimJj5cATGQmldBFjr4He9edVLBK6bijx/3H3xkY0lgTXUjZcjAp4Un340ZzCZaGXWk0msZQ43798OeoMHFQqwUeeoIXP4oElCSQElBpx229njh+3R64E/sS9THxLFuYsxUFfaoiQJK6UJnqqSRW4dvLt4/SzaZmV9KDE6dv8+On4oPh7D7d77//tZ2fnE6Hbi65utbtsb5O3+ReZFItLx++wuETzfHLTdstBunG5b/hy1xM/QvT9GF5XK838p0hVqT99A/vR9b/LP4Gs4+49ommjD/PJJhUjEmppHD8n2rk1EN5cRRhcxzzKqwmjv0UXJXjvcHBeXby+vL0Ui8NBkH5lqPOAktO22i7hmE2nbAWk0FcbYtv8CRuRA+A== sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a highlight"}

<MethodEndpoint
method={"delete"}
path={"/highlights/{highlightId}"}
context={"endpoint"}

Delete a highlight by its ID.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The deleted highlight is returned.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Highlight not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Delete List.Api (`docs/docs/api/delete-list.api.mdx`)


id: delete-list title: "Delete a list" sidebar_label: "Delete a list" hide_title: true hide_table_of_contents: true api: eJy1VlFv2zYQ/isH9qU1FDsdOrTQwwBnSYGsxRC0CYYhNeCzeLZYUyRLUo5VQ8B+xH7hfslwlCzbadbtZU9xyOPdd9/dfaedsI48RmXNtRS5kKQp0nsVosiEpFB45fhS5OIyXQGCViGO4bZUATxVdkMBYknpGKzRDfz1x5+wsHZdoV8HeFCxVAZUBPQExkbogsixyETEVRD5veCIQcwyEaiovYqNyO93YkHoyU/rWIr8ftbOMuHQY0WRfEgGoSipQpHvRGwciVyE6JVZfYP9tiSojfpSEyhJJqqlIg92OQBnLLTFymn2okhJvW1W1cPnN6/t9uuP5TZGW7xhwComEwZ8LUWbCU9fauVJijz6mjJhsGID3RlkQjEAh7EUnICn4KwJFBj0D+ev+M8p1l8tFNZEMjEROVD7gGHPHIS6KCiEZa11M2YQr85ffuvpzmAdS+vVV5KDr4vEKUS7JgMqQKVCUGaVgTIb1EpmYD3Q1nFKzEqPJXFM2zhxGjmj73F/IPIYgWjbNiF9ImdmM7XG0tbmcVh0Tqsi9ejkc7BPB7eLz1Rw0zrPHR1Vx3BhJf17e0yhwqJUhs48ocSFJiDvrQd+nvitKARc/SdXZV2heeyofz8W7UnH3HcAD/5nhw674oeJtBQ/lvYwoJwnd1QuJtwbYbLr2q0VPEF+s5+P2muRix1K6SmEdoJOTTYvRSY26BXDSyT1111ZlljrKHJRxuhCPplE34zX6HFN5Mbo3JOz1XvYT9S73h46LJzE0Wh/5Np1kY8HfGCWI3MeyUzkvZHI+h9vra+QEf7y222iU5ml5eecdQfp5fh8fH40rAOe6c31N/iHSxUAIZBenpU2xFS8vYopswI0EriqZyqeaYzkU3aqoF4LpzfXgFrbhwCNrSFaqNDg6uAkZGmQQwasehmUalVqtSr5BEOg9NdIWGCxrl0A5+3KY1VhVAXyoH8yn8yzZ8B0sYZ1I8GHU62BjHRWmciinNoL8HTWHceQoEwq0XzaD2ZyMoeSUJIfw++2hgINrMjwXiBAkzJbUwNLb6vT+j7QAu6uoTaSPIxGHylGZVYBfkpv3lETRqM97BtcKTNAThN/wBxq56yPUNQ+WH+2QIbqhhewUQjz7nKeSJprVak4hy81+QYOa4GLQbBXWVCm0LUkruzc0Db+3LtYKtKdJjItaTl1W2wIMrjkSi4pFmW6ZycMjMYwhbmptZ7DBnVNsLT+NIYykmvUrUeuR1p/UFmfANY6hj03F32LwG3jKPDhxbA/uRoLAmuoGy9PBDwpIf9kzmA00sqsR6OUyxTuPrwf+i1tXrCpz1FD4fFBk4SKIkqMOO6es6gPz5O4Ax+xGlNvkppzb2OgdtqiJAlLpQmeq4qb3Hq4uXz7IomlsyFWmHS6X4Yn3w6PJ3B3EPv/6SOj05Wj9dVmnTTuehm9T+s6iEzk/d6eZYJVgK92O27HO6/blo9Tx/H3yEFFk9ZKFfi3FPkSdaDvJPn8Q78AXsA/oesP0TRJrHXN/4lMrKk5fFu0szYT3eAmBN3ltCjIxaNnx55nR6vk8ur91e2VyASe6u8jvU2un8Sz23UWt6wvbTvAS3rD6Nr2b2ZfomE= sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a list"}

<MethodEndpoint
method={"delete"}
path={"/lists/{listId}"}
context={"endpoint"}

Delete a list. This removes the list only — bookmarks within it are not deleted.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the list was deleted successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Delete Tag.Api (`docs/docs/api/delete-tag.api.mdx`)


id: delete-tag title: "Delete a tag" sidebar_label: "Delete a tag" hide_title: true hide_table_of_contents: true api: eJytVttuGzcQ/ZUB85IIa8kpUiTYhwJy7QBugsJIZBSFI0Cj5WiXEZdkSK4sRVigH9Ev7JcUw12tZMdN+9CnlTjk8MzlnOFeWEceo7LmWopcSNIUaYalyISkUHjl2CZycZksgBCxHMOsUgE81XZDAWJFvAorb2tArWFp7bpGvw6gItxjAIwRi4okRDsWmYhYBpHfiRl/55kIVDRexZ3I7/ZiSejJT5tYifxu3s4z4dBjTZF8SBtCUVGNIt+LuHMkchGiV+ZbxLOKoDHqS0OgJJmoVoo82NUBLyOhLdZOsxNFSurtrqzvP795bbdff6y2MdriDcNVMW2ZYXktRZsJT18a5UmKPPqGMmGwZntM9kwovt1hrASj9xScNYECI/7h/BV/HgL91UJhTSQT4a8//hzSyYnr6iEhNEVBIawarXdjhvDq/OW3jm4NNrGyXn0lObi6SPmEaNdkQAWoVQjKlBkos0GtZAbWA20dB8Qp6aGk/NI2TpxGDuh7eT9m8RSBaNs2IX0i5BmWYGyElW3M41vROa2K1JOTz8E+fbddfqYiikw4zx0cVZffwkr6986YQo1FpQydeUKJS01A3lsPfDylt6YQsPxPrqqmRvPYUX9+LNoH7XLXATz6nx+764oPppyl+2Nlj4TkOLmfcjFh7kz2qdVawdTxmwMxGq9FLvYopacQ2gk6Ndm8FJnYoFcMLqWoN3c1WWGjo8hFFaML+WQS/W68Ro9rIjdG554kVe/hQKV3/X7osHAIJ5z+yJXrbj5l9pBXvpnjSNtE3m8SWf/jrfU1MsJffpulZCqzsnyco+4gvRyfj89PaDrgmd5cf4N/MKoACIH06qyyIabSHWRLmRLQSOCanql4pjGST9Gpgnrtm95cs9TZ+wA720C0UKPB8ugkZKBViCFjLocMKlVWWpUVr2AIlL5GwhKLdeMCOG9Lj3WNURXILP9kPplnz4DTxeLVEYIXp1oDGemsMpFFODUX4EOiO75DgjKpRItpz8rkZAEVoSQ/ht9tAwUaKMnwFCBAkyJb065T8wf1vacl3F5DYyR5GI0+UozKlAF+Smfe0S6MRgfYN1gqM0B+r0I8wRwa56yPUDQ+WH+2RIbqhhOwUQiLzrhISVpoVau4gC8N+R0c5wEXg+CgsKBMoRtJXNmFoW38uXexUqQ7QeS08FDCbmoNlwwuuZIrikWV7OyEgdEYprAwjdYL2KBuCFbWP7xDGck16sYh18MTGAu19Qlgo2M45OaibxGY7RwFXrwYBiZXY0lgDXX08kTATAn5J3MGo5FWZj0apVimcPvh/dBvcK9iBTb1OWooPN5rklBTRIkRx91xVvTheFJ24CXWYuq3pOY87DHQOG1RkoSV0gTPVc1Nbj3cXL59kaTS2RBrTCrdz8HTp8JjAu6PSv//Pik6NTmZWG3WCeK+l8677tmRibyb0/NMMPPZsN9zC9563ba8nLqMHx9H5Uz6KlXg31LkK9SBvhPZ8w+95L+Af8LWL6LZJYHWDf8TmVjTbnhKtPM2Ex1XE4DONi0KcvHk1Knj+cnsuLx6fzW7EpnAh5L7SGKT6yfh7PfdjhlLStse0fF/Rte2fwPHe5L9 sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Delete a tag"}

<MethodEndpoint
method={"delete"}
path={"/tags/{tagId}"}
context={"endpoint"}

Delete a tag. This removes the tag from all bookmarks it was attached to.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the tag was deleted successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Tag not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Detach Asset From Bookmark.Api (`docs/docs/api/detach-asset-from-bookmark.api.mdx`)


id: detach-asset-from-bookmark title: "Detach asset from a bookmark" sidebar_label: "Detach asset from a bookmark" hide_title: true hide_table_of_contents: true api: eJy9Vm1v2zYQ/isH9ktrKHY6dFihDwPcNQWyFkPRJhiG1IDP4kliTZEsSSV2DQH7EfuF+yXDUZJf0qzrgGGf4lB3x+eeu3uOO2EdeYzKmkspciEpYlHPQ6D4ytvmhbXrBv1aZEJSKLxybCly8TLZARpAtoXS2wYQVoP9VGQiYhVEfiPGGEEsMhGoaL2KW5Hf7MSK0JOft7EW+c2iW2TCoceGIvmQDEJRU4Mi34m4dSRyEaJXpvoCzVVN0Br1qSVQkkxUpSIPtoRY0wkm2mDjNEdSpKTebKvm7uPzH+zm8/f1JkZbPGfgKiaTEfilFF0mPH1qlScp8uhbyoTBho1WB6NMKAbjMNaiy/4j9Inefw09FfCruHGwOAG9YPPgrAkUGPd358/4zyncXywU1kQyEf78/Y+h/ncYoO8dkhDaoqAQylbr7ZQxPDt/+mWca4NtrK1Xn0mmSJzui9QSEO2aDKgAjQpBmSoDZW5RK5mB9UAbxxkxKwOSRDJt4sxp5Hy+Rv6ByGMEouu6hPSBjMdG4Lv7dI2NUNrW3MeAzmlVpHGafQz2YSR29ZGKKDLhPA9fVD3ZhZX0z80yhwaLWhk684QSV5qAvLce2D2R3VAIWH1TqLpt0NwPNPhPRXfSPTc9wEP8xaHdLtgxMZjuj7XttURTZI/UXLmYjbMSZrvD2HSzRGmY7YaW7ATLhL8dRaD1WuRih1J6CqGboVOz26ciE7foFeNO7A2f++KV2OooclHH6EI+m0W/na7R45rITdG5B0dwiDAO3uvBHnosnN2Rfr3novY3H6vYnnK+mfNIZiwTyUhkw49X1jfICH/+9SrxrExp2Z2z7iE9nZ5Pz49Geo9n/vbyC/z7jyoAQiBdntU2xFTVkWplKkAjgct9puKZxkg+ZacKmsJVrQLHBtTa3gXY2haihQYNVocgIQOtQgwZsLxnUKuq1qqq+aSvY5YuWWGxbl0A523lsWkwqgJZDj6YD+bRI2C6WOr6WeHDudZARjqrTAww9B3gqSI4vkOCMqlEy/kwvinIEmpCSX4Kv9kWCjRQkeHdRrymOLM1bftFdVLfO1rB9SW0RpKHyeQ9xahMFeDH5POatmEyGWG/xUqZPeQ3KsQjzKF1zvoIReuD9WcrZKhu7wG3CmHZf1wmkpZaNSou4VNLfguH3cfFIBiVGJQpdCuJK7s0tIk/DSFKRbpXTqYFVAQMPS/jJfuQXMmSYlGn7xyEgdEU5rA0rdZLuEXdEpTWn96hjOQaUQrM9fAExkJjfQLY6hhGbvYqebV1FPhwv/lTNVYE1lA/Xp4IeFJC/sGcwWSilVlPJimXOVy/e7PvN7hTsQab+hw1FB7vNEloKKLEiNPenaV/755WAPARyzQNJqk5RxsDrdMWJUkolSZ4rBpucuvh7ctXT5KKOhtig0nAh405Pnkeeu/cH8jdYSl801OpF42jDdZlve7tBvG82T80gshEfvLq6OeOj8elvsgEjz+77Xbch9dedx0fp1bj19ZBPpPIShX4txR5iTrQV9J5/G5YCU/g75APh2i2SaV1y/+JTKxpe/pi4lfS/3jzSE+36DLRi0VKvv86Lwpy8cjvOPTiaK+9vHhzcXXBxJ9q/j2NT6EfBLTb9RZXrGldt8eXNI7Rdd1fn98Mqw== sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Detach asset from a bookmark"}

<MethodEndpoint
method={"delete"}
path={"/bookmarks/{bookmarkId}/assets/{assetId}"}
context={"endpoint"}

Detach an asset from a bookmark.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — asset was detached successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark or asset not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Detach Tags From Bookmark.Api (`docs/docs/api/detach-tags-from-bookmark.api.mdx`)


id: detach-tags-from-bookmark title: "Detach tags from a bookmark" sidebar_label: "Detach tags from a bookmark" hide_title: true hide_table_of_contents: true api: eJy1VttuGzcQ/ZUB85IIa8kpUjTYhwJy7ABugiBwZBSFY0Cj5WiXEZfckFzbG2GBfkS/sF/SDvci2VaDtEj9IEvkzHAuZ87MVtiKHAZlzbkUqZAUMCsWmPvXzpYn1m5KdBuRCEk+c6piQZGK0ygG1hBYB6V1BAFzD2tnS0BY9XpTYEuQoYEVgZJkglorkrBq4PyUVQ2WNBWJYG2RXonhRS+uE+Epq50KjUivtmJF6MjN61CI9Oq6vU5EhQ5LCuR8FPBZQSWKdCtCU5FIhQ9OmfyR74uCoDbqc73nkQO7hlDQznORCLrDstJsSZGS+q7Jy9tPL3+yd19+LO5CsNlLdlyFKDI4fi5FmwhHn2vlSIo0uJoSwWGKVKx2QolQ7EyFoRAcDGuQDydWNhzCY5djfoOFrkJTOOMCBMyhrH2AAm8ISIWCHCAsA+bncskJ7n68w5KWHFNmTSAT+AmsKq2yWPrZJ8/vHMihXX2iLIhEVI6BEhT5eBvLNUqhc9hwSIFK/03aDLaHhWojDN7FVB24w8CBkzxpDtWYTF0ygFCJRBR1iYYRJGmNtQ4i7Y9a/tsvz1UXyvVw7itrfOflD8fHhytxfuoHuHRFKTDALTnqa0PyO2Z6MPkN2f4veA+Y/2uoL2L5HiVy9LRP5ovj54/zd2mwDoV16svfLPDn739EJ05ia0OwGzKgPJTKe2XyBJS5Qa1kwkCmu4pfepDaQHdhVmlUh5O6g8cY4L4HYvD0xWNPh4YGYwOsbW2+Z1UzKw+A/GHl5lBiVihDR45Q4koTkHPWAatPuSdK8h7zbzIVG+ChoV5/Kh4WMzq4s3+9q/4ZKw6NVFIobDc3NAXWiISWitlAdX623bFeO4vdxszubgberp0WqdiilI68b2dYqdnNc5GIG3SKfY0Z66+7Oo1NHULl09ksuGa6QYcbomqKVXWwB3oLA/Lf9PLQ+cIR7Y2cD1zI7uX9wTOmmV/mOKIYM3sUEkn/5bV1JbKHv/y6iLllgFzsKP5sgONApVcjK+4qOJLh7mifAwdKu255lqwtG+OkdhE/nx5Pj/eadgx3/v78UXrGS+UBwZNeHxXWhwiUoXrK5IBGAiPoSIUjjYFcTJ7KaAqLQnm2Dai1vfXQ2JqnVYkG850Rn4BWPvgkMmcChcoLrfKCT9B7iv+NhBVmm7ryUDmbOyxLDCpDrZvpR/PRPHkCXA2msq79+HCuNZCRlVUmeOihDHifWyp+Q4IyEQHLeU8E0cgSCkJJbgq/2TquLDkZXo0I0MTINtR0C849+NzSCi7PoTaSHEwmHygEZXIPP0edN9T4yWRw+z3myowuv1U+7Pns66qyLkBWO2/d0QrZ1WrUgBuFsOwulzFJS61KFZbwuSbXwG4b4mIQDLMMlMl0LYkruzR0F171JtaKdMfBnBZQAdB3eRkeGU1yJdcUeOEoCNgIO0ZTmMPS1Fov4QZ1TbC27v4bykiuEUXDXA9HYGy3MDrytQ5+yM3It4umIs+H4y44LJBx3eTudUTAjejTj+YIJhOtzGYyibHM4fLi7Yg3uFWhABtxjhoyh7eaJJQUUGLAaafOQ2RUj8ME+IiZn3qRCM5BxkBdaYuSJKyVJniqSga5dfD+9PWzSMyV9YG7M90Ou1+/Mh9akx/243Y3Zv6HTbsjsL3B2SYdB2978r4a91Sm6vTe0tptS4lgemDJ7ZZxeul02/JxhCLv5zv2jtwmlefvUqRr1J6+Eu/Ti34KPYN/cnZYg0wTh4Su+ZdIxIaa+zt2pMauq6MXncCr7q0jxtmegUfjvE0GjXmWURW+Knu9NwtPz96eLc54FvTLfBmnvXB4K5L4Gd3tUBlHTDzbCo0mr+M4F51Vnhx4f/A8GDTd5DiUkO22k1gw87XtmJ/IhJyatv0LslDeoA== sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Detach tags from a bookmark"}

<MethodEndpoint
method={"delete"}
path={"/bookmarks/{bookmarkId}/tags"}
context={"endpoint"}

Detach one or more tags from a bookmark. Tags can be identified by ID or name.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The tags to detach. Each tag must have either a tagId or a tagName.","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"object","properties":{"tagId":{"type":"string"},"tagName":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"],"default":"human"}}}}},"required":["tags"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The IDs of the tags that were detached.","content":{"application/json":{"schema":{"type":"object","properties":{"detached":{"type":"array","items":{"type":"string","description":"The unique identifier of the tag.","example":"ieidlxygmwj87oxz5hxttoc8","title":"TagId"}}},"required":["detached"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Download Backup.Api (`docs/docs/api/download-backup.api.mdx`)


id: download-backup title: "Download a backup" sidebar_label: "Download a backup" hide_title: true hide_table_of_contents: true api: eJy1VttuGzcQ/ZUB85BEWEtOkaLBPhRQmqRwk4cgsVEUjgGNdke7jLgkw4ssWVigH9Ev7Je0w71IttK0L33SipzLmdsZ7oWx5DBIoy9KkYvS3GplsHyJxTpakYmSfOGkZQGRi1f9NSAUprGKApWwTLKAHhDupAV0RS03NIXLmobLJvoANW4IEB77WBTk/WPwAUP0U5GJgJUX+bXo/HpxkwlPRXQy7ER+vRdLQkduHkMt8uub9iYTFh02FMj5JOCLmhoU+V6EnSWRCx+c1NVJBIwpavklEsiSdJArSQ7MCsIIlvHQFjk8kQtJslTbXdXcfn7xg9nefV9vQzDFCwYtQxLpQF+Uos2Eoy9ROipFHlykTGhsWGQ5iGRCMgyLoRYchiNvjfbkGfp35+f8c4q4z+JKKjrNs8hEYXQgHVgZrVWySBWd3UnLR2Nu2rZtM/H8/NmplyuNMdTGybu/K/rn73+kfLxMWYdg1qRBemik91JXGUi9QSXLDIwD2loO+AGMQNswswo52m9V55DoYwRiQPr8FGmXbdAmwMpE/dDxcfyfvfm6e7P8TEUQmbCO+z/ILv+FKenfW2gODRa11HTmCEtcKgJyzjhg9Sk3QUPeY/WfTNWxQf3QUK8/Fe29jrruAB7s3xx68DUrprQl/6E2PM4VpSC52XIx67rIz/ZDN7azYd4Fz5vbDNMUnRK52GNZOvK+naGVs80zkYkNOslAU7r6665EK4wqiFzUIVifz2bB7aZrdLgmslO0p1zCfd1bGObvbS8PHRYO54gIPnIVO8/HdDDmmD1zHEmMZy4Jiaz/eGNcg4zwl18vU2KlXhlW56g7SM+m59Pzo8Ee8czfX5zgHy8lD6QntTqrjQ+pjEtj1g26tdQVoC6B63smw5nCQC5FJ4tEkNKzbUClzK2HnYkQDDSosToY8Rko6YPPgFkyg1pWtZJVzSfoPaVfPfCwB+tM5bBpMMgCldpNP+lP+tEj4HQx43XDwYdzpYB0aY3UwUPfaID3596yjxKkTiVazPshTUYWUBOW5Kbwm4lQoIaKNO8TAtQpsjXtYOVMc7++t7SEqwuIuiQHk8lHCkHqysOPSect7fxkMsB+j5XUI+R30ocjzD5aa1yAIjpv3NkSGaodNWAjERbd5SIlaaFkI8MCvkRyOzgskW5bDWwMUhcqlsSVXWjahp96EytJquNHTgvIwHSc8jI4GU1yJVcUijrdsxEGRlOYw0JHpRawQRUJVsbd9yF1yTWiZJjr4Qi0gca4BDCq4IfcvOxbBC53ljwfDic+VWNJYDR14+WIgCfF55/0GUwmSur1ZJJimcPVh3djv8GtDDWY1OeooHB4q6iEhgKWGHDaqTPBj+qJ6IGPmJepF0nNOchoiJaZhspujT2RDTe5cfD+1ZuniTat8aHBxNj92jx6byy/+iLZH6j/f3ycdPxytNLarKPIfc+t1/2C9yIT+dGuH+n1JhNMDiy533OXXjnVtnycGpEfNQdyTRRcSs/fpchXqDx9I+4nH/oN8RT+CWx/iHqXOFxF/icysabd8eOkvWkz0U10wtBdz4uCbDhSfPjEYJIeV87Pry9FJvA+NT+g4mT8q5j2+07ikqmnbUeIiYoYX9v+BSrqvTM= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Download a backup"}

<MethodEndpoint
method={"get"}
path={"/backups/{backupId}/download"}
context={"endpoint"}

Download a completed backup as a zip archive. The backup must have a 'success' status.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The backup file as a zip archive.","content":{"application/zip":{"schema":{}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Backup not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Asset.Api (`docs/docs/api/get-asset.api.mdx`)


id: get-asset title: "Get a single asset" sidebar_label: "Get a single asset" hide_title: true hide_table_of_contents: true api: eJy9VduO2zYQ/ZUB89DE0NqbokUDPRRwrtgmAYJkF0WxWcBjaSSxpkiGHO1aMQT0I/qF/ZJiKNnrzW7zWL/YJofDM2cOz+yU8xSQtbNnpcpVTbyMkVhlqqRYBO1lS+XqpbuxxmEJaAEl4ocIa20x9FA4y2R5DucNQaDonY0EL8bVk/PeEzSEJQXQESIxrDFSCc4CN3RI9v7s/Svg3tNcZYqxjiq/VAlLVFeZilR0QXOv8sudWhMGCsuOG5VfXg1XmfIYsCWmEFNALBpqUeU7JRlVriIHbet7VQnizuovHYEuybKuNAVw1S0yQUNbbL2RNJp0abZ93d78+ewXt/36c7NldsUzgaw5hSTIZ6UaMhXoS6cDlSrn0FGmLLYSgVNEprRg8MiNkhr21EXB/ePpqXzdh/s98h/iPFBlqOD4MNnwmOb1PAPdYk0Lb+sM0HujiySJhS+rJ3Mp5afTp/fhXFjsuHFBf6US/vnr73TF89QbYLchKw1vdYxa8mp7jUaXGbgAtPVCjJA7FZB6RVteeINCy/d6eNuPYwRqkE+mWuLGTVpW2Uhvrhap9LjYTewPSjQVrveK6YJRudphWQaKcVig14vrpypT1xg0rs3YlWl7pKLCzrDKVcPsY75YcOjnGwy4IfJz9P5BtU0Z9hp7O8XDiEVqOBL7J6FgvPlY8gdG5GapI4WpfApS2fTjtQstCsLffj9XQo22lZPjUvUI6en8dH56pN4DnuWHs3v4D5s6AkIkU500LrKwA2vnNi2GjbY1oC0hEJYnmk8MMoVUnS5IVKqj5AY0xt1E6F0H7KBFi/VtkpiB0ZFjBmIEGTS6boyuG1kZ+5ilS9ZYbDofwQdXB2xbZF2gMf38s/1sHz0CoUte9ahmWVwaA2RL77TlCNMDBbyrWi93lKBHg1otJ4mlJKvpXc3hD9dBgRZqsuKgJM4olW2ohyq49m5/b2gNF2fQWXmTs9knYta2jvBrOvOW+jib7WF/wFrbA+R3OvIR5th57wJD0YXowsnopf5wAq41wmrcXCWSVka3mlfwpaPQw61RfuPX2hamK0k6u7K05RdTikqTGV+30AKaAUcvOVxySCmdrIiLJu1LEgFGc1jCynbGrOAaTUdQuXD3Dm1L6RGlxNKPQGAdtC4kgJ3huOfm+SQREI+LsrhfiakbawJnaXxegSiZXMw/2xOYzYy2m9ks1bKEi4/vDnqDG80NuKRzNFAEvDFUQkuMJTLOx+NiT4fjyaZAlsA6pikkiXMfY6HzMjKphEobgsfJZMX+Prx8Pdqqd5FbTHY3DYc3xPK2tK3NZNffPsPdrWX+31N5dJ0jmx6y0Th3k81ejsMtqkzl+zF3lSlxCdnc7eSSi2CGQZaTImWC37ps8uJSR/ldqrxCE+k79T/+OI3YJ/Bf+KZFtH0yc9PJP5WpDfVHs3i4GjI18pEgjLvLoiDPR+eOU18djZo3r85VpvCuO3/jxinvg2h2uzHiXNxnGA7gkhsJtGH4F4TkX+M= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single asset"}

<MethodEndpoint
method={"get"}
path={"/assets/{assetId}"}
context={"endpoint"}

Download an asset's binary content. The response Content-Type header is set based on the asset's MIME type.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The asset's binary content. The Content-Type header reflects the asset's MIME type (e.g., image/png, application/pdf)."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Get Backup.Api (`docs/docs/api/get-backup.api.mdx`)


id: get-backup title: "Get a single backup" sidebar_label: "Get a single backup" hide_title: true hide_table_of_contents: true api: eJy9Vu+KGzcQf5VB+ZKYPftSUhr2Q8FJk3BNCiG5o5TLgce7Y69irbSRRnfnmIU+RJ+wT9KOdr322U4pFPrJa41m9Jt/v5mNcg15ZO3sRalytSR+gcUqNipTJYXC60ZkKlcfiL2mW4KaGEtkhIXzgBC0XRqCedLKQNvCxFLbJWgOUETvyTIERo4BHjdkRZZBiEVBIWTgPCxQm+jpyVhlinEZVH6tOhBB3WQqUBG95rXKrzdqTujJTyNXKr++aW8y1aDHmph8SBdCUVGNKt8oXjekchXYa7s8cueyIohWf4kEuiTLeqHJg1sAV1tnBA/dY90YsaNJl+Z+vazvPj//wd1//b66Z3bFcwGtOV3pQF+Uqs2Upy9ReypVzj5SpizWcmW+vZIpLTAa5EqJG55C42ygINC/Oz+Xn2PEYpUCU7kHsXCWybIoYNMYXaRsTj4H0ToREDf/TAWrTDVecs+6e1OXx0FrMxUD+YvTIgyB+JQsUzYag3MJinjfZqrwhEzllE9aCvor7QlsrOfkRTB3blWjX7100fLJG11lncJANtZSSn3NqUz1Racy1ZecumkzRd47/wuFgEv6F748yO21hG0I0i4k+w737h06M0C/aVsx+uz86XHOryxGrpzXX/9O+Z+//5Gq80XqAWC3Igs6QK1DSE2l7S0aXaamovtGIB4UCNM9TxqD+nRp7GI3lP0+ArVF+uwYaVf7YB3DwkV7+PB/qczClScT8xDAFGosKm3pzBOWkjBImQVRH0up1N/O8aGpKtZoDw31+mN1WAMJ4M7+zY4RXoliClt6nyvXk6w4Ka2fq0nXyWGy2XJDK7VB/nZLadEblasNlqWnENoJNnpy+1Rl6ha9FnwpSr24y8wCo2GVq4q5Cflkwn49XqHHFVEzxuaY3YVcegtbEnzb34cOi3ixx8YfJXndy/ucPIRWXhY/0jUhvnRJuiB9vHa+RkH486+XKZ7aLpyoi9cdpKfj8/H5HrsOeKbvL47wD0IdZCaRWZxVLnDK3rbvZCihLUHSeqb5zCCTT97pgsZwWekgtgGNcXcB1i4CO6jR4nJnJGRgdOCQgYyqDCq9rIxeVnKSul9+7ZafAzTeLT3WNbIu0Jj1+JP9ZB89AgmXjJ2uJ+RwagyQLRunLQfo6wvwYbs38kYJ2qYUzaZ9byYjM6gIS/Jj+M1FKNDCkqwMdwK0ybMVrWHhXf0wv3c0h6sLiLYkD6PRR2LWdhngx6TzltZhNNrCfo9LbQfI73TgPcwhNo3zLFM/OH82R4HaDBpwqxFmnXCWgjQzutY8gy+R/Bp2k1ySIcOuG4n9TkGS2Zmle37Zm1hoMh0tSlhAM2Do4rJ9ZDApmVwQF1WSixEBRmOYwkwIfga3aCKlnebBG9qWkiNKhiUfnsA6qJ1PAKPhsI3Ni75E4HLdUJDD7UlI2ZgTOEtde3kikE4J+Sd7BqOR0XY1GiVfpnD14d1Qb3CnuQKX6hwNFB7vDJXDEjbu1IXXB/XE7yBHQsfUX0nFub1jITbGYUklLLQheKxrKXLn4f1Pr58ktmxc4BoTUfe7yxviw33vsA83O87/vxbGjm72BpssLcKYm55hr/ulS+Z+PuxfN5kSghDxZiOVeuVN28pxKkbZLncEm2i41EG+S5Uv0AT6B88ff+iHwxP4FsL+EO068biJ8k9lakXr/S2xlQWl6+qEoRNPi4Ia3lM8mq7C1MO4efPqUlaTh/x8wMfJ+klQm01341L4p20HjImPBGDb/gWcCEi2 sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single backup"}

<MethodEndpoint
method={"get"}
path={"/backups/{backupId}"}
context={"endpoint"}

Retrieve metadata for a single backup, including its current status (pending, success, or failure).

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The requested backup.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"assetId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"size":{"type":"number"},"bookmarkCount":{"type":"number"},"status":{"type":"string","enum":["pending","success","failure"]},"errorMessage":{"type":"string","nullable":true}},"required":["id","userId","assetId","createdAt","size","bookmarkCount","status"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Backup not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Bookmark Highlights.Api (`docs/docs/api/get-bookmark-highlights.api.mdx`)


id: get-bookmark-highlights title: "Get highlights of a bookmark" sidebar_label: "Get highlights of a bookmark" hide_title: true hide_table_of_contents: true api: eJylVm2P2zYM/iuE+qUNfMl16LDCHwakW9vdOmCH9g7DcD0gjE3bamTJleTcuYGB/Yj9wv2SjfJLnEvaFeinBBZFPSQfPuROmIosemn0RSpikZN/YcymRLv5ReaFknnhnYhESi6xsmI7EYu35K2kLQEqBZ7uPRSjMdxJX0gNviBwFSUyk5TCunc6F5HwmDsR34jhISduI+Eoqa30jYhvdmJNaMkua1+I+Oa2vY1EhRZL8mRdMHBJQSWKeCd8U5GIhfNW6vwI6FVBUGv5sSaQKWnPYCyYLKCbYqJ7LCvFniTJVN03eXn34fkP5v7T98W99yZ5zsClDyYD8ItUtJGw9LGWllIRe1tTJDSWbLTeG0VCMpgKfSE4GEuuMtqR4wC+Oz/nn2Pcp1Iq3QHqxGhP2vN9rColk1DIxQfHTk5kyaw/UOJFJCrLZfeyg7B/aWKL1mLD0D2V7v99TMI9qkobCefR+t+zzJGfnOu6XJPlc9LpF04To4w9VW3SdclUakgpcyc4tZzu3BJpEYm1qonJlVKGtfIiHgzbSDBtT7nUtVK45jpzOdtIaOPpqwzl6dBrR/YzWUksoad0eQJIe8Csm0M6TbM5zV0fVY85IBrfn752u+fy2OWiffjkhBa3bTh9dv70mKvXGmtfGCs//dfn//z1d+itF6GDwZsNaZAOSumc1HkEUm9RyTQCY4HuK37rAZM5hEWlUJ7m8L72Y8tOEYgB6bNjpEPfgjYeMlPrh09/SxMlJj1Jk0MISygxKaSmM0uYMn2ArDUW+PqcOVGSc5h/lauiLlE/dNTfnx8xKADc+59w4CVfDIkL7/vC9KOAg2TRisVi4J9b7PZUbBfFdEg4sttBoWurRCx2mKaWnGsXWMnF9qmIxBatZLghaf1xV6qhRwvvKxcvFt428w1a3BBVc6yqk+reexg0/U1vDx0WDmoyXN5xLXu9moyYMdP8MscRzFjDgxELSfjzytgSGeGvf1yF9EqdGb7OUXeQns7P5+eTUTHiWV5eHOEfD6UDBEcqOyuM86GYQ5KlzgF1ClzlM+nPFHqyITqZ0ByueCQsLy94Eps7B42pwRsoUWO+d+IiUNJ5FwHP3mgyWiJA5yj86hTWmGzqykFlTW6xLNHLBJVq5u/1e/3oEXC6eIp2LcIfl0oB6bQyUnsHPd0AD/u/4jdS6JeC1bJv1uBkBQVhSnYOf5oaEtSQk+aNhAB1iGxDDWTWlIf1vaM1XF9ArVOyMJu9I++lzh38GO68ocbNZgPsS8ylHiH/Jp2fYHZ1VRnrIamtM/ZsjQy1Gm/AViKsusNVSNJKyVL6FXysyTawX0y4GATDbAepE1WnxJVdabr3P/UuMkmq00lOC0gP6Lq8DI+MLrmSGfmkCOfshIHRHJaw4umzgi2qmiAz9vANqVOuEQXHXA9LoA2UxgaAtfJuyM2oiVdNRY4/jmtZqMaawGjq2ssSAXeKi9/rM5jNlNSb2SzEsoTrt7+NfAsLC5jAc1SQWLxTlEJJHlP0OO+us9CP14Pgd7skD6/eJJBzsNFQV8pgSilkUhE8liWT3Fi4/PnVkyCelXG+xKDb/Rr2mg6WU5MBjjAfNuRuPwu+dcXt9GQyyngRYEnc9Yq6n+isnPHBeJ8O3kiwJLD9bsfcvLaqbflzoB+vx3tJDcKbSsf/UxFnqBx9IcTHb/vp8AQ+B3nYBXUTlJvXqViISGyoOVxx29s2El0nBxSdwTJJqPKTq0cDltV5nDivX16JSOChJj/Q4OD9JKzdrrO4Ys1p2xFl0CAG2Lb/AidXhhI= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get highlights of a bookmark"}

<MethodEndpoint
method={"get"}
path={"/bookmarks/{bookmarkId}/highlights"}
context={"endpoint"}

Retrieve all text highlights within the specified bookmark.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The highlights within this bookmark.","content":{"application/json":{"schema":{"type":"object","properties":{"highlights":{"type":"array","items":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}}},"required":["highlights"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Bookmark Lists.Api (`docs/docs/api/get-bookmark-lists.api.mdx`)


id: get-bookmark-lists title: "Get lists of a bookmark" sidebar_label: "Get lists of a bookmark" hide_title: true hide_table_of_contents: true api: eJylVttuGzcQ/ZUB85IIa8kpUjTQQwElTQI3fTAcG0XhCNBoOdIy4pIMyZWtCAv0I/qF/ZJ2uBddmwbIk1bkXA7ncma2wjryGJU1V1KMxZLiK2tXJfrVbyrEIDIhKeReORYRY3FD0StaE6DWoFkEYoERcmsiKgOxIAiOcrVQJGHe2hqKTERcBjG+F539IKaZCJRXXsWNGN9vxZzQk59UsRDj+2k9zYRDjyVF8iEJhLygEsV4K+LGkRiLEL0yyxOQtwVBZdTnikBJMpHBeLCLhG4fEz1i6TRbUqSkftwsy4dPL3+yj19+LB5jtPlLBq5iEumAX0lRZ8LT50p5kmIcfUWZMFiy0HwnlAnFYBzGQvBjPAVnTaDAD/jh8pJ/TnGfjakKB7D5gkxkA+icVnlK4OhTYCtnwmTnnyiPIhPOc7qjajAkV3ti6D1uGHakMvy/upKnmai7QJy5OHjraQpNpTXOOdIc0DoTKj8nWKeqIBOvzrg/Y6UROBUkU5VcjiWaCrXIRCjRR65JSQusdBTj7q7OxOeK/Oab/LlqrlW+Jzq3VhMatlJgeG1Z3nqM1ofzUlUgf2P1V1HbB0Oe/0sVLX+sFT2kk9b/tD6o0XvOVpubNrJ7cey1zkDcwzPd9QKTg6iPfTQFNa3TxYvL56cVfmewioX16su/7PD3n3+ljnyV+h6iXZEBFaBUISizzECZNWolM7Ae6NGxm6Pyj/QYR06jOl/4u7j1jb6PQHRIX5wi7bodjI2wsJU5dv09nZdbeTa9hxAmUGJeKEMXnlBylQF5bz2w+pBLpaQQcPlNpoqqRHNsqNUfiuNMJoA7+3uZf8OKKXDJfyxsOzdSQTF1i1HHVWG03fFhPdLtRAnk1x2lV16LsdiilJ5CqEfo1Gj9nAsavWKkKV7tdZOlrjuLGF0Yj0bRb4Yr9LgickN07uw4aC10Q+B9Kw8NFn7P3jT6wGlsPO/PpD7I7JnfkcS4eZOQyNqPt9aXyAh//f02RVaZhWV1fnUD6fnwcni5N1t6PJPrqxP8/aUKgBBILy4KG2LKYxdfZZaARgIn+ELFC42RfHqdymkItzxCJtdXPLbtQ4CNrSBaKNHgcmckZM34yYCHdQaFWhZaLQs+wRAo/RoJc8xXlQvgvF16LEuMKketN8OP5qN58gQ4XDx2m+7gw4nWQEY6q0wM0FYa4GHrO/Yhod0iZpO2T5ORGRSEkvwQ/rAV5GhgSYY3FwI06WUr2sDC2/Iwvw80h7srqIwkD4PBB4pRmWWAn5POe9qEwaCDfY1LZXrITHF7mEPlnPUR8soH6y/myFBdrwFrhTBrLmcpSDOtShVnkEYH7DYZTgZBtwyAMrmuJHFmZ4Ye4+vWxEKRbiiSwwIqAoYmLp2T3iRnckExL9I9G2FgNIQJzHg+zWCNuiJYWH/oQxnJOaJkmPPhCYyF0voEsNIxdLHp6fB24yjwYb/HpWzMCayhpr08EXCnhPFHcwGDgVZmNRikt0zg7ua3vt7gQcUCbKpz1JB7fNAkoaSIEiMOG3Xm+F49cT3wERMztSKpODsZA5XTFiVJWChN8FSVXOTWw/Uvb58l3nQ2xBITZbd72zuK7eplF4A9wuNe3O4mwPeswg2N7A0vHvvMhNuWQ+/7RZIJc3ywVbZTNhNMAiy63XI13nld13zc7ir30x2JJqqVKvC3FOMF6kBfednTm3YUPIP/QtutjGaTuFpX/E9kYkWbwy24nvLik3o3oWgEJnlOLu6pnkxT5uN+vLx7cysygYcsfMS6yfpZWNttI3HLLFPXPcrEOgywrv8BsYyNGA== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get lists of a bookmark"}

<MethodEndpoint
method={"get"}
path={"/bookmarks/{bookmarkId}/lists"}
context={"endpoint"}

Retrieve all lists that contain the specified bookmark.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The lists that contain this bookmark.","content":{"application/json":{"schema":{"type":"object","properties":{"lists":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","nullable":true},"public":{"type":"boolean"},"hasCollaborators":{"type":"boolean"},"userRole":{"type":"string","enum":["owner","editor","viewer","public"]}},"required":["id","name","icon","parentId","public","hasCollaborators","userRole"],"title":"List"}}},"required":["lists"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Bookmark.Api (`docs/docs/api/get-bookmark.api.mdx`)


id: get-bookmark title: "Get a single bookmark" sidebar_label: "Get a single bookmark" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single bookmark"}

<MethodEndpoint
method={"get"}
path={"/bookmarks/{bookmarkId}"}
context={"endpoint"}

Retrieve a single bookmark by its ID, including its tags, content, and assets.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The requested bookmark.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Current User Stats.Api (`docs/docs/api/get-current-user-stats.api.mdx`)


id: get-current-user-stats title: "Get current user stats" sidebar_label: "Get current user stats" hide_title: true hide_table_of_contents: true api: eJzVV81u20YQfpXB5tIKtGQXPekQQKmbxE2KBrGNIHAMaESOxI2Wu8zuUDYjCOhD9An7JMUsKYmSpTg/p55EaHZmv/nZb2aWypXkkbWzF5kaqhnxb5X3ZPk6kL9k5KASlVFIvS7llBqqt8Re04KgCjgjCIysA+s0wNR54JwgbUyYGrDinCzrFJkyqAL5BLRNTZVpO4OJc/MC/RxSV1kOMKmB65ISYFdC5grUNiTAOGuuSjYKoowp64XmGkpkJi8n0WYQ2HmBFTX6KlGMs6CGN0ocCuo2UYHSymuu1fBmqSaEnvyo4lwNb25Xt4nyFEpnAwU1XKpfTk/lZzcA58SoTfTnywGIDguG1Fkmy2IKy9JIOLSzg49B7C1VSHMqUL7EfTVUbvKRUlaJKr3kh3WDxlbFszYCoXPaVsWEvFol8vUcF85rpqMHRj7N9YKyY/KrGK/Dstc68FHhSz3LjZ7lR06scxee1VdR9pi3Rtv5QUtM93xQgCHQIclKsvqp0l68vmkMt2bWSrdi15XnTdF1bKD3WKtEaaYiPA66qdrOucBe25mgi0X+OLrWwvq8ACvw/qK5/uw04mQ0I4F9qT/T8Ug8jPQ3OsO72o+70mI7AmvP0Shd2+pq3q465aLtbNS+9K8AnOvwjuhI2eQ6/OmsvPQj0veE/nDt1i9d5b8/kPmu9tbwV9ZE1N9WRER0jvVf0z1nv7VYsf4RVFm8awNqP73rXHQj34nzJqq7zsSHiLNrodbv98xi8W2Vuwc+6n/hCXbI7NJVPv0BqGFfvwUrnGoMTgypIfuKEkW2KgQcllol6o4mgtDId+Em2ghgumeyQdpUooK2M0PTRuCDNHJdlM43Dn1lIFp0x9O805P2OtBuv9l2l04v2e8cD/vEDi8/IL89qjvMG52KOpQ6cWqVqF9Pzx72+msrI4zz+jNl8O/f/8T2/iwODcBuThZ0gEIHCbaMNgs0OkvAeaD7UmK01/6l6QxK0/aIB41/k3u6x6KU1O8gUKsGakGcu3Zek4JCITU1kHEjDAoahHZwC+QXMvXIpFN5o4ZqiVnmKYTVAEs9WJypRC3QaymzWI2tuAnEFCvDaqhy5jIMBwP2dX+OHudEZR/L8sFoeJUTtBbATWOsXrXnocEiHnRmsEsJQHNzdxLbxENuFj/iMTVsD0kW48dz5wsUhH+8u4qlq+3Uibp43UA665/2T6UCNMdwbvCM3lw8wL8R6gAIgcz0JHeBJTq7s6fNwBNmJ5pPDDL56J1OqQ9XuQ5iG9AYdxegdhWwgwKtzIqb4kvASP3H6TYkkG9eQAJNQTfT7ATTeVUGKL2beSwKlFHamLr/wX6wT57AaDtfa2flz5ExQDYrnZaJun2pgLs1W8odGWgbUzQetQUWjYwhJ8zI9+G9qyBFCzOysiMQoI2ezamGqXfFbn7vaALXF1DZjDz0epfErO0swNOo84rq0OutYb/BmbYbyMIEHcyhKoWlZIgOzp9MUKCWGw1YaIRxIxzHII2NLjSP4VNFXtYBjwUx+SDJIFjP8+3eQZLZsaV7WXSiiakm07xtCQtoBgxNXNaXbExKJqfEaR7lYkSAUR9GMBa2HsMCTUVxD9i5Q9ss7kDRsOTDE1gHhfMRYGU4rGOzZlMQQgvy54ZfYzYmBM5S87w8UdyYwvCDPYFeTybbXi/6MoLrt6+3G9ad5hxcrHM0kHq8kwWmIMYMGfuNupDTRj2SFMhfYB1TeyQW5/qMhao0DjPKQNoM/KQLKXLn4c3585/70m9LF7hAu+3J6gXxzn4E4dCWudyS5v9u4Wyoq8P0q6Rh32XL1DcqMrU0bulITQBuEyVcI9LlUor+2pvVSv6OdS3r6Zar47KaqOalRnqfU62GapSmVHIkdVPFYWR/3RT23bSPF79fSQfd5dw9jo3W16ONrTu2l8vmxJVwymqlkhZE5Bi1krb6H6wyvyg= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get current user stats"}

<MethodEndpoint
method={"get"}
path={"/users/me/stats"}
context={"endpoint"}

Retrieve usage statistics for the currently authenticated user, including bookmark counts by type, top domains, tag usage, bookmarking activity patterns, and storage usage.

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Detailed usage statistics for the current user.","content":{"application/json":{"schema":{"type":"object","properties":{"numBookmarks":{"type":"number"},"numFavorites":{"type":"number"},"numArchived":{"type":"number"},"numTags":{"type":"number"},"numLists":{"type":"number"},"numHighlights":{"type":"number"},"bookmarksByType":{"type":"object","properties":{"link":{"type":"number"},"text":{"type":"number"},"asset":{"type":"number"}},"required":["link","text","asset"]},"topDomains":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"count":{"type":"number"}},"required":["domain","count"]},"maxItems":10},"totalAssetSize":{"type":"number"},"assetsByType":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"count":{"type":"number"},"totalSize":{"type":"number"}},"required":["type","count","totalSize"]}},"bookmarkingActivity":{"type":"object","properties":{"thisWeek":{"type":"number"},"thisMonth":{"type":"number"},"thisYear":{"type":"number"},"byHour":{"type":"array","items":{"type":"object","properties":{"hour":{"type":"number"},"count":{"type":"number"}},"required":["hour","count"]}},"byDayOfWeek":{"type":"array","items":{"type":"object","properties":{"day":{"type":"number"},"count":{"type":"number"}},"required":["day","count"]}}},"required":["thisWeek","thisMonth","thisYear","byHour","byDayOfWeek"]},"tagUsage":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"count":{"type":"number"}},"required":["name","count"]},"maxItems":10},"bookmarksBySource":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"count":{"type":"number"}},"required":["source","count"]}}},"required":["numBookmarks","numFavorites","numArchived","numTags","numLists","numHighlights","bookmarksByType","topDomains","totalAssetSize","assetsByType","bookmarkingActivity","tagUsage","bookmarksBySource"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Get Current User.Api (`docs/docs/api/get-current-user.api.mdx`)


id: get-current-user title: "Get current user info" sidebar_label: "Get current user info" hide_title: true hide_table_of_contents: true api: eJy9VcGO20YM/RWCObQ1tPam6EmHAk7bBGlyCJJdFMVmAdMSLU08mpnMUN51DQH9iH5hv6TgSOu1sznk1JOEGQ75SD4+HtAHjiTGu9c1ltiw/NLHyE6uE0cssOZURRPUAEt8zxIN7xhC9BtjGYzb+Njl97DxEaRlqEYHdg/US8tOTEXCNfSJYwHGVbavjWvU1kRw1HEB3JGxBZCrgXYkFOdYoFCTsLxBhZLwtsDEVR+N7LG8OeCaKXJc9tJieXM73BYYOQXvEicsD/jj5aV+zvFfPcLLcL5LX8tEY1feCTtRFxSC1RSMd4tPSf0cMFUtd6R/sg+MJfr1J64ECwxRKypmRGHqE5sk0bgGhwI16acXBbreWlpbxlJiz0OBuS7fZGk6ar7Np/UV2dzeR+u195bJ4TBoGT/3JnKtpTc1nj64HQa1+Ony+dPaXjttt4/mL67h37//yVx4kZsE4rfswCToTErGNUqDHVlTF+Aj8H3QeF+UXfheFsGS+XrBj/nxPXVB0ztDgMMItWNp/cRs7Q4pXXChzU+LjlFJFXfKL+VUHy2WeKC6jpzSsKBgFrvnWOCOotEi5qZO12MJNtRbwRJbkZDKxULifr6lSFvmMKcQnsyQcnDyAH6Tq/RmsocRi2I/YfsHTX2MfMr5YyU0suaRzbSX2QiL6edlpjWW+PsfV7m/ynR9rlmPkJ7PL+eXOnBGciGPeJbvXj/Bf7w0CQgS281F65NodWDt/bajuNXx1lmOTPWFkQtLwjFnZyqew1VrkvoGstbfJdj7HsRDR46aRyepAGuSpAJUCApoTdNa07R6Qilx/roa1lRt+5AnuYnU6QxXZO1+/tF9dM+ewfJRhYx3eri0FtjVwRsnCSa+A52zNWiMGozLLVotJ2plJytomWqOc/jT91CRg4ad6igDuZzZlvewib477+8dr+H6NfSu5giz2QcWMa5J8HN+84b3aTZ7gP2OGuOOkN+aJCeYUx+Cj6Jilny8WJNCDccXsDMEq/FylYu0sqYzsoLPPcc9BIrUsXBM2gyGB+Wc1Jm1syvH97oMsouNYTtOtZYFjAClsS4PQY4utZMblqrN9+pEgfEclrBSLVrBjmzPeV2cxTCuzpsiO9Z+RAbnofMxA+ytpIfavJgoAlf7wEkPH05S7saawTsexysyg05KKj+6C5jNrHHb2SznsoTr92+PfIM7Iy34zHOyUEW6s1xDx0I1Cc3H5ypLx+dZnkCPwHnhySST88HGQR+sp5pryHvm+yzUKnvvfn35w1y3QfBJOsoyNy4GfMVytqfydvpyEg+Pavl/L+ZReE4UeihG7TxMCnuDWWFRBVg3tyqEnh4OStXraIdBjzMbdX0/Kmxe5gWO85VFect7LHFZVRwkS7HtNfqTtayaeZT7V79dYYF0rpRfKGP2Pl2R25/4PhxGiytVgmHAYgKRlQEHXYP/ATixQLA= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get current user info"}

<MethodEndpoint
method={"get"}
path={"/users/me"}
context={"endpoint"}

Retrieve profile information for the currently authenticated user, including their name, email, and avatar.

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The current user's profile information.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"image":{"type":"string","nullable":true},"localUser":{"type":"boolean"}},"required":["id","localUser"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Get Highlight.Api (`docs/docs/api/get-highlight.api.mdx`)


id: get-highlight title: "Get a single highlight" sidebar_label: "Get a single highlight" hide_title: true hide_table_of_contents: true api: eJylVm1v2zYQ/isH9ktrKHY6dFihDwPc9WVZCyxoEwxDGsBn6SyxpkiVPCVxDQH7EfuF+yXDUbIsJ27RYZ8kkHfH5+65e8itcjV5ZO3sWa5SVRD/qovS6KJklaicQuZ1LdsqVe+JvaYbAoSgbWEIyp0tLDegOcDZy6lKFGMRVHqlhlBBXScqUNZ4zRuVXm3VktCTnzdcqvTqur1OVI0eK2LyIRqErKQKVbpVvKlJpSqw17Z4AOqiJGis/twQ6Jws65UmD24FXI7wCSq6w6o2EkqTzs3dpqhuPz3/yd19+bG8Y3bZc4GuOZoM0M9y1SbK0+dGe8pVyr6hRFmsxKocWSVKC54auVSSj6dQOxsoSA4/nJ7K5yF0CUyBKT/EmjnLZFl8sK6NziJFs09BHI8Uxy0/USaM1V4IZd0du3RuXaFfC7f3C9kmKjB6/n21CsSjfdtUS/KyTzb/xm7mjPPHCCLbVEL/hoxxt0pKIeUpPJFViVqahqQfclphY1ilO8M2UUx3fCykbYzBpTAj9W8TZR3Tdxnq46k3gfxXqpJ5QqZ8fgRIe9AKV+P6HlZzXLs+qx5zRDScPz7t+kj3qbaVM5+dPn3YPpcWGy6d118oh3/++jt2/Is4V8BuTRZ0gEoHmdUEtL1Bo/MEnAe6qyWDe40mKGe1QX28xfb0DnM0RjAgffYQ6ZAOWMewco29f/b/afLM5Udb4RDDHCrMSm3pxBPm0iJA3jsP4j4V3isKAYvvClU2Fdr7gXr/6YMuiQD38Uc8vxLHWLl4PpeuF2FJUoQkVbNBF8JsO9KbVjqO/M1OLxtvVKq2mOeeQmhnWOvZzVOVqBv0WlDGWvXbHUW78SuZ65DOZuw30zV6XBPVU6zro1rbR9gp7NveHjoskstI6j8Ihb0UjQR/KLCcLHlEM5X2RqIR8ee18xUKwt/+uIhV1XblxF2y7iA9nZ5OT0e6PeCZn589wD9s6iB3GJnVSekCRw53o6xtAWhzEHJPNJ8YZPIxO53RFC5KHSQ2oEhWgI1rgB1UaLHYBwkJGB04JCBXYbLX9pAAhkDxa3NYYrZu6gC1d4XHqkLWGRqzmX60H+2jRyDlkjutmwxZnBsDZPPaacsB+i4DPJz7Ws7IQdtI0WLeD2kMsoCSMCc/hT9dAxlaKMjKE4AAbcxsTRtYeVcd8ntLS7g8g8bm5GEy+UDM2hYBfo4+b2kTJpMd7HMstB0gv9OBR5hDU9fOM2SND86fLFGg1oMH3GiERbe5iEVaGF1pXsDnhvwG9s8EIUMu0O6aBW0z0+QkzC4s3fEvfYiVJtPpo5QFNAOGri67Q4aQwuSKOCvjvgQRYDSFOSzkYlnADZqGYOX84Rna5sIRxcDChyewDirnI8DGcNjV5kXfInCxqSnI4m4lRDaWBM5SN16eCGRSQvrRnsBkYrRdTyYxlzlcvn839Bvcai7BxT5HA5nHW0M5VMSYI+O0cxeBH9yj0IMsiShTbxKbc2djoamNw5xyWGlD8FhX0uTOw/nL10+iZtYucIVRrvsn0RviI+/D+6O43Yv/f3hWdqIxuqfkIhfd2/ZqebV/kQWVqHT8PrtOlAy7GG230nWX3rStLMfGkmfoXiyjpOY6yH+u0hWaQN9I4fH7Xu6fwNdw9otoN1GT5Q2UKpWoNW3uPSTb6zZR3ZBGGJ3FPMuo5pHvgytThHe4Q968ulCJwkO5vSevMfpRXNttZ3EhctK2A8woLwKwbf8FIl9Czg== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single highlight"}

<MethodEndpoint
method={"get"}
path={"/highlights/{highlightId}"}
context={"endpoint"}

Retrieve a single highlight by its ID.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The requested highlight.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Highlight not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get List Bookmarks.Api (`docs/docs/api/get-list-bookmarks.api.mdx`)


id: get-list-bookmarks title: "Get bookmarks in a list" sidebar_label: "Get bookmarks in a list" hide_title: true hide_table_of_contents: true api: eJzVWdtuGzkS/ZUC5yGJ0ZaTxQx2oIcFlMxkxjvJjhHbWCwcAaK6S2pGbLJDsmUrQgP7EfuF8yWDIvsmuWW3Lw+zT3HUxapTFxaLh1umczTcCa1OEzZmS3QfhHVvtV5l3Kwsi1iCNjYiJxE2Zp/QGYFrBA45XwrFHSYghXWgFzCvl8G1cKlQ4FIEm2MsFqISG8F7bcBm3Dj/fxt1VnGDEOssL0jpwujMKyCxFxa+Fmg2IxYxx5eWja8YAbVsGjGLcWGE27Dx1ZbNkRs0k8KlbHw1LacRy7nhGTo01gvYOMWMs/GWuU2ObMysM0Itb3l6kSIUSnwtEESCypEPhrysMREWvOFZLkmLQJHIm80yu/7y49/1zbcf0hvndPwjARbOixDg04SVETP4tRAGEzZ2psCIKZ6RgAwCERMEIOcuZWV0F2JURUah4Dau8FM8ElzwQjo2Dr/sO3aujQNtEjQw30Bs0KcfEu5wBD+FtRachhe07sVoF/CCS4tPVtm4bLVxv9PC2muf5n63VZHNveCu8Y/8RmRFBuEzZUg4zLw5g64wCnI0VK04xJWHaOskLhNugAcHSu1dYaw2oeI55AbXQhcWDNpcK4tke4EuTn3pKbxxjf26tIKGAe493lTlahws3e/rXGuJXLFOPfYiOl2ARUeG/V7whuuW8MLCopASYq0cKgcvf734+CEChzcuAnTx6BVcCylhjiBULIsEE6jaTu3RCM6Ddm8cFtqAFMvUoWlELFynqEAruYEMHU+44yAsKMQEkyFF89f3oclfZeNdQLOXxyl5WimkVP7t9Wv6Z9fZyZ2dv7/rs4hV/pM+nudSxL5HnHyxpLSnfvT8C8YEMDd0RjkRIDWWOqLcGL4hV2in3q9CJLe3ZBkx37Ywmbjer5lOvD99nyOmCin5nLYiFUDZbMwBktzEqVhj0rN1yogt+FrT4Xbou+PLpVDLc8ddYe+31x4ZtohjtHTAL7iQhUEKE6qEVk3LiNkiy7gR33yWnl+90m5YeAKOzTBZXZh4gNrOwZkLFrFrnFOBSvo703Mh0R/tDpWlko+YFWopcRE+GO+WyHJtnPelsGhO+2sqzCrPXKhhJ/d84M7xOMXkbW+4Gp/JzbTIuGLTcqe3XZHFSv+ONi/X2cBa4e8LP03d7UD4ehiKFGoVQmhkf/wGb6OdHjVAXmR8iZd9Zg8JT6xF15fnvkqMDaKyqXYPWZUni4eI07FyRsBCB3mQJYOx4dcSk0csXosE9YOA8rWIB+YldZl811bavfJVVT4ETu35QAMk/fwNkBcu1WZYsoq5FDbFYdI0dJ9VK4bFg1Z8rI63AQv2WoaXDjt4SoPg0zoCjUU+Pv6PvpYQmvywndsPtbbxVKycai4kk/66uEfcNxHmd3m76MC5QUfNv3rb/MFjb2gvs+JbV21zqTq0sx4d5jYora/PEPVCrZS+7jm7/IJp2YT2+Q/eQWmmM+3XThPrHgZV9itN593f51wpNKdVjey1dlY1XZKr5l/f8FhPJ2dhILnMpeYJ0nnO19xxSnEbugdVWN+M0IZiWvYKtNP0zuzcmXd3htv9SbZ/AG1mrWqyaou0yfm0vRTXLBYjgHSXrW7JA7p4/6VZm91rcQTaAC0FsQClIdPGX9qI7Rix/bDMO6RaB00H8Fl9r2r5t9JH9/vXb27fwy5VOEPEN0zgj//+z2N76+kvcHqFiu5/mbA0vEYg1JpLkXjIeJMTqL1bGbXFk1xy0X8fawu94by6CBqk399GSsQXKO1goQu1b/Ypl8FYJ70FvH9hzXicCoXHBnlCaQY0Rhug5f56n6G1tPEGqPKD876iav3tnHuArf5Orn+mhT5o3r5LdcW/kpPE/I3ZiSdIT7aBFixPugVk0axrRtMPz2zLk8SgteUJz8XJ+g31DG4EofSxqj6H7NQEYepcbscnJ85sRitu+AoxH/E872VDKw01B/pbJQ8BC/nSIWPPKYXVlb1DyTYBJsu+N5IY3Wm9EDU4/8d7bTJOCP/57wsfVaEWmpaT1wHSm9Hr0esOB9bgmZyd3sLffBQWOFiUi+NUW+dzWMdVqCVwlQAl91i4Y8mJYSHvRIwjuEiFJd3ApdTXFja6IE4m44ovWyU2qnlt6lARpGKZerLGRhBaVOSNzHm8KnILudFLw7OMOxFzKTejz+qz+u47oHAR6xx2Bv04kRJQJbkWyhFj56sM+O6Wz8lGQyDNJtX+9EpmkCJP0IzgP7qAmCtYoiL2H4Er79kKNy3v3oTsGudweQqFIn736OgcnRNqaeEffs1vuLFHRzXsqoVVkP3GbzHbIqdLMwQO8XjOCWrerIC14DALH2c+SDNPrM4C9w8tkU/JaOmxmjejzM7azjqDhUAZWiOFBYQDbkNcaiONykPEJ0xgRh1+Bmsui8C97dgQKqEcoVdM+TB46yioYlN3daBz09KPTZ/32ZgjaIVhexlEoJ1ix5/VMRwd0VRxdOR9mcDlpw9NvfmnFtC+zrmEahZoOMBRWE69vVnue7wnIKkpYyXii7OWUVBU8wPQoAAv/fBKZ8fZT+9f+Z6Za+uIQxhva2rxF3S7RCD3W2F/L27b7v+XeE4K/ahz+rV8RGjEV/5hhrruuHmhaXvxNGLUSUhsu6WSvjSyLOnnQKpSh06EpU5zgD7uBuQRLym9Dqxws/e64uuXjZln64cDeth7yB1Y6jeSR+J4whvJYUzNY8YjQf0/8P53uH/rLaANw7SdHh5YwS8/VfPPKzhkvb6UqU3XZlso4ZmUbinhwPIIwsdJHGPehXprfCTozTz1y88XLHAtXfp8d9To8pi7kLbbIHFBR2tZNgj9UUsAy/JP7xni+g== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get bookmarks in a list"}

<MethodEndpoint
method={"get"}
path={"/lists/{listId}/bookmarks"}
context={"endpoint"}

Retrieve a paginated list of bookmarks within the specified list. For smart lists, bookmarks are computed from the list's query.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of bookmarks in the specified list.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["bookmarks","nextCursor"],"title":"PaginatedBookmarks"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get List.Api (`docs/docs/api/get-list.api.mdx`)


id: get-list title: "Get a single list" sidebar_label: "Get a single list" hide_title: true hide_table_of_contents: true api: eJylVtuO2zYQ/ZUB85IYWntTpEjghwLOFdvkIdjsoig2BjwWx9bEFKmQ1NqOIaAf0S/slxRDybe1GyzQJ8vkXA7ncmY2ylXkMbKzV1oN1ZziJw5RZUpTyD1XcqOG6pqiZ7onQAhs54bAcIgwXQPHAFdv+ypTEedBDe+UGAhqnKlAee05rtXwbqOmhJ78qI6FGt6Nm3GmKvRYUiQfkkDICypRDTcqritSQxWiZzs/gXJTENSWv9cErMlGnjF5cDOIRYtKsNAKy8qIFSbWZrWel8tvr1661Y9fi1WMLn8lgDkmEQF8pVWTKU/fa/ak1TD6mjJlsRQB0wpkigVAhbFQ8gBPoXI2UBDQv1xeys8pVrFJIZLegcudjWSjiGNVGc5T/AffguicCYSbfqNcclJ5yVbk1iPr02A1W8xnLo6gnUbZ1sbgVAIib28yxfk5wSYljqwE5DFWWoFTQbJ1KdVSoq3RqEyFEn2UstE0w9pENdzeNZn6XpNfP8pfVU8N5weiU+cMoRUrBYY3TuSdx+h8OC9VB/LXzvwUtVta8vJfc3Tycc+0TCed/3FzVE53kq0uN11kD+K40zoD8QDP+LhkVdOIkxeXz08L79ZiHQvn+Qdp+Oevv1NzvE4tCNEtyAIHKDlIM2fA9h4N6wycB1pVAvlBnUZaxUFlkM9X6D4+u747RLBD+uIUqbwErIswc7V96Pb/tEfu9NkUHrsfQYl5wZYuPKGWSgLy3nkQ9b6UQ0kh4PxRpoq6RPvQUKffVw8rIgHc2z/I7jtRTEFL/mPhOm5ORSMMqgZCJmGwaampkf4hf7/l0tobNVQb1NpTCM0AKx7cP5cyRc+CLUWou25zsu25IsYqDAeD6Nf9BXpcEFV9rKqzPNxZ2LLvx04eWizygoMx8EUS13o+HAa7sIpneUcSk5ZMQirrPt47X6Ig/P2PmxRLtjMn6vLqFtLz/mX/8oDYd3hGn69O8O8uOchUIzO7KFyIKXNT5xYl+gXbOaDVICm94HhhMJJPr+Oc+nBTcBDbgMa4ZYC1qyE6KNHifG8kZIn5QwYyITMoeF4YnhdygiFQ+rUappgv6ipA5d3cY1li5ByNWfe/2q/2yROQcMm8a/tBDkfGAFldObYxQFdbgMeNXokPDWxTiiajriuTkQkUhJp8H/50NeRoYU5W9gECtOllC1rDzLvyOL9LmsLtFdRWk4de7wvFyHYe4Lek85HWodfbwv6Mc7Y7yKnd95hDXVXOR8hrH5y/mKJArXYacM8Ik/ZykoI0MVxynEAaCLBfISQZMmvbiQxsc1NrksxOLK3im87EjMm0hChhAY6AoY3L1snOpGRyRjEv0r0YEWDUhxFMZOpM4B5NTTBz/tgHWy05omRY8uEJrIPS+QSwNjFsY/O6KxG4WVcU5HB7ElI2pgTOUttengikU8Lwq72AXs+wXfR66S0juL3+tKs3WHIswKU6RwO5x6UhDSVF1Bix36oLo+/UE7ODHAkVUyeSinMrY6GujENNGmZsCJ5yKUXuPHx++/5ZYsrKhVhiIulucfpA8XhjfNiFmz3bP27HbKniYBzJwBa223TMeJe2NZmbw25tG2dKGluuNhupsFtvmkaOu63ibrwnxkSfmoN8azWcoQn0E8xPrztCfwb/ha47RLtO/Gtq+acytaD1frVsxrKepF5MCNrLUZ5TFQ/UTuah8OtuQHx4d6Myhces+oBFk/WzkDabVuJGWKNpdggTiwjApvkXiRA7OA== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single list"}

<MethodEndpoint
method={"get"}
path={"/lists/{listId}"}
context={"endpoint"}

Retrieve a single list by its ID.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The requested list.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","nullable":true},"public":{"type":"boolean"},"hasCollaborators":{"type":"boolean"},"userRole":{"type":"string","enum":["owner","editor","viewer","public"]}},"required":["id","name","icon","parentId","public","hasCollaborators","userRole"],"title":"List"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Tag Bookmarks.Api (`docs/docs/api/get-tag-bookmarks.api.mdx`)


id: get-tag-bookmarks title: "Get bookmarks with a tag" sidebar_label: "Get bookmarks with a tag" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get bookmarks with a tag"}

<MethodEndpoint
method={"get"}
path={"/tags/{tagId}/bookmarks"}
context={"endpoint"}

Retrieve a paginated list of all bookmarks that have the specified tag attached.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of bookmarks that have the specified tag.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["bookmarks","nextCursor"],"title":"PaginatedBookmarks"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Tag not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Get Tag.Api (`docs/docs/api/get-tag.api.mdx`)


id: get-tag title: "Get a single tag" sidebar_label: "Get a single tag" hide_title: true hide_table_of_contents: true api: eJytVtuO2zYQ/ZUB85IYWntTpEighwJOc8E2eQgSL4pis4DH4lhiTJEKOdq1YwjoR/QL+yXFULLX63XTAu2TbM5weDhn5gy3yjcUkI13F1rlqiSeYakypSkWwTRiULn6SBwM3RAgRONKS8BYwmIDhiNcvMrAuMK22rgSuCJwbb2gAH4JC+9XNYZVhFY2guGxyhRjGVV+pWbyvc5UpKINhjcqv9qqBWGgMG25UvnVdXedqQYD1sQUYnKIRUU1qnyreNOQylXkYNxD0LOKoHXma0tgNDk2S9ODEoiMpSChNdaNlSCGjLbrTVnffnnx3K+//VitmX3xQuAaTi4zLC+06jIV6GtrAmmVc2gpUw5rsXOyZ8rI6Q1ypQR9oNh4FykK4h/Oz+XzEKiEpMikU2ZvDVfQRiwJIiObyKaIgrfwjsmxxMCmsaZI1E2+RAl0IjV+8YUKVplqghDNpodh9MP0dbt7nDK09csdkwcOPc/HDi83U2YsKtKz5PZPYNCcDFm1NboTlq67x8CVXGaAfgT0u7Cu7/E6hH12/vQhPZcOW658MN9Iw5+//5Hq52WqUmC/IgcmQm2iFLh0wg1aozPwAWjdCMgj4pjWPGksmtOU7av5rjYPEeyRPjtRSFiC8wxL37rjU/9LuRRen6iL436bQo1FZRydBUKNC0tAIfgAsn0slNYUpab/TajE/nGgYf9YHZdAAngX/4Db17Ix5Sydz5UfZE4uKS2aq4nI0WSburdTokbhZqc1bbAqV1vUOlCM3QQbM7l5qjJ1g8EIsr6Ce3NPyBJbyypXFXMT88mEw2a8woAromaMTXNSp4YIO3V6N/hDj0XwH8jkJ6GtP/lQLPdJlZPlHslN5YOTyoYfb3yoURD+8ussZdK4pZftcuse0tPx+fj8QPn2eKYfLh7g3xtNlPlAdnlW+ciJt53+i/aj0yCEnhk+s8gU0u1MQWOYVSZKbEBr/W2EjW+BPdToRAL3QyQDayLHTDQyZlCZsrKmrGQFY6T0dRoWWKzaJkITfBmwrpFNgdZuxp/dZ/foEUi6ZB703SCLU2uBnG68cRxhqCzA+13eyBkajEsUzadDS6Ygc6gINYUx/OZbKNBBSU4GKwG6dLMVbWAZfH2f31tawOUFtE5TgNHoEzEbV0b4Ke15R5s4Gu1gf8DSuD3k9ybyAebYNo0PDEUbog9nCxSozX4H3BiEeW+cpyTNrakNz+FrS2EDdyNWyJBx1A+tYbCTMDt3tOafhxBLQ7ZXQ0kLGAaMfV52h+xDCpNL4qLq3wa0ZgFGY5jC3LXWzuEGbUuw9OH+GcZp4YhSYOEjEDgPtQ8JYGs57nKzU3kQbY+yuNf9xMaCwDvq2ysQgXRKzD+7MxiNrHGr0SjdZQqXH9/v660fwz7VOVooAt5a0lATo0bGcb9d5Hy/Pck6yJIIMQ0uqTh3Pg7axnrUpGFpLMFjU0uR+wAfXr15knSy8ZGH4Tc8Ld4S33t7HTfh9k7q//fHWi8qB1Ory3pd3A4KetU/6DKV9y+g60yJAIhhu5VKvAy262Q5FZs86+4ENMmsNlF+a5Uv0Ub6zuUefxxk/wn8HbZhEd0m6bRt5Z/K1Io2+0dady0vjNSyCUBvmxYFNXyw68HQFBneT5G3r2cqU3hffI/ENkU/iWi77T1mIi5ddwdQ/gvArvsLHy8NAA== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get a single tag"}

<MethodEndpoint
method={"get"}
path={"/tags/{tagId}"}
context={"endpoint"}

Retrieve a single tag by its ID, including the number of bookmarks using it.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The requested tag with usage statistics.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"numBookmarks":{"type":"number"},"numBookmarksByAttachedType":{"type":"object","properties":{"ai":{"type":"number"},"human":{"type":"number"}}}},"required":["id","name","numBookmarks","numBookmarksByAttachedType"],"title":"Tag"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Tag not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Karakeep Api.Info (`docs/docs/api/karakeep-api.info.mdx`)


id: karakeep-api title: "Karakeep API" sidebar_label: Introduction sidebar_position: 0 hide_title: true custom_edit_url: null

import ApiLogo from "@theme/ApiLogo";
import Heading from "@theme/Heading";
import SchemaTabs from "@theme/SchemaTabs";
import TabItem from "@theme/TabItem";
import Export from "@theme/ApiExplorer/Export";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Karakeep API"}

Karakeep is a self-hostable bookmarking and read-it-later service. This API allows you to manage bookmarks, lists, tags, highlights, assets, and backups programmatically.

Authentication

All endpoints require a Bearer token passed in the Authorization header. You can generate an API key from the Karakeep web UI under Settings > API Keys.

Pagination

List endpoints support cursor-based pagination via cursor and limit query parameters. The response includes a nextCursor field — pass it as the cursor parameter to fetch the next page. A null value for nextCursor indicates there are no more results.

Bookmark Types

Bookmarks can be one of three types:

  • link — A URL bookmark with optional crawled metadata.

  • text — A plain text note.

  • asset — An uploaded file (image or PDF).

    <Heading
    id={"authentication"}
    as={"h2"}
    className={"openapi-tabs__heading"}
    children={"Authentication"}

    <SchemaTabs
    className={"openapi-tabs__security-schemes"}

    <TabItem
    label={"HTTP: Bearer Auth"}
    value={"bearerAuth"}

Security Scheme Type: http
HTTP Authorization Scheme: bearer
Bearer format: JWT
text
</TabItem>

Docs Api List Backups.Api (`docs/docs/api/list-backups.api.mdx`)


id: list-backups title: "Get all backups" sidebar_label: "Get all backups" hide_title: true hide_table_of_contents: true api: eJy9VsGO2zYQ/ZUBc2kNrb0pevKhgDdtgm1SIEh2URTJAh5LY4kxRTLk0LuOIaAf0S/slxRDybJ310B76kkCZzh8nHnzhnvlPAVk7ex1pebK6MhXWG6Sj6pQFcUyaC9WNVcfiIOmLQGCuIFbAxoDq94d1i4ANwSYuCHLukSmClKkUIC2pUmVtrV46ACRkVMEtBW0xFgh41QVirGOav5JHRDcFSpSmYLmnZp/2qsVYaCwSNyo+ae77q5QgaJ3NlJU87364fJSPo9RL86BlcNKZ5ksyw703ghe7ezsS5RtexXLhlqUP955UnPlVl+oZFUoHyRnrPtDh4gnjhgC7lShNFMb/z2Ark58Igdta9UVShJ3fd6EMRKfsxXKJmNwZUjNOSTqClUGkjos+GykqL/RicGmdkVBDCvnNi2GzSuXLJ/16Et4DgPZ1EoVPdmqX4mpLCkKo9aoTQqk7rpCUQgu/EYxYk3/4S6dVPtr0oEqia4rNSbpmJLTCw/Xe3qZEfpd9zTmoZZi6Qr14+XL53y6tUJwF/Q3quDvP//KnL/KxAR2G7KgI7Q6Rm1rIf4Wja4KcAHowctBT7jH9MAzb1CfZ90xqw/YeknGIwSq66G2xI2TBq4pMwylRdRsNbZypLClEHMbpWDUXO2xqgLF2M3Q69n2pSrUFoOWjOeyDuY+A2tMhtVcNcw+zmczDrvpBgNuiPwUvX8mFjeiBH0E6T1J0tvBH3osAv2kwT/KzYeWOmnzMRFystwju6n54CTVzT+vXWhREP76+42SjGi7drJdbt1Dejm9nF6KymjOeRzxLN5fP8M/GnUEhEhmfdG4yJIdOPBJ9EwkLBBWF5ovDDKFfDtd0hRuGh0ltgiPu4+wcwnYQYsW62OQWGSBigWI+hXQ6Loxum5kJbNavrYaZdYHVwdsWxSFNWY3/Ww/2xcvYHGUXe2sLC6MAbKVd9pyhIHngI/J6uWMCrTNJVouBmblIEtoCCsKU/jDJSjRQk1WpgUB2nyzDe1gHVz7uL73tILba0i2ogCTyUdi1raO8FPe85Z2cTI5wH6PtbYj5Hci1UfMMXnvAkOZQnThYoUC1Y87YKsRlr1xmZO0NLrVvISvicIOPAZsiSlEKQbBYVgM44iksktLD/xqCLHWZPqmlrSAZsDY5+VwyBhSKrkmLptslyACjKawgKUI1xK2aBLlqfjoDG2rPBpzYKlHILAOWhcywGQ4HnJzNVAEbnaeoiweVmKuxorAWerbKxCBdEqcf7YXMJkYbTeTSb7LAm4/vBv5BveaG3CZ52igDHhv6GQM99tFlcbtWZ1AlsA6psElk/PgYyF547CiCtbaEHynWyG5C/D+59ffT2VgeBe5xaxyFnMLvyE+HcpPe3B/lMn/4+3Ry8yJHMsQFqXcD3J6Mh8KJWIgS/u9sPI2mK6T5Uw8eZwcxTQ/VQrVt1LW3w3t5GFSluQ5q65J+d3w9BUi8jgK+5tfbmTOPRbFJyKYox9eIXZ3Enu/7z1upOm7ThUDiCwCqpOB9w8jvIXe sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get all backups"}

<MethodEndpoint
method={"get"}
path={"/backups"}
context={"endpoint"}

Retrieve a list of all backups for the authenticated user, including their status and metadata.

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A list of all backups.","content":{"application/json":{"schema":{"type":"object","properties":{"backups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"assetId":{"type":"string","nullable":true},"createdAt":{"type":"string"},"size":{"type":"number"},"bookmarkCount":{"type":"number"},"status":{"type":"string","enum":["pending","success","failure"]},"errorMessage":{"type":"string","nullable":true}},"required":["id","userId","assetId","createdAt","size","bookmarkCount","status"]}}},"required":["backups"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api List Bookmarks.Api (`docs/docs/api/list-bookmarks.api.mdx`)


id: list-bookmarks title: "Get all bookmarks" sidebar_label: "Get all bookmarks" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get all bookmarks"}

<MethodEndpoint
method={"get"}
path={"/bookmarks"}
context={"endpoint"}

Retrieve a paginated list of all bookmarks for the authenticated user. Supports filtering by archived/favourited status and sorting by date.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of bookmarks.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["bookmarks","nextCursor"],"title":"PaginatedBookmarks"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api List Highlights.Api (`docs/docs/api/list-highlights.api.mdx`)


id: list-highlights title: "Get all highlights" sidebar_label: "Get all highlights" hide_title: true hide_table_of_contents: true api: eJy1V1GP2zYM/iuE9rIFvtx12FMeBqTb2nXtsKK9wzBcA4SxmViNLKmUnLssMLAfsV+4XzJQdhznklu7FXvKQZbIj+THj7ydcp4Yo3b2RaEmyugQf9Sr0uhVGYPKVEEhZ+3lgpqoNxRZ04YAweNKW4xUgLwBtwQ0Bsr+LWDOLoR0unBuXSGvAywdQywJsI4l2ajzZKEOxGOVqYiroCa3aoBglqlAec06btXkdqcWhEw8rWOpJrezZpYpj4wVReKQLoS8pArVZKfi1pOaKFtXC+KTUH7Ge13VFbSfBb+OVAWIDphizRY8sURJY9VkiulDrZkKNVmiCfQ51jJlsaKU7EpHlSktFj7UxFvVZGciCJG1XZ1E8F3NwTEs2VVSD6aNdnUApuCdDSS+lxTzMiXc0n3s/UcdDfUWPiG8/+6qCzVvPR3HOhO/rYUg4X59dSU/x66nZ5h2YJm4yJ2NZKM8Re+NcEo7e/k+yPsz6XSL95RL3j0L+aNuvR+MDu4iM24FtlTz4zb2RJdeeli+JlMhIsdflstA8ZSgTabIFv/wNXfG8TlakK0raZstGePulGS1UJlaMZFVmVqYmqSPClpibaKa7C82mYp0H8+ZtLUxuBCSRK6pyZR1kT7poj4furT4I1nJmaS60zNAmiNq3g7ze5zNYe66qDrMCVHvf+htdmiEXnCSRyFw1xofjfixTul0ru+FDByDPAW9BOugckzSP7UREj+MsxxK8ADOAPLrfVcMxLJpxNA3V09O2+jGiuQ61r9TAX/98WdC9zSJKUS3Jgs6QKVD0HaVgbYbNLpIoOneC6wHnSYpvvQG9fkeO3DzHiufAA8RJKRNpiqKpZO5s0p18yiyri6Pwg/Em72412zURO2wKJhCaC7R68vNE5WpDbKWoqQu7D63SdhzvozRh8nlZeTteI2MayI/Ru9PZPVaxlNrQbRG8vSyuw8tFkE/mEtvJfiu/wfTqc+FeJY40jU16S5JY6Y/njmuUBD+9Ot1IoK2SyfPJeoW0pPx1fhqoNs9nunrFyf4+486AEIgs7woXYiSnX4Qa7sCtAUwYXGh44XBSJyi0zmN4brUQWzL8HZ3AbauFomv0OLqYCRkSZBDBjK3s4EqZ4AhUPq1BSwwX9c+gGe3YqwqlLFvzHb8zr6zX3wB08MuoJ2Vw6kxQLbwTtsoUyY1BuAxX734KEDbVKL5tCNXMjKHkrAgHsNvroYcLazIyp5DgDZFtqZtO86O6ntHC7h5AbUtiGE0eksxarsK8G1685K2YTTaw+4asIP8SkbTAXOovXccoZ17FwsUqL5/ARuNMG8/zlOS5mkZmEMajXDYaaQYdBi02uamLkgqOz/owhyWmkzb15IW0BEwtHnZO+lNPjasYQpzEag5bNDUlCTsyIe2RdrXkmGpB9OJknW5edpRBK63noIcPu1XQKnGgsBZatuLiUA6JUze2QsYjYy269EoxTKFmzever7BnY4luMRzNJAz3hkqoKKIBUYct89FmPrnSaBAjkCGQXclkXN/x0LtjcOCClhqQ/ClroTkjuH198++SrufdyFWmISuW2eeU3yw7j5sw91BLP/3rbmVmYEiy7wVpdx1ino0UGaZEj2Q091OiHnDpmnkuF3LRGcLHUQvHlkHh7H9u8X3LNQ1bQfLcCKfmqi0Cn86js9Yhh/H1G+tB1Czw6xJ/4BkqlWalLb21TTPyQ9DOdlKxUo/+p7/cK0yhccz48GMSNb3K6ndDmzvdu2Na9HEplF76EkjVTNrmuZvOTne2g== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get all highlights"}

<MethodEndpoint
method={"get"}
path={"/highlights"}
context={"endpoint"}

Retrieve a paginated list of all highlights across all bookmarks for the authenticated user.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of highlights.","content":{"application/json":{"schema":{"type":"object","properties":{"highlights":{"type":"array","items":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["highlights","nextCursor"],"title":"PaginatedHighlights"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api List Lists.Api (`docs/docs/api/list-lists.api.mdx`)


id: list-lists title: "Get all lists" sidebar_label: "Get all lists" hide_title: true hide_table_of_contents: true api: eJy9Vs1uGzcQfpUBc2mFtWQXPelQQEmbwE0OQWKjKGwBGi1HWkZckiFnZW+FBfoQfcI+STvc1Y9toe2pJ63I4cw3f9/MTvlAEdl4d63VVFmT+INJnFShNKUymiB3aqo+EUdDWwK0Fpbeb2qMGxD5BCsfgSsCbLgix6ZEJg1NoliAcaVttHFrWHquoEbXoAV0GlKNkXsNY1UoxnVS0zvVm58XKlHZRMOtmt7t1JIwUpw1XKnp3bybFypSCt4lSmq6U99dXsrPU8gzaweA/sGRhmULPkKqMJKGB8NVBl02MZLjDFdwlN4xORZ1GIIVZ4x3ky9JdO5UKiuqUb64DaSmyi+/UMmqUCFKLNn0iLLhEzGMEVtVKMNUp39/bvSJTOJo3Fp1hXJY09mLJ54/vy+Ua6zFpSU15dhQVyhTnhPsChVQonF9xvwZLb3AS0FyTS257LOtCpVzLUnVtMLGspru77pCfW0otv/JXmiW1pQnokvvLaETLRWmN17kfUT2MZ2Xkix/8vYfUUu1RPmvDXv52Bp6yCeD/XnXSf19bUwkLS+MVkNuhsiexPHw6gzEEzzzQrFhAZY7QHXPbfQFNe/yxfeXVy/r/dZJA/pofvu72P/8/Y9c3q9z4wD7DTkwCWqTknFracwtWqML6Ql6DGLmWfkzPfIkWDTnC/8Yt0esQ0Z+ikA8EKg1ceWFW9aUyxylhdXEDiyTKG5JsnW3U020aqp2qHWklLoJBjPZXkkCMBophJzU4br3f19NFXNI08mEYzveYMQNURhjCC947EZ4qtcAfpVD9H6Qhx6LAD+hn8/id2/5lIQOYRDL4kcWk2LLQqoYPt76WKMg/PmXGyXxMG7l5bl43UO6Gl+OL9Ux/wc8s4/XL/AfLk0ChER2dVH5xBKdAy0L2wrDRkJ9YfjCIlPM3pmSxnBTmSS6hcr9Q4LWN8BeqBnXRyWp6MmzAGHmAiqzrqxZV3KCKVH+dRqWWG6akCBEv45Y1yj8b207vnf37tUrmB2HgvFODoWXyengjeMEQ40DPi3VIDY0GJdTtJgNdZWVLKAi1BTH8KtvoEQHa3IyxgjQZc821MIq+vppfh9oCbfX0DhNEUajz8Rs3DrBD/nNe2rTaLSH/RHXxh0gS0ueYE5NCD6yzI7k48USBWo4vICtQVj0l4scpIU1teEFZKqDgBFrYopJkkGwH2XDsCTJ7MLRI78ZVKwM2b6lJSxgGDD1cdkbOaiUTK6Iy364iRIBRmOYwUL4dAFbtA3lmf3EhnE6D+6sWPIRCZyH2scMsLGc9rF5vR//N22gJIf7k5SzsSTwjvr2ikQgnZKm9+4CRiNr3GY0yr7M4PbTh+MukSeyz3WOFsqID5Y01MSokXHcPxdOOjzP3ARyBM4zDSK5OPcyDppgPWrSsDKW4BtTS5H7CB9/fPvtOE88n7jGzHH9eFXviPOaY89tQrsjRf4PS1HPMSdMLDNMaHI3MOlhMBRKeEAOdjspyNtou06Oh/F6Nz/yaN6hCtV3UabeDbWyMZUlBc6Ea5u8tTzfgIQZD4z+7qcbVSh8yofP+C9r3+9Arj3Rvdv1EjfS712nigFE7n/VyaT7C6UyuQc= sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get all lists"}

<MethodEndpoint
method={"get"}
path={"/lists"}
context={"endpoint"}

Retrieve all bookmark lists for the authenticated user, including both manual and smart lists.

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"All lists owned by or shared with the current user.","content":{"application/json":{"schema":{"type":"object","properties":{"lists":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","nullable":true},"public":{"type":"boolean"},"hasCollaborators":{"type":"boolean"},"userRole":{"type":"string","enum":["owner","editor","viewer","public"]}},"required":["id","name","icon","parentId","public","hasCollaborators","userRole"],"title":"List"}}},"required":["lists"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api List Tags.Api (`docs/docs/api/list-tags.api.mdx`)


id: list-tags title: "Get all tags" sidebar_label: "Get all tags" hide_title: true hide_table_of_contents: true api: eJzNVs2OGzcMfhWCubTGrL0peppDAW/aBGlyCBIvimLXgOkZ2qNYI00kjXcdw0Afok/YJykojf+dzaKnnrw7osiP5KePXKNt2FFQ1rwtMUetfBjR3GOGJfvCqUaOMMePHJziJQNBQ3NlKHAJYg12BqQ1BJr7Pnxqm8a64GGmdGCnzBymKzBUcwYUAhUVl1fTFXjbukK+mRK8deHIsPU0Zyhsa0IG1oFjzUsyBfcxQ4mD+R1GlOMMPRetU2GF+d0ap0yO3bANFeZ34804w4Yc1RzY+Wjgi4prwnyNYdUw5uiDgMRNho6/tMpxifmMtOcMBQzm8eeVNYGUkbIoqcaXlt0KN9m3HWbIpq0FaHSTYUwKJUyXjIAveUatDph3x0/AkCr9l/CkMMOqrclghsYaxvETUbY9ulk9P9YT7orWeeue4cq09ZTF0LRa01Qz5sG1/IRrrWp1WpCxmPvGGs9enP90fS0/x0weXiCwkAoeVKgOueeFboU1gU0QN9Q0WhXxrQw+e/F1IRE7/cyF4GqcvKygEpLE2p0VOUexwoFr//3bqrxY9VSJSwdtfWPtoia38OdFPjG4WQ27po+i2ffAkLroMlHs/GSzOWrinSSTbR/FEdAnYY0zDCoIL+Tlozg1/BheJYJd4P8xkU7lLN2DmXUQKgZxJbTgqDdyFdQMjIXaOgbHvtVCh9NUQlLKAyDjlO/P1y/PiXdrqA2Vdeorl/DPX3/HyDdRsSDYBRtQHmrlvTLzDJRZklZlBMSPjYQ84WPgxzBoNKnLTNwrwSPVTazcIYLYmU2GNYfKivTPOfaaRDtx0KXm2S232tk6jTmuqSwde78ZUKMGy5eY4ZKcklIneqTjlP5W3aoQGp8PBsGt+gtytGBu+tQ0Z2NmVDF0HuK7rBjedfaQsAjuA9n/JGmnyIfiv6uCRJY8ohnmnRFm3R+vratJEP7+xyi2V5mZleuSdYL0sn/dv8Y9/XZ4hh/enuHfHSoPBJ717KqyPkh1YNpRW2adzD3HVF6pcKUpsIvZqYL7MKqUF98yVe2Dh5VtIVioyYgybZ34LIqXz6J2ZVCpeaXVvJIv5D3HX1PClIpF23honJ07qmsKqiCtV/17c29evAApF5vQ6Zp8HGoNbMrGKhM8dHQHOmZqIzFKUCa2aDLsaBWdTKBiKtn14U/bQkEG5mxkyWAgEzNb8ApmztbH/X3gKdy+hdaU7KDX+8RB1gIPv8Q773jle70t7A9JwjvI70XG95h9WkIgTZ+rKQnUZncDlopgkg4nsUiTOEwmEMcI7FcGaUZ8/nGkgDKFbkuWzk72b34CM8U6vWgpC6gA5FNdtkF2LqWTMw5FdSw7fRjCRGRnAkvSLUdhOoqhTCk94uhY+uH4TJ+62mwlFEQ4vXzciWrsxpTBGk7PyzGDvBSf35sr6PW0MoteL+YyhNuP73d8S9PRRp6ThsLRg+YSag5UUqB+ui6StLsepQnkExgbuDOJ5NzaGGgbbankUhZGhh9ULSS3Dj78+vrHvsyVxvrQTZZu8r/hsNs4Tx/gei+Q/6OVNUnRgV5vsqSm605vu1EyzlDUQv5fr4W2t05vNvI5LTiiwqXyoib7fWjBq/MtNbIIc4zb1jeudBvlc0yP1sLnXNgtfs8x3q5ye9vxfqjERT7DJCmxAunSsCi4Obx1tp6Jl910e/PbCDOk4+FwMgyi9+2GZg5TXa+TxUjEb7PBLfIohriRqf8v9k2eOw== sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Get all tags"}

<MethodEndpoint
method={"get"}
path={"/tags"}
context={"endpoint"}

Retrieve a paginated list of all tags. Supports filtering by name, attached-by source, and sorting by name, usage count, or relevance.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of tags with usage counts.","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"numBookmarks":{"type":"number"},"numBookmarksByAttachedType":{"type":"object","properties":{"ai":{"type":"number"},"human":{"type":"number"}}}},"required":["id","name","numBookmarks","numBookmarksByAttachedType"],"title":"Tag"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["tags","nextCursor"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Remove Bookmark From List.Api (`docs/docs/api/remove-bookmark-from-list.api.mdx`)


id: remove-bookmark-from-list title: "Remove a bookmark from a list" sidebar_label: "Remove a bookmark from a list" hide_title: true hide_table_of_contents: true api: eJzlVtuKG0cQ/ZWi/WKLWWkdHGLmISDHa9jYBGPvEsJaoNJMSdNWT3e7L1rJYiAfkS/Ml4TquUjaXTsOhLzkabU9dTl1O1V7YSw5DNLoy1LkwlFtNvTCmHWNbv3KmfqN9EFkoiRfOGlZUOTiXRIDhEUnCUtnakCoUUdUoKQPY5GJgCsv8hvBRryYZcJTEZ0MO5Hf7MWC0JGbxlCJ/GbWzDJh0WFNgZxPAr6oqEaR70XYWRK58MFJvboH56oiiFp+igSyJB3kUpIDs4RQ0YCFtlhbxVYkyVJtd6v69uPzH8z28/fVNgRTPGfAMiQRBnxZiiYTjj5F6agUeXCRMqGxZgHVCmRCMgCLoRJN9i8h7pP6j1H3dfsq8sVB6AT9jDW8NdqT5wC+O3/Gf05x/2KgMDqQDvDn73+coIVb9ND2T9m2Q5998LEoyPtlVGo3ZmjPzs/v2+7Rg/SgTQCpT+rX+WU9tFbJInXt5KNn5QcybxYfqeDWtY57PMg2rMKU9Pf1mUKNRSU1nTnCEheKgJwzDlg9hVCT97j6JlNVrFHfNdTpj0VzUqqbFuDB/uxQ3gtWFE3TpAw+vZ/Ba40xVMbJz1QO9XmRpgyCWZPm1NbSe6lXGUi9QSXLDIwD2lr2fyfPgbZhYhXKhzM8BHxo0mMEA9IH+ojni/0OzcMFX5qo70L435c6+Q+VYXYuSVFgjTSxuZjwbPjJviWjZtJn00/2hylvBNOu2/SkGp0SudhjWTryvpmglZPNU5GJDTrJqFPuus9t5ZYYVRC5qEKwPp9MgtuN1+hwTWTHaO2D9NZZ6EntdScPLRaO7WgfvOeStp6Pt8KQcPbMcSQxJrEkJLLuxyvjamSEP/96lbIs9dKwOkfdQno6Ph+fH3HlgGf69vIe/uGj9IDgSS3PKuNDqmmfWalXgLoELvaZDGcKA7kUnSxoDFeV9GwbUClz62FnIgTDCxJXByM+S/zmM+BVmUElV5WSq4pf0HtKf3UJCyzW0Xqwzqwc1jUGWSCz6Qf9QT96BJwuXiPtpPDjVCkgXVojdWBeTl0HeEoHln2UPdPOp93sJiNzqAhLcmP4zUQoUMOKNN8KBKhTZGvaHYh+SNktLeD6EqIuycFo9J5CkHrl4cek85p2fjTqYb/FldQD5EQKB8w+WmtcgCI6b9zZAhmqHTRgIxHm7cd5StJcyVqGOXyK5HZwuCW4GAT9cgOpCxVL4srONW3DT52JpSTV0ianBWQA9G1eeieDSa7kkkJRpe9shIHRGKYw11GpOWxQRYKlcac+pC65RpQMcz0cgTZQG5cARhV8n5thHV7tLHl+7F98qsaCwGhqx8sRAU+Kzz/oMxiNlNTr0SjFMoXrd2+OlrQMFZjU56igcHirqISaApYYcNyqM+8P6on/gZ+YpKkTSc3Zy2iIVhksefFLRfBY1tzkxsHbl6+eJA61xocaE313d8gXb0j1wMW5P+yEbz8+W+o4WmJN1rLfviPQm3TGeZGJfLjnhsnk16NbaZYJpgBW2u+5F6+dahp+Tu3GF+yBQhPRltLz71LkS1SevhLR43fdUngCX8LdPaLeJaZWkf8TmVjT7nCN8gX6H3o9yk4zazLR8kWKvRWYFgXZcKR6b5vzDhjW28uLNxdXFyITeEr+d8g+OXgQ2X7fSlwxuTXNADSRHWNsmr8ApAaEbg== sidebar_class_name: "delete api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Remove a bookmark from a list"}

<MethodEndpoint
method={"delete"}
path={"/lists/{listId}/bookmarks/{bookmarkId}"}
context={"endpoint"}

Remove a bookmark from a manual list.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — the bookmark was removed from the list successfully."},"400":{"description":"Bookmark is not in the list.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List or bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Replace Asset On Bookmark.Api (`docs/docs/api/replace-asset-on-bookmark.api.mdx`)


id: replace-asset-on-bookmark title: "Replace asset on a bookmark" sidebar_label: "Replace asset on a bookmark" hide_title: true hide_table_of_contents: true api: eJy9VttuGzcQ/ZUB+5IIa8kpUjTYhwLKDXATtIZjoygcARrtzmoZcUmG5FpShAX6Ef3Cfkkx3Isky0lT9PJiyNy5nLmdmZ0wlhwGafRFLlLhyCrMaOo9hZ/1c2NWFbqVSEROPnPSsqBIxVUrBqiBNtIHqZeArANGA8Ki04O1DCUg5LIoyJEOYB3dSVN7tYXaKoM55a3iWCQi4NKL9Fb0br2YJcJTVjsZtiK93YkFoSM3rUMp0ttZM0uERYcVBXI+CvispApFuhNha0mkwgcn9fIkgOuSoNbyY00gc9JBFpIcmAJCSQN8xkQbrKxiS5JkrjbbZbX+8Ox7s/n0XbkJwWTPGLgMUaQHfpGLJhGOPtbSUS7S4GpKhMaKhRZ7oURIBmMxlKJJ/iX0Qzr/FvRY8S/ixk7iCPSsFScfnpt8y8hPkV687KFpWndtEgx0rRY/DE1kNDH0zOhAOrA9tFbJLHbo5INnow/kySw+UBZEIqzjfg6SfNTtIH9VQj8Ds/acUsAeb0U6jEVzlKfbwdOsadpP3hrtWxTfnj89TcxPBrog4Y/ffu/crdH3bnLwdZaR90Wt1HbMdXl6/uTUzo3GOpTGyU+UR0scwPM4JhDMijRID5X0XuplAlLfoZJ5AsYBbSyjv5fuQJswsQrlw4ke8rdvrkMEog3/6UMR98PBvttwtQlQmFrfx/BPSp6ZnP663lOoMCulpjNHmONCEZBzxgGrx2RX5D0uv8pUWVeo7xvq9E87JQLc25/tR/AVK8YMRv+hNMzIto5B8rSlYtKTh5/s9jzSTGI+/WTXtWEjmDfdXc+KtVMiFTvMc0feNxO0cnL3RCTiDp1k0O20tJ/byhVYqyBSUYZgfTqZBLcdr9DhisiO0doHR6iz0M/Rm04eWiwc2gGhv+OKtp4PaX3IN3vmOKIY82YUEkn347VxFTLCH3+5jknmTrnac9GrvkEPaKCvYcMcVhj+xjlqA3gyPh+fHzDigH56eXES7fBRMjV4UsVZaXyIDdAXJi5FnQN3xpkMZwoDuZgLmdEYrkvp2TagUmbtYWtq5psKNS73RnwCSvrgE+DtmEApl6WSy5Jf2qon0ckCs1VtPVhnlg6rCoPMkJnjvX6vv/kGOLm8Kdqx4sepUkA6t0bqwLQTWxTwmDws+8hB6ljQ+bSb9GhkDiVhTm4Mv5oaMtSwJM3HRLwLOLIVbaFwpjruhjUt4OYCap2Tg9HoHQWmfg8/RJ03tPWjUQ/7EpdSD5DfSh8OMPvaWuMCZLXzxp0tkKHaQQPuJMK8/TiPSZorWckwh481uS3sTwcuBkFP2iB1puqcuLJzTZvwojNRSFItyXJaQAZeDDEvvZPBJFeyoJCV3ULZBAZGY5jCXNdKzeEOVU1QGHfsQ+qca0TRMNfDEWgDlXERYK2C73MzEOr11pLnx+FwitVYEK/TdhgdEfBc+fS9PoPRSEm9Go1iLFO4uXp772Qzsc9RQeZwrSiHigLmGHDcqvOWGNTjtgB+YkanTiQ2Zy+j99deIRXBI1lxkxsHly9fP46Ea40PFUau7w6O4cg8PSzvz+Nuvz7+q9u0JaWD9dgkLa/uOnK+HS47LxKRHp157aTy83AoJIIJg9V2O+7cG6eahp9jc/J5u6fnSOK59Pw7F2mBytMXMvDoqts3j+FzyLtH1Nu4BVTN/4lErGh7fKLyWfo/eu7T08yaRLT0EoNvv75oHZ1xwx9on9wLDLrVmGYZ2XAgewhmdrBmL2+uebV0R2wVrwjhcC2S+DdCbKcibqz4thMK9bKOZ4JoHfMiwuM9dm9vxXAeTMJu10pcM/M2zZCTyMSckab5E6WWyl4= sidebar_class_name: "put api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Replace asset on a bookmark"}

<MethodEndpoint
method={"put"}
path={"/bookmarks/{bookmarkId}/assets/{assetId}"}
context={"endpoint"}

Replace an existing asset on a bookmark with a different previously uploaded asset.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The ID of the new asset to replace the existing one.","content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","description":"The ID of the new asset to use as a replacement."}},"required":["assetId"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"204":{"description":"No content — asset was replaced successfully."},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark or asset not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Search Bookmarks.Api (`docs/docs/api/search-bookmarks.api.mdx`)


id: search-bookmarks title: "Search bookmarks" sidebar_label: "Search bookmarks" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "get api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Search bookmarks"}

<MethodEndpoint
method={"get"}
path={"/bookmarks/search"}
context={"endpoint"}

Full-text search across all bookmarks. Searches bookmark titles, content, descriptions, and notes. Results default to relevance sorting.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"A paginated list of bookmarks matching the search query.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"attachedBy":{"type":"string","enum":["ai","human"]}},"required":["id","name","attachedBy"]}},"content":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["link"]},"url":{"type":"string"},"title":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageAssetId":{"type":"string","nullable":true},"screenshotAssetId":{"type":"string","nullable":true},"pdfAssetId":{"type":"string","nullable":true},"fullPageArchiveAssetId":{"type":"string","nullable":true},"precrawledArchiveAssetId":{"type":"string","nullable":true},"videoAssetId":{"type":"string","nullable":true},"favicon":{"type":"string","nullable":true},"htmlContent":{"type":"string","nullable":true},"contentAssetId":{"type":"string","nullable":true},"crawledAt":{"type":"string","nullable":true},"crawlStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true}},"required":["type","url"]},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"sourceUrl":{"type":"string","nullable":true}},"required":["type","text"]},{"type":"object","properties":{"type":{"type":"string","enum":["asset"]},"assetType":{"type":"string","enum":["image","pdf"]},"assetId":{"type":"string"},"fileName":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"size":{"type":"number","nullable":true},"content":{"type":"string","nullable":true}},"required":["type","assetType","assetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["unknown"]}},"required":["type"]}]},"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"assetType":{"type":"string","enum":["linkHtmlContent","screenshot","pdf","assetScreenshot","bannerImage","fullPageArchive","video","bookmarkAsset","precrawledArchive","userUploaded","avatar","unknown"]},"fileName":{"type":"string","nullable":true}},"required":["id","assetType"]}}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId","tags","content","assets"],"title":"Bookmark"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null if no more results."}},"required":["bookmarks","nextCursor"],"title":"PaginatedBookmarks"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Docs Api Summarize Bookmark.Api (`docs/docs/api/summarize-bookmark.api.mdx`)


id: summarize-bookmark title: "Summarize a bookmark" sidebar_label: "Summarize a bookmark" hide_title: true hide_table_of_contents: true api: eJzNV9tuGzcQ/ZUB85IIa8kpUjTQQwGlbQA3AWrENorCMaDRcrTLiEtueJGtCAv0I/qF/ZJiuBdJltIaaB/6pDU5nDlzOzPeCluTw6CsuZBiKnysKnTqC72xdlWhW4lMSPK5UzXLiKm4dqooyMHsAnrh9ByW1gHCons3huuSOokNKA8FGTZEEtBvTF46a2z0egNoJGAImJckIVgIJe1p+UAhOuPTaaxlUtDfgqPcOjkWmQhYeDG9FT1sL+4y4SmPToWNmN5uxYLQkZvFUIrp7V1zl4kaHVYUyPkk4POSKhTTrQibmjgWwSlTHAeAkRj1ORIoSSaopSIHdnkIXGSCHrCqNWtSpKR+2BTV/afX39mHL9+WDyHY/DUDVyGJ9MAvpGgy4ehzVI6kmAYXKRMGKxZa7IQyoRhMjaEU7IwjX1vjybMD35yf888x7iFy9yqUBzHtMsW4c2sCmcAasK61ylN+J588qzkRJ7v4RHkQmagdF1NQLQglj2PZZCJ3xAZn4eRtZSXH8+R1JkzUGhccLw5LM0TvCZLo8lKtaR/TwlpNaNjsEteWS+Vr9wGLQpniKmCI/p/tZYJMrLgefcxz8l6wCaWjIw4TGcmv7ppMHLTQf6/e2PC08HTpf5qsjS5/gtodTKyVyMQ9Lbi6NH9XdqE0pSYJZDxXaCa8MoWmZXvhkluqqq0LyZfoyV2cqqmDfrnlutuvsoOa2quDg6Q/zvDpxAwY7pqGrb46f3ncZjcGYygtc6iEP3//I3XZm0Q+EOyKDJNhpTw7m4Eya9RKZmAd0EPNPjxqwUAPYVJrVKebb4j9jm32EYge6atjpD3lgLEBljaax6b/TffnVp4skUMIM6gwL5WhM0couXSAnLMO+Pk4EQJ5j8WTVJWxQvNYUfd+fFQmCeBO/92Oin/ihylwyX4oLU/G2vrkJRPuVEx6JvWT7Y6Vm8kwP7mEyK374RKdFlOxRSkded9MsFaT9UuRiTU6xXBT0LrrNlVLjDqIqShDqP10MgluM16hwxVRPca6PjmYOg39OHrXyUOLhZ3am4tXnMvW8v50HCLNltmPJMaEmIRE1n28ta5CRvjzr9cpvMosLT9nr1tIL8fn4/O9KTfgmV1eHOEfLpUHBE96eVZaH1Iy+xgrU6SFgbN8psKZxkAueady4p1DedYNqLW997CxkVeKCg0WOyU+A6188Bnw2pBBqYpSq6LkE/Se0q+RsMB8FWsPtbOFw6rCoHLUejP+aD6aZ8+Aw8ULQNsifDjTGsjI2ioTPHTlBnjY/zXbkKBMStF81jVrUjKHklCSG8NvNkKOZtibAE3ybEUbWDpbHeb3nhZwcwHRSHIwGl1RCMoUHr5Pb97Rxo9GPexLLJQZIL9XPuxh9rFmxoU8Om/d2QIZaj28gLVCmLeX8xSkuVaVCnP4HMltYLdTtQtgv5aAMrmOkjizc0MP4YdOxVKRbnmSwwIqALbL3mBkUMmZXFLI28WFlTAwGsMM5jx55rBGHSktogc2lJGcI0qKOR+OwFiorEsAow6+j83AidebmjwfDhtlysaCwBpq28sRAXeKn340ZzAaaWVWo1HyZQY3H94/2rZsqnPUkDu81yShooASA47b50z0w/NE+MBHzM7UiaTi7GUMxFpblCSBRyY8VxUXuXVw+ePbF4k8mbMqTLzdbZBXPT/treqPG3G7mwH/122/5ae90cj7AVPstiPo22FX5rE9PVicdxx9lwlmGBbfbrnUb5xuGj5O1cz/KOwYOvG4VJ6/pZguUXv6m8g9/9ANmxfwNcTdIZpNGgQ68l8iEyvaHC77De8/LTEkFK3ALM+pDntPj+Y1k/0wwC5/ubrmBeiQ4x9xelJ/Etd220pcM4c1zQAzcRojbJq/ACkPBf8= sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Summarize a bookmark"}

<MethodEndpoint
method={"post"}
path={"/bookmarks/{bookmarkId}/summarize"}
context={"endpoint"}

Trigger AI summarization for a bookmark. The summary is generated asynchronously and attached to the bookmark. Returns the updated bookmark record.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={undefined}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The bookmark with the updated summary.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Update Bookmark.Api (`docs/docs/api/update-bookmark.api.mdx`)


id: update-bookmark title: "Update a bookmark" sidebar_label: "Update a bookmark" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "patch api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update a bookmark"}

<MethodEndpoint
method={"patch"}
path={"/bookmarks/{bookmarkId}"}
context={"endpoint"}

Partially update a bookmark. Only the fields provided in the request body will be updated. Supports updating common fields (title, note, archived, favourited) as well as type-specific fields.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The fields to update. Only the fields you want to change need to be provided.","content":{"application/json":{"schema":{"type":"object","properties":{"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"summary":{"type":"string","nullable":true},"note":{"type":"string"},"title":{"type":"string","nullable":true,"maxLength":1000},"createdAt":{"type":"string","nullable":true},"url":{"type":"string","format":"uri"},"description":{"type":"string","nullable":true},"author":{"type":"string","nullable":true},"publisher":{"type":"string","nullable":true},"datePublished":{"type":"string","nullable":true},"dateModified":{"type":"string","nullable":true},"text":{"type":"string","nullable":true},"assetContent":{"type":"string","nullable":true}}}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The updated bookmark.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"modifiedAt":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"archived":{"type":"boolean"},"favourited":{"type":"boolean"},"taggingStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"summarizationStatus":{"type":"string","nullable":true,"enum":["success","failure","pending"]},"note":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"source":{"type":"string","nullable":true,"enum":["api","web","cli","mobile","extension","singlefile","rss","import"]},"userId":{"type":"string"}},"required":["id","createdAt","modifiedAt","archived","favourited","taggingStatus","summarizationStatus","userId"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Bookmark not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Update Highlight.Api (`docs/docs/api/update-highlight.api.mdx`)


id: update-highlight title: "Update a highlight" sidebar_label: "Update a highlight" hide_title: true hide_table_of_contents: true api: eJytV+Fu2zYQfpUD+6c1FDsdOqzQjwFu16JZCyxoEwxDGsBn8SyxpkiVpOKohoA9xJ5wTzIcJcty7BYFVv+xQx6P3313/O6yFbYih0FZcyFFKupKYqA3Ki+0yosgEiHJZ05VbCFScYkuKNS6gc4SEIqd8RQ+1FVlXfCQFWhyZXIIBUFmtXVgHRgbaCoSETD3Ir0RwzVe3CbCU1Y7FRqR3mzFktCRm9ehEOnNbXubiAodlhTI+Wjgs4JKFOlWhKYikQofnDL5EeCrgqA26nNNoCSZoFaKHNhVRLaHLhJB91hWml0pUlLfN3m5+fT8F3v/5efiPgSbPWfoKkSTAfqFFG0iHH2ulSMp0uBqSoTBkq2KkVUiFOOpMBSC4+Ej5MMLKxuO4hj1SpGWHoLtqZ7CH0Y3EXe/1dgaNmgC20TGCQyR5D+XBJWzd0qS5NgyawKZwBdhVWmVxYzPPnm+7QSZdvmJMs5+5bg+giLPuzGTpzgnU5ec0Ya0thvB0XHEuSMyIhFLXZO4bRPBFXDqvKm1xiUzy/y18cNOfGWN7+7+6fz8NE8dO/IwmT8o4KW16xLdmt/GQ9RtInxAF/5YrTyF0b6pyyU53icjv7H7/9jkQl9hrYNId4ZtIgLdh+8g+LszkQh1OvTak/sKK5kjTsj8BJD24K3cjPk9ZHPMXR9VjzkiGu4f33Z74nmKrpKenT89Lp5rg3UorFNfSMK/f/8Tn9aLKDwQ7JoMKA+l8l6ZPAFl7lArmbCQ0X3FETwoNEY5qzSq0yW2T+8gNGMEA9Jnx0iHcFhCYWVr82NftTxZCocY5lBiVihDZ45QcokAOWcd8PEp570k7zH/LldFXaJ56Kg/Pz2qkghw73+U51d8UPRyUVIorOw0Nis4TNbaVMwGZfCz7UiSW645cne7llI7LVKxRSkded/OsFKzu6ciEXfoFOOMbPXbXZJ2D7AIofLpbBZcM12jwzVRNcWqOtmOeg+7JvS2t4cOC0cz6oYfOIm9GI164kAx38xxRDOR9kasEvHHa+tKZIS//3kVeeXieL9vPa92tTiI+151OokYPWxlVpYtmbEunKfT8+n5qC0OscwvL45iHzaVBwRPenVWWB9iBeyEgGcGNBK4NM5UONMYyEVmVEZTuCqUZ9+AjLHrgMFCiQbzvROfgFY++AR40kj2ncEngN5T/DYSlpit68pzp8wdliUGlfFsM/1oPppHj4Cp5pGhe1e8ONcayMjKKhM89DUKeKgaFd8hQZmY3sW8f+LRyQIKQkluCn/ZGjI0kJPhAYwATYxsTQ2snC0Pa2NDS7i+gNpIcjCZfKAQlMk9/BrPvKXGTyY72JeYKzNAfqd8GGH23YgGWe28dWdLZKjVcALuFMKi21xEkhZalSos4HNNroH9FMbJINi1aFAm07UkzuzC0H142buIo0pUV6YFVAD0HS+7SwaXnMkVhayI++yEgdEU5rDgtrSAO9Q1wcq6wzuUkZwjio45H47AWCitiwBrHfyOmxd9icBVU5Hnxd2Kj9lYElhD3dN0RMCvzKcfzRlMJlqZ9WQSY5nD9ft3Q73BRoUCbKxz1JA53GiSUFJAiQGn3XFuD8Px2CaAl7qpuDOJxbmzMVBX2qIkCSulCR6rkovcOrj87fWTqLiV9aHEKPb9xHl9NJU/fIbbfdv4QdN8J0Sj7sfjAWvptlfgm/0g7EUi0vFYfJsIFgE22m65Gq+dbltejgXH0/9egKNMS+X5txTpCrWnb4T3+H3fRJ7A13D2i2iaqPM8WaVCJGJNzYP5veX5tXu8EUZn8bK77IzLaeThqB23ye7EPMuoCt+0vR31ssv51cs3LOf9/wllbNbCYZwLcdPB7Wovdom4thUaTV7Hbiw6pyz+eNg7HvSKGNZJQrbbzuKK9a1tB36i3jEzbfsf6cH7pg== sidebar_class_name: "patch api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update a highlight"}

<MethodEndpoint
method={"patch"}
path={"/highlights/{highlightId}"}
context={"endpoint"}

Partially update a highlight. Supports changing the color or note.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The fields to update. Only the fields you want to change need to be provided.","content":{"application/json":{"schema":{"type":"object","properties":{"color":{"type":"string","enum":["yellow","red","green","blue"]},"note":{"type":"string","nullable":true}}}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The updated highlight.","content":{"application/json":{"schema":{"type":"object","properties":{"bookmarkId":{"type":"string"},"startOffset":{"type":"number"},"endOffset":{"type":"number"},"color":{"type":"string","enum":["yellow","red","green","blue"],"default":"yellow"},"text":{"type":"string","nullable":true},"note":{"type":"string","nullable":true},"id":{"type":"string"},"userId":{"type":"string"},"createdAt":{"type":"string"}},"required":["bookmarkId","startOffset","endOffset","text","note","id","userId","createdAt"],"title":"Highlight"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Highlight not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Update List.Api (`docs/docs/api/update-list.api.mdx`)


id: update-list title: "Update a list" sidebar_label: "Update a list" hide_title: true hide_table_of_contents: true api: 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 sidebar_class_name: "patch api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update a list"}

<MethodEndpoint
method={"patch"}
path={"/lists/{listId}"}
context={"endpoint"}

Partially update a list. Only the fields provided in the request body will be updated.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The fields to update. Only the fields you want to change need to be provided.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","nullable":true,"minLength":0,"maxLength":500},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"query":{"type":"string","minLength":1},"public":{"type":"boolean"}}}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The updated list.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"icon":{"type":"string"},"parentId":{"type":"string","nullable":true},"type":{"type":"string","enum":["manual","smart"],"default":"manual"},"query":{"type":"string","nullable":true},"public":{"type":"boolean"},"hasCollaborators":{"type":"boolean"},"userRole":{"type":"string","enum":["owner","editor","viewer","public"]}},"required":["id","name","icon","parentId","public","hasCollaborators","userRole"],"title":"List"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"List not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Update Tag.Api (`docs/docs/api/update-tag.api.mdx`)


id: update-tag title: "Update a tag" sidebar_label: "Update a tag" hide_title: true hide_table_of_contents: true api: eJytVttuGzcQ/ZUB85IIa8kpUiTYhwJKmqBu8mA4MorCEaDRcrTLiEsyJNeSIizQj+gX9kuK4a4ulpWgQOoHSyKHwzNnZs5wK6wjj1FZcyVFLhonMdIES5EJSaHwyvGeyMUNGawJECKWQ5hUBIZWkNZWSmuYExjra9TqK0lAIyF6VdckhyITEcsg8jsx4c9pJgIVjVdxI/K7rZgTevLjJlYiv5u200w49FhTJB+SQSgqqlHkWxE3jkQuQvTKPIbIoBqjvjQESpKJaqHIg11ArCjBFpmgNdZOsxNFSur1pqxXn1+9tOuvP1frGG3xiuGqmEwmWF5J0WbC05dGeZIij76hTHDYIuewrqTIhOLbHcZKMHo2phBfW7lhzI8xMnERy0QeYyqsiWQiG6NzWhUpH6PPgU+cCd/OP1MRRSac5+xFRYF3O1CnJLXpj1EFZ03oTH+6vDwPrcu/3LH1PyFT8gyu7JuAj/m+48O96bSL5MXl88fgbw02sbI+Vd8/f/2dcv46VRZEuyQDKkCtQlCmzECZe9RKZmA90NrxVSfhRlrHkdOozge6r8BDPR0jEDukL87QzJm3ERa2Mae3/gjJhZVn2DztkTHUWFTK0IUnlDjXBOS99cDHh5yVmkLA8j+5qpoazamj/vzwUSITwIP/6aHP3vJB0RdqTbGysmuoouIwubFyMWIRGW1Tz7WCNcTf7xSi8VrkYotSegqhHaFTo/vnIhP36BVjSwz1211KFtjoKHJRxehCPhpFvxku0eOSyA3RubPq0nvYacr73h46LBzBkbh95MR1Nx9L3J5WvpnjSGYi741E1n95x2rKCH//Y5K45IK4OWjL213l7Tr/qLOUWVjeYII69M+Hl8PLI2nbQx9fXz0Kdb+pAiAE0ouLyoaYkjy3dlmjXypTJpXn7F+oeKExkk9EqIJ4QKjAvgG1tqsAG9tAtFCjwfLgJGSgVYghY8EJGVSqrLQqK17BECh9GglzLJaNC+C8LT3WNUZVoNab4SfzyTx5AswsC37XOrw41hrISGeViQH6MgR8KAmO75CgTMrmbNz3b3Iyg4pQkh/Cn7aBAg2UZHhUEqBJkS1pAwtv64elsKI53F5BYyR5GAw+UozKlAF+SWfe0yYMBjvY11gqs4f8QYV4hDk0zlkfoWh8sP5ijgzV7U/AvUKYdZuzRNJMq1rFGXxpyG/gMEO7ab3Tf1Cm0I0kzuzM0Dq+6V0sFOlOOpkWUBEwdLzsLtm75EwuKBZV2mcnDIyGMIaZabSewT3qhmBh/cM7lJGcI0qOOR+eXw1QW58ANjqGHTev+xKBycZR4MXdSkjZmBNYQ10neiLgpgr5J3MBg4FWZjkYpFjGcHvzYV9vsFKxApvqHDUUHleaJNQUUWLEYXectX9/PM0A4CVWbepNUnHubAw0TluUJGGhNMFTVXORWw/Xv757lkTV2RBrNEfNepsmbfeeOm3A7WEm/OC7q1Oao2HWZp1YbntZveveZpnIu8fMNBPc6ryx3XLN3XrdtrycyopfaAdVTdorVeDvUuQL1IG+E8rTm34aPINvYesX0WySeOuGf4lMLGmzf2+10zYTXXMmAN3em+6aCy6Xo7OPJmqb7U6Mi4Jc/K7t9GgcXY8nb35jde7fdXWat8LjSmTpfwLa1VYS/bS2FRpN2aSBKjqnrOX4cBScSH8K6ywV221nMWH9atsDM/ybmWnbfwG89Bx+ sidebar_class_name: "patch api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Update a tag"}

<MethodEndpoint
method={"patch"}
path={"/tags/{tagId}"}
context={"endpoint"}

Rename a tag. The new name will be normalized and trimmed.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The new tag name.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The updated tag.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}},"404":{"description":"Tag not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"A machine-readable error code."},"message":{"type":"string","description":"A human-readable error message."}},"required":["code","message"],"title":"Error"}}}}}}


Docs Api Upload Asset.Api (`docs/docs/api/upload-asset.api.mdx`)


id: upload-asset title: "Upload a new asset" sidebar_label: "Upload a new asset" hide_title: true hide_table_of_contents: true api: eJzNVttuGzcQ/ZUB89IKK8kp+rQPBZS0AdwkrRHbKIrYgGZ3R1pGXJIhubY3wgL9iH5hv6QYcrW6WAX82DeCHB6eufDMbIWx5DBIoy8rkYvWKoPVwnsKIhMV+dJJy6ciF7fxDBAKqdF1sJKKAD0gaHoE5DszuKkJEghVaQ9K1BBq0lAQYAhY1lRBMAxkzKZBt4EHiWwCV79f38B8t+3n293ysurnEc0D6coaqcNMZCLg2ov8s4iEvbjPhKeydTJ0Iv+8FQWhI7doQy3yz/f9fSYcfW3Jhzem6kS+PXGQuUenghl8YPeaVgVp0YX5yrhmWmFAfro0OpAOjHLGgrd9WVMTV6GzJHJhii9Uclyt46gHSZ5P+cloJQMvxLuBQrGPpOj7xF06qtjheOe+79O+t0b7BPbDxcV5x1IuHtHv0+PbsiTvV61S3Qw+UWid9tBQQHYBsDBtiGk5TuiJ92itkmUsofkXz++93PWIx4U3GvrgpF4/q71YVlp+bQlkRTrIlSTHdORap2o6x7Mfid5E9Je88vHy4y/AZmBWx6Ac84jp5bdDMN02BbmzYGx5FgekhqIL5CMg7/yGzQsZGifXUqNKQBqb/6R6UjS7aB9HZfDngMV9Ntbi7YCYFCHV248Xr5+X2K3GNtTGyW9UwT9//R35vIn/D4LZkAbpoZHeS73OQOoHVLLKwDigJ8sET6oq0FOYW4XyfD2N4aEnbGyiesAgMu0z0VCoDeuaNT5WH7IUiEFK2HVyD+R8VIvWKZGLLVaVI+/7OVo5f3gtMvGATmKhhpJNxykCK2xVELmoQ7A+n8+D62YbdLghsjO09mz+BoRd0t4P9pC4MPUDHbtmz9PLh2o2BoJfZj+imcgHI5ENi3fGNcgMf/3jJtaD1CvD19nrROn17GJ2IfYpH/ksri6f8R8PJeu+J7Wa1sYHjs6o5lKvAXUFjrCayjBVGMhF72RJ3CGkZ2xApcyjh860/H8b1Ljeg/gMlPTBZ8Aan0Et17WS65p3Uvay+EiB5aa1Hqwza4dNg0GWyHp2p+/0q1fA4WK9SALFmwulxh7iYfgfgMfFavmNin8pp2i5GCorgiyhJqzIzeBP08butibNTZQAdfRsQx2snGmO8/tIBdxeQqsrcjCZXFMIUq89/BTvvKfOTyY72lfIX3xH+YP04YCzb601LkDZOm/ctECmascbsZsu0+EyBmmpZCPDEr625Dqw6LChQM6ndr3rHyB1qdqKOLNLTU/h7QCxkqTSp+awgAzcFmNcdo+MkJzJFYWyjucMwsRoBgtY6lapJTygaglWxh2/IXXFOaIIzPlwBNpAY1wk2Krgd7F5s5saWL48b+52fMxGQWD0oImOKIq5z+/0FCYTJfVmMom+LOD204f9CPIoQw0m1jkqKB0+KqrGZjhL11mVxutRnYC3QJtAg0kszp2NPlH972TDRW4cXP387vuo/axMDUaV07EF7Oescaw6/YbbvVL+L6eyJE0HEt5nSV23gwIPvShObKwfvLPdciHfOtX3vB1rlce2vf7GIS4T6fdFyd5QJ3LxNgVjOrSzWGEiPzuW9dnu0qIsyYYD82dzDMvw2EA4Bqyqw+DYmIrvMHDEzfbLRBKPZfpEliP54Qh1d8Biu00WNyxDfS+ygW6UJdHzyPcva0od9w== sidebar_class_name: "post api-method" info_path: api/karakeep-api custom_edit_url: null

import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint";
import ParamsDetails from "@theme/ParamsDetails";
import RequestSchema from "@theme/RequestSchema";
import StatusCodes from "@theme/StatusCodes";
import OperationTabs from "@theme/OperationTabs";
import TabItem from "@theme/TabItem";
import Heading from "@theme/Heading";

<Heading
as={"h1"}
className={"openapi__heading"}
children={"Upload a new asset"}

<MethodEndpoint
method={"post"}
path={"/assets"}
context={"endpoint"}

Upload a binary file as a new asset. The uploaded asset can then be attached to a bookmark via the POST /bookmarks/{bookmarkId}/assets endpoint.

<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}

<RequestSchema
title={"Body"}
body={{"description":"The file to upload as multipart/form-data.","content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"title":"File to be uploaded"}},"required":["file"]}}}}}

<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"The asset was uploaded successfully. Returns metadata about the uploaded asset.","content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","description":"The unique identifier assigned to the uploaded asset."},"contentType":{"type":"string","description":"The MIME type of the uploaded file."},"size":{"type":"number","description":"The size of the uploaded file in bytes."},"fileName":{"type":"string","description":"The original file name of the uploaded file."}},"required":["assetId","contentType","size","fileName"],"title":"UploadedAsset"}}}},"401":{"description":"Unauthorized — the Bearer token is missing, invalid, or expired.","content":{"text/plain":{"schema":{"type":"string","example":"Unauthorized"}}}}}}


Versioned Docs Version V0.28.0 03 Configuration (`docs/versioned_docs/version-v0.28.0/03-configuration.md`)

Configuration

The app is mainly configured by environment variables. All the used environment variables are listed in packages/shared/config.ts. The most important ones are:

Name Required Default Description
PORT No 3000 The port on which the web server will listen. DON'T CHANGE THIS IF YOU'RE USING DOCKER, instead changed the docker bound external port.
WORKERS_PORT No 0 (Random Port) The port on which the worker will export its prometheus metrics on /metrics. By default it's a random unused port. If you want to utilize those metrics, fix the port to a value (and export it in docker if you're using docker).
WORKERS_HOST No 127.0.0.1 Host to listen to for requests to WORKERS_PORT. You will need to set this if running in a container, since localhost will not be reachable from outside
WORKERS_ENABLED_WORKERS No Not set Comma separated list of worker names to enable. If set, only these workers will run. Valid values: crawler,inference,search,adminMaintenance,video,feed,assetPreprocessing,webhook,ruleEngine.
WORKERS_DISABLED_WORKERS No Not set Comma separated list of worker names to disable. Takes precedence over WORKERS_ENABLED_WORKERS.
DATA_DIR Yes Not set The path for the persistent data directory. This is where the db lives. Assets are stored here by default unless ASSETS_DIR is set.
ASSETS_DIR No Not set The path where crawled assets will be stored. If not set, defaults to ${DATA_DIR}/assets.
NEXTAUTH_URL Yes Not set Should point to the address of your server. The app will function without it, but will redirect you to wrong addresses on signout for example.
NEXTAUTH_SECRET Yes Not set Random string used to sign the JWT tokens. Generate one with openssl rand -base64 36.
MEILI_ADDR No Not set The address of meilisearch. If not set, Search will be disabled. E.g. (http://meilisearch:7700)
MEILI_MASTER_KEY Only in Prod and if search is enabled Not set The master key configured for meilisearch. Not needed in development environment. Generate one with openssl rand -base64 36 | tr -dc 'A-Za-z0-9'
MAX_ASSET_SIZE_MB No 50 Sets the maximum allowed asset size (in MB) to be uploaded
DISABLE_NEW_RELEASE_CHECK No false If set to true, latest release check will be disabled in the admin panel.
PROMETHEUS_AUTH_TOKEN No Random Enable a prometheus metrics endpoint at /api/metrics. This endpoint will require this token being passed in the Authorization header as a Bearer token. If not set, a new random token is generated everytime at startup. This cannot contain any special characters or you may encounter a 400 Bad Request response.
RATE_LIMITING_ENABLED No false If set to true, API rate limiting will be enabled.
DB_WAL_MODE No false Enables WAL mode for the sqlite database. This should improve the performance of the database. There's no reason why you shouldn't set this to true unless you're running the db on a network attached drive. This will become the default at some time in the future.
SEARCH_NUM_WORKERS No 1 Number of concurrent workers for search indexing tasks. Increase this if you have a high volume of content being indexed for search.
SEARCH_JOB_TIMEOUT_SEC No 30 How long to wait for a search indexing job to finish before timing out. Increase this if you have large bookmarks with extensive content that takes longer to index.
WEBHOOK_NUM_WORKERS No 1 Number of concurrent workers for webhook delivery. Increase this if you have multiple webhook endpoints or high webhook traffic.
ASSET_PREPROCESSING_NUM_WORKERS No 1 Number of concurrent workers for asset preprocessing tasks (image processing, OCR, etc.). Increase this if you have many images or documents that need processing.
RULE_ENGINE_NUM_WORKERS No 1 Number of concurrent workers for rule engine processing. Increase this if you have complex automation rules that need to be processed quickly.

Asset Storage

Karakeep supports two storage backends for assets: local filesystem (default) and S3-compatible object storage. S3 storage is automatically detected when an S3 endpoint is passed.

Name Required Default Description
ASSET_STORE_S3_ENDPOINT No Not set The S3 endpoint URL. Required for S3-compatible services like MinIO. Setting this enables S3 storage.
ASSET_STORE_S3_REGION No Not set The S3 region to use.
ASSET_STORE_S3_BUCKET Yes when using S3 Not set The S3 bucket name where assets will be stored.
ASSET_STORE_S3_ACCESS_KEY_ID Yes when using S3 Not set The S3 access key ID for authentication.
ASSET_STORE_S3_SECRET_ACCESS_KEY Yes when using S3 Not set The S3 secret access key for authentication.
ASSET_STORE_S3_FORCE_PATH_STYLE No false Whether to force path-style URLs for S3 requests. Set to true for MinIO and other S3-compatible services.

:::info
When using S3 storage, make sure the bucket exists and the provided credentials have the necessary permissions to read, write, and delete objects in the bucket.
:::

:::warning
Switching between storage backends after data has been stored will require manual migration of existing assets. Plan your storage backend choice carefully before deploying.
:::

Authentication / Signup

By default, Karakeep uses the database to store users, but it is possible to also use OAuth.
The flags need to be provided to the web container.

:::info
Only OIDC compliant OAuth providers are supported! For information on how to set it up, consult the documentation of your provider.
:::

:::info
When setting up OAuth, the allowed redirect URLs configured at the provider should be set to <KARAKEEP_ADDRESS>/api/auth/callback/custom where <KARAKEEP_ADDRESS> is the address you configured in NEXTAUTH_URL (for example: https://try.karakeep.app/api/auth/callback/custom).
:::

Name Required Default Description
DISABLE_SIGNUPS No false If enabled, no new signups will be allowed and the signup button will be disabled in the UI
DISABLE_PASSWORD_AUTH No false If enabled, only signups and logins using OAuth are allowed and the signup button and login form for local accounts will be disabled in the UI
EMAIL_VERIFICATION_REQUIRED No false Whether email verification is required during user signup. If enabled, users must verify their email address before they can use their account. If you enable this, you must configure SMTP settings.
OAUTH_WELLKNOWN_URL No Not set The "wellknown Url" for openid-configuration as provided by the OAuth provider
OAUTH_CLIENT_SECRET No Not set The "Client Secret" as provided by the OAuth provider
OAUTH_CLIENT_ID No Not set The "Client ID" as provided by the OAuth provider
OAUTH_SCOPE No "openid email profile" "Full list of scopes to request (space delimited)"
OAUTH_PROVIDER_NAME No "Custom Provider" The name of your provider. Will be shown on the signup page as "Sign in with <name>"
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING No false Whether existing accounts in karakeep stored in the database should automatically be linked with your OAuth account. Only enable it if you trust the OAuth provider!
OAUTH_TIMEOUT No 3500 The wait time in milliseconds for the OAuth provider response. Increase this if you are having outgoing request timed out errors

For more information on OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING, check the next-auth.js documentation.

Inference Configs (For automatic tagging)

Either OPENAI_API_KEY or OLLAMA_BASE_URL need to be set for automatic tagging to be enabled. Otherwise, automatic tagging will be skipped.

:::warning

  • The quality of the tags you'll get will depend on the quality of the model you choose.
  • You might want to tune the INFERENCE_CONTEXT_LENGTH as the default is quite small. The larger the value, the better the quality of the tags, but the more expensive the inference will be (money-wise on OpenAI and resource-wise on ollama).
    :::
Name Required Default Description
OPENAI_API_KEY No Not set The OpenAI key used for automatic tagging. More on that in here.
OPENAI_BASE_URL No Not set If you just want to use OpenAI you don't need to pass this variable. If, however, you want to use some other openai compatible API (e.g. azure openai service), set this to the url of the API.
OLLAMA_BASE_URL No Not set If you want to use ollama for local inference, set the address of ollama API here.
OLLAMA_KEEP_ALIVE No Not set Controls how long the model will stay loaded into memory following the request (example value: "5m").
INFERENCE_TEXT_MODEL No gpt-4.1-mini The model to use for text inference. You'll need to change this to some other model if you're using ollama.
INFERENCE_IMAGE_MODEL No gpt-4o-mini The model to use for image inference. You'll need to change this to some other model if you're using ollama and that model needs to support vision APIs (e.g. llava).
EMBEDDING_TEXT_MODEL No text-embedding-3-small The model to be used for generating embeddings for the text.
INFERENCE_CONTEXT_LENGTH No 2048 The max number of tokens that we'll pass to the inference model. If your content is larger than this size, it'll be truncated to fit. The larger this value, the more of the content will be used in tag inference, but the more expensive the inference will be (money-wise on openAI and resource-wise on ollama). Check the model you're using for its max supported content size.
INFERENCE_MAX_OUTPUT_TOKENS No 2048 The maximum number of tokens that the inference model is allowed to generate in its response. This controls the length of AI-generated content like tags and summaries. Increase this if you need longer responses, but be aware that higher values will increase costs (for OpenAI) and processing time.
INFERENCE_USE_MAX_COMPLETION_TOKENS No false [OpenAI Only] Whether to use the newer max_completion_tokens parameter instead of the deprecated max_tokens parameter. Set to true if using GPT-5 or o-series models which require this. Will become the default in a future release.
INFERENCE_LANG No english The language in which the tags will be generated.
INFERENCE_NUM_WORKERS No 1 Number of concurrent workers for AI inference tasks (tagging and summarization). Increase this if you have multiple AI inference requests and want to process them in parallel.
INFERENCE_ENABLE_AUTO_TAGGING No true Whether automatic AI tagging is enabled or disabled.
INFERENCE_ENABLE_AUTO_SUMMARIZATION No false Whether automatic AI summarization is enabled or disabled.
INFERENCE_JOB_TIMEOUT_SEC No 30 How long to wait for the inference job to finish before timing out. If you're running ollama without powerful GPUs, you might want to increase the timeout a bit.
INFERENCE_FETCH_TIMEOUT_SEC No 300 [Ollama Only] The timeout of the fetch request to the ollama server. If your inference requests take longer than the default 5mins, you might want to increase this timeout.
INFERENCE_SUPPORTS_STRUCTURED_OUTPUT No Not set [DEPRECATED] Whether the inference model supports structured output or not. Use INFERENCE_OUTPUT_SCHEMA instead. Setting this to true translates to INFERENCE_OUTPUT_SCHEMA=structured, and to false translates to INFERENCE_OUTPUT_SCHEMA=plain.
INFERENCE_OUTPUT_SCHEMA No structured Possible values are "structured", "json", "plain". Structured is the preferred option, but if your model doesn't support it, you can use "json" if your model supports JSON mode, otherwise "plain" which should be supported by all the models but the model might not output the data in the correct format.

:::info

  • You can append additional instructions to the prompt used for automatic tagging, in the AI Settings (in the User Settings screen)
  • You can use the placeholders $tags, $aiTags, $userTags in the prompt. These placeholders will be replaced with all tags, ai generated tags or human created tags when automatic tagging is performed (e.g. [karakeep, computer, ai])
    :::

Crawler Configs

Name Required Default Description
CRAWLER_NUM_WORKERS No 1 Number of allowed concurrent crawling jobs. By default, we're only doing one crawling request at a time to avoid consuming a lot of resources.
BROWSER_WEB_URL No Not set The browser's http debugging address. The worker will talk to this endpoint to resolve the debugging console's websocket address. If you already have the websocket address, use BROWSER_WEBSOCKET_URL instead. If neither BROWSER_WEB_URL nor BROWSER_WEBSOCKET_URL are set, the worker will use plain http requests skipping screenshotting and javascript execution.
BROWSER_WEBSOCKET_URL No Not set The websocket address of browser's debugging console. If you want to use browserless, use their websocket address here. If neither BROWSER_WEB_URL nor BROWSER_WEBSOCKET_URL are set, the worker will use plain http requests skipping screenshotting and javascript execution.
BROWSER_CONNECT_ONDEMAND No false If set to false, the crawler will proactively connect to the browser instance and always maintain an active connection. If set to true, the browser will be launched on demand only whenever a crawling is requested. Set to true if you're using a service that provides you with browser instances on demand.
CRAWLER_DOWNLOAD_BANNER_IMAGE No true Whether to cache the banner image used in the cards locally or fetch it each time directly from the website. Caching it consumes more storage space, but is more resilient against link rot and rate limits from websites.
CRAWLER_STORE_SCREENSHOT No true Whether to store a screenshot from the crawled website or not. Screenshots act as a fallback for when we fail to extract an image from a website. You can also view the stored screenshots for any link.
CRAWLER_FULL_PAGE_SCREENSHOT No false Whether to store a screenshot of the full page or not. Disabled by default, as it can lead to much higher disk usage. If disabled, the screenshot will only include the visible part of the page
CRAWLER_SCREENSHOT_TIMEOUT_SEC No 5 How long to wait for the screenshot finish before timing out. If you are capturing full-page screenshots of long webpages, consider increasing this value.
CRAWLER_FULL_PAGE_ARCHIVE No false Whether to store a full local copy of the page or not. Disabled by default, as it can lead to much higher disk usage. If disabled, only the readable text of the page is archived.
CRAWLER_JOB_TIMEOUT_SEC No 60 How long to wait for the crawler job to finish before timing out. If you have a slow internet connection or a low powered device, you might want to bump this up a bit
CRAWLER_NAVIGATE_TIMEOUT_SEC No 30 How long to spend navigating to the page (along with its redirects). Increase this if you have a slow internet connection
CRAWLER_VIDEO_DOWNLOAD No false Whether to download videos from the page or not (using yt-dlp)
CRAWLER_VIDEO_DOWNLOAD_MAX_SIZE No 50 The maximum file size for the downloaded video. The quality will be chosen accordingly. Use -1 to disable the limit.
CRAWLER_VIDEO_DOWNLOAD_TIMEOUT_SEC No 600 How long to wait for the video download to finish
CRAWLER_ENABLE_ADBLOCKER No true Whether to enable an adblocker in the crawler or not. If you're facing troubles downloading the adblocking lists on worker startup, you can disable this.
CRAWLER_YTDLP_ARGS No [] Include additional yt-dlp arguments to be passed at crawl time separated by %%: https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#general-options
BROWSER_COOKIE_PATH No Not set Path to a JSON file containing cookies to be loaded into the browser context. The file should be an array of cookie objects, each with name and value (required), and optional fields like domain, path, expires, httpOnly, secure, and sameSite (e.g., [{"name": "session", "value": "xxx", "domain": ".example.com"}]).
HTML_CONTENT_SIZE_INLINE_THRESHOLD_BYTES No 5 * 1024 The thresholds in bytes after which larger assets will be stored in the assetdb (folder/s3) instead of inline in the database.

More info on BROWSER_COOKIE_PATH

BROWSER_COOKIE_PATH specifies the path to a JSON file containing cookies to be loaded into the browser context for crawling.

The JSON file must be an array of cookie objects, each with:

  • name: The cookie name (required).
  • value: The cookie value (required).
  • Optional fields: domain, path, expires, httpOnly, secure, sameSite (values: "Strict", "Lax", or "None").

Example JSON file:

json
[
  {
    "name": "session",
    "value": "xxx",
    "domain": ".example.com",
    "path": "/",
    "expires": 1735689600,
    "httpOnly": true,
    "secure": true,
    "sameSite": "Lax"
  }
]

OCR Configs

Karakeep uses tesseract.js to extract text from images.

Name Required Default Description
OCR_CACHE_DIR No $TEMP_DIR The dir where tesseract will download its models. By default, those models are not persisted and stored in the OS' temp dir.
OCR_LANGS No eng Comma separated list of the language codes that you want tesseract to support. You can find the language codes here. Set to empty string to disable OCR.
OCR_CONFIDENCE_THRESHOLD No 50 A number between 0 and 100 indicating the minimum acceptable confidence from tessaract. If tessaract's confidence is lower than this value, extracted text won't be stored.

Webhook Configs

You can use webhooks to trigger actions when bookmarks are created, changed or crawled.

Name Required Default Description
WEBHOOK_TIMEOUT_SEC No 5 The timeout for the webhook request in seconds.
WEBHOOK_RETRY_TIMES No 3 The number of times to retry the webhook request.

:::info

  • The WEBHOOK_TOKEN is used for authentication. It will appear in the Authorization header as Bearer token.

    text
    Authorization: Bearer <WEBHOOK_TOKEN>
  • The webhook will be triggered with the job id (used for idempotence), bookmark id, bookmark type, the user id, the url and the operation in JSON format in the body.

    json
    {
      "jobId": "123",
      "type": "link",
      "bookmarkId": "exampleBookmarkId",
      "userId": "exampleUserId",
      "url": "https://example.com",
      "operation": "crawled"
    }

    :::

SMTP Configuration

Karakeep can send emails for various purposes such as email verification during signup. Configure these settings to enable email functionality.

Name Required Default Description
SMTP_HOST No Not set The SMTP server hostname or IP address. Required if you want to enable email functionality.
SMTP_PORT No 587 The SMTP server port. Common values are 587 (STARTTLS), 465 (SSL/TLS), or 25 (unencrypted).
SMTP_SECURE No false Whether to use SSL/TLS encryption. Set to true for port 465, false for port 587 with STARTTLS.
SMTP_USER No Not set The username for SMTP authentication. Usually your email address.
SMTP_PASSWORD No Not set The password for SMTP authentication. For services like Gmail, use an app-specific password.
SMTP_FROM No Not set The "from" email address that will appear in sent emails. This should be a valid email address.

Proxy Configuration

If your Karakeep instance needs to connect through a proxy server, you can configure the following settings:

Name Required Default Description
CRAWLER_HTTP_PROXY No Not set HTTP proxy server URL for outgoing HTTP requests (e.g., http://proxy.example.com:8080). You can pass multiple comma separated proxies and the used one will be chosen at random. The proxy is used for crawling, RSS feed fetches and webhooks.
CRAWLER_HTTPS_PROXY No Not set HTTPS proxy server URL for outgoing HTTPS requests (e.g., http://proxy.example.com:8080). You can pass multiple comma separated proxies and the used one will be chosen at random. The proxy is used for crawling, RSS feed fetches and webhooks.
CRAWLER_NO_PROXY No Not set Comma-separated list of hostnames/IPs that should bypass the proxy (e.g., localhost,127.0.0.1,.local)
CRAWLER_ALLOWED_INTERNAL_HOSTNAMES No Not set By default, Karakeep blocks worker-initiated requests whose DNS resolves to private, loopback, or link-local IP addresses. Use this to allowlist specific hostnames for internal access (e.g., internal.company.com,.local). Supports domain wildcards by prefixing with a dot (e.g., .internal.company.com). Note: Internal IP validation is bypassed when a proxy is configured for the URL as the local DNS resolver won't necessarily be the same as the one used by the proxy.

:::info
These proxy settings will be used by the crawler and other components that make outgoing HTTP requests.
:::


Versioned Docs Version V0.28.0 04 Screenshots (`docs/versioned_docs/version-v0.28.0/04-screenshots.md`)

Screenshots

Homepage

Homepage (Dark Mode)

Tags

Lists

Bookmark Preview

Settings

Admin Panel

iOS Sharing


Versioned Docs Version V0.28.0 05 Quick Sharing (`docs/versioned_docs/version-v0.28.0/05-quick-sharing.md`)

Quick Sharing Extensions

The whole point of Karakeep is making it easy to hoard the content. That's why there are a couple of

Mobile Apps

Browser Extensions

  • Chrome extension: here.

  • Firefox addon: here.

  • Community Extensions

  • Safari extension: App Store Link. For macOS and iOS to allow a simple way to add your bookmarks to your self hosted karakeep instance.


Versioned Docs Version V0.28.0 06 Openai (`docs/versioned_docs/version-v0.28.0/06-openai.md`)

OpenAI Costs

This service uses OpenAI for automatic tagging. This means that you'll incur some costs if automatic tagging is enabled. There are two type of inferences that we do:

Text Tagging

For text tagging, we use the gpt-4.1-mini model. This model is extremely cheap. Cost per inference varies depending on the content size per article. Though, roughly, You'll be able to generate tags for almost 3000+ bookmarks for less than $1.

Image Tagging

For image uploads, we use the gpt-4o-mini model for extracting tags from the image. You can learn more about the costs of using this model here. To lower the costs, we're using the low resolution mode (fixed number of tokens regardless of image size). You'll be able to run inference for 1000+ images for less than a $1.


Versioned Docs Version V0.28.0 08 Security Considerations (`docs/versioned_docs/version-v0.28.0/08-security-considerations.md`)

Security Considerations

If you're going to give app access to untrusted users, there's some security considerations that you'll need to be aware of given how the crawler works. The crawler is basically running a browser to fetch the content of the bookmarks. Any untrusted user can submit bookmarks to be crawled from your server and they'll be able to see the crawling result. This can be abused in multiple ways:

  1. Untrusted users can submit crawl requests to websites that you don't want to be coming out of your IPs.
  2. Crawling user controlled websites can expose your origin IP (and location) even if your service is hosted behind cloudflare for example.
  3. The crawling requests will be coming out from your own network, which untrusted users can leverage to crawl internal non-internet exposed endpoints.

To mitigate those risks, you can do one of the following:

  1. Limit access to trusted users
  2. Let the browser traffic go through some VPN with restricted network policies.
  3. Host the browser container outside of your network.
  4. Use a hosted browser as a service (e.g. browserless). Note: I've never used them before.

Versioned Docs Version V0.28.0 09 Command Line (`docs/versioned_docs/version-v0.28.0/09-command-line.md`)

Command Line Tool (CLI)

Karakeep comes with a simple CLI for those users who want to do more advanced manipulation.

Features

  • Manipulate bookmarks, lists and tags
  • Mass import/export of bookmarks

Installation (NPM)

text
npm install @karakeep/cli

Installation (Docker)

text
docker run --rm ghcr.io/karakeep-app/karakeep-cli:release --help

Usage

text
karakeep
text
Usage: karakeep [options] [command]

A CLI interface to interact with the karakeep api

Options:
  --api-key <key>       the API key to interact with the API (env: KARAKEEP_API_KEY)
  --server-addr <addr>  the address of the server to connect to (env: KARAKEEP_SERVER_ADDR)
  -V, --version         output the version number
  -h, --help            display help for command

Commands:
  bookmarks             manipulating bookmarks
  lists                 manipulating lists
  tags                  manipulating tags
  whoami                returns info about the owner of this API key
  help [command]        display help for command

And some of the subcommands:

text
karakeep bookmarks
text
Usage: karakeep bookmarks [options] [command]

Manipulating bookmarks

Options:
  -h, --help             display help for command

Commands:
  add [options]          creates a new bookmark
  get <id>               fetch information about a bookmark
  update [options] <id>  updates bookmark
  list [options]         list all bookmarks
  delete <id>            delete a bookmark
  help [command]         display help for command
text
karakeep lists
text
Usage: karakeep lists [options] [command]

Manipulating lists

Options:
  -h, --help                 display help for command

Commands:
  list                       lists all lists
  delete <id>                deletes a list
  add-bookmark [options]     add a bookmark to list
  remove-bookmark [options]  remove a bookmark from list
  help [command]             display help for command

Obtaining an API Key

To use the CLI, you'll need to get an API key from your karakeep settings. You can validate that it's working by running:

text
karakeep --api-key <key> --server-addr <addr> whoami

For example:

text
karakeep --api-key mysupersecretkey --server-addr https://try.karakeep.app whoami
{
  id: 'j29gnbzxxd01q74j2lu88tnb',
  name: 'Test User',
  email: '[email protected]'
}

Other clients

There also exists a non-official, community-maintained, python package called karakeep-python-api that can be accessed from the CLI, but is not official.


Versioned Docs Version V0.28.0 09 Mcp (`docs/versioned_docs/version-v0.28.0/09-mcp.md`)

Model Context Protocol Server (MCP)

Karakeep comes with a Model Context Protocol server that can be used to interact with it through LLMs.

Supported Tools

  • Searching bookmarks
  • Adding and removing bookmarks from lists
  • Attaching and detaching tags to bookmarks
  • Creating new lists
  • Creating text and URL bookmarks

Usage with Claude Desktop

From NPM:

json
{
  "mcpServers": {
    "karakeep": {
      "command": "npx",
      "args": [
        "@karakeep/mcp"
      ],
      "env": {
        "KARAKEEP_API_ADDR": "https://<YOUR_SERVER_ADDR>",
        "KARAKEEP_API_KEY": "<YOUR_TOKEN>"
      }
    }
  }
}

From Docker:

json
{
  "mcpServers": {
    "karakeep": {
      "command": "docker",
      "args": [
        "run",
        "-e",
        "KARAKEEP_API_ADDR=https://<YOUR_SERVER_ADDR>",
        "-e",
        "KARAKEEP_API_KEY=<YOUR_TOKEN>",
        "ghcr.io/karakeep-app/karakeep-mcp:latest"
      ]
    }
  }
}

Demo

Adding Text Bookmarks

Adding URL Bookmarks


--- METRICS ---