Karakeep — Reference
Links
- Website: https://docs.karakeep.app
- API docs: https://docs.karakeep.app/api/karakeep-api/
- OpenAPI spec: https://github.com/karakeep-app/karakeep/blob/main/packages/open-api/karakeep-openapi-spec.json
- MCP docs: https://docs.karakeep.app/integrations/mcp/
- GitHub: https://github.com/karakeep-app/karakeep
- Python client: https://pypi.org/project/karakeep-python-api/
Authentication
All API requests require a Bearer token. The API key is stored in Vault at secret/karakeep → api_key (format: ak2_...).
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/...
API — Bookmarks
List bookmarks
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
"https://karakeep.eva-00.network/api/v1/bookmarks?limit=20" | python3 -c \
"import json,sys; [print(f'{b[\"id\"]} {b.get(\"title\",\"\")}') for b in json.load(sys.stdin)['bookmarks']]"
Supports cursor-based pagination: pass cursor=<nextCursor> from the response.
Search bookmarks
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
"https://karakeep.eva-00.network/api/v1/bookmarks/search" \
-X POST -H "Content-Type: application/json" \
-d '{"q": "homelab backup"}'
Create a bookmark (URL)
curl -s -X POST -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/bookmarks \
-d '{"type": "link", "url": "https://example.com/article"}'
Create a bookmark (note)
curl -s -X POST -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/bookmarks \
-d '{"type": "text", "text": "My note content here"}'
Get bookmark details
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/bookmarks/<bookmark-id>
Update a bookmark (PATCH)
curl -s -X PATCH -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/bookmarks/<bookmark-id> \
-d '{"note": "Added via API"}'
Delete a bookmark
curl -s -X DELETE -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/bookmarks/<bookmark-id>
Returns HTTP 204 (No Content) on success.
List bookmarks by tag
# First, get the tag ID
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/tags | python3 -c \
"import json,sys; [print(f'{t[\"id\"]} {t[\"name\"]}') for t in json.load(sys.stdin)['tags'] if 'github' in t['name'].lower()]"
# Then list all bookmarks with that tag (paginated)
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
"https://karakeep.eva-00.network/api/v1/bookmarks?tagId=<tag-id>&limit=50"
Follow nextCursor in the response until it's null to get all results.
Bulk delete bookmarks
There is no native bulk delete API. Use curl with xargs for parallel deletion:
# 1. Collect bookmark IDs into a file (e.g., by tag)
python3 -c "
import urllib.request, json
api_key = 'ak2_...'
base = 'https://karakeep.eva-00.network/api/v1/bookmarks'
tag_id = '<tag-id>'
cursor = None
ids = []
while True:
url = f'{base}?tagId={tag_id}&limit=50'
if cursor:
url += f'&cursor={cursor}'
req = urllib.request.Request(url)
req.add_header('Authorization', f'Bearer {api_key}')
data = json.loads(urllib.request.urlopen(req).read())
ids.extend(b['id'] for b in data['bookmarks'])
cursor = data.get('nextCursor')
if not cursor:
break
with open('/tmp/delete_ids.txt', 'w') as f:
f.writelines(id + '\n' for id in ids)
print(f'Collected {len(ids)} bookmark IDs')
"
# 2. Delete in parallel (10 concurrent)
cat /tmp/delete_ids.txt | xargs -P 10 -I {} \
curl -s -o /dev/null -w '{} %{http_code}\n' -X DELETE \
-H "Authorization: Bearer $KARAKEEP_API_KEY" \
"https://karakeep.eva-00.network/api/v1/bookmarks/{}"
Note: Python urllib cannot send DELETE requests reliably to this API (returns 403). Use curl for deletions.
API — Tags
List all tags
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/tags | python3 -c \
"import json,sys; [print(f'{t[\"id\"]} {t[\"name\"]}') for t in json.load(sys.stdin)['tags']]"
Attach a tag to a bookmark
curl -s -X POST -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/bookmarks/<bookmark-id>/tags \
-d '{"tags": [{"tagId": "<tag-id>"}]}'
Detach a tag
curl -s -X DELETE -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/bookmarks/<bookmark-id>/tags \
-d '{"tags": [{"tagId": "<tag-id>"}]}'
API — Lists
List all lists
curl -s -H "Authorization: Bearer $KARAKEEP_API_KEY" \
https://karakeep.eva-00.network/api/v1/lists
Create a list
curl -s -X POST -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/lists \
-d '{"name": "My List", "icon": "📑", "type": "manual"}'
Add bookmark to a list
curl -s -X PUT -H "Authorization: Bearer $KARAKEEP_API_KEY" \
-H "Content-Type: application/json" \
https://karakeep.eva-00.network/api/v1/lists/<list-id>/bookmarks/<bookmark-id>
MCP Server
The Karakeep MCP server provides AI-accessible tools for bookmark management.
# Available MCP tools
npx @karakeep/mcp --help
Tools: search-bookmarks, get-bookmark, create-bookmark, get-lists, add-bookmark-to-list, remove-bookmark-from-list, attach-tag-to-bookmark, detach-tag-from-bookmark, get-bookmark-content
What the API/CLI Cannot Do
| Gap | Workaround |
|---|---|
| Cannot trigger AI re-tagging via API | Use the web UI (bookmark → re-tag button) |
| Cannot manage OIDC/auth settings via API | Environment variables in docker-compose |
| Cannot export/import bookmarks via API | Use the web UI export feature |
| Cannot manage Meilisearch index via API | docker exec karakeep-meilisearch-1 curl localhost:7700/indexes |
| Cannot configure AI models via API | Set INFERENCE_TEXT_MODEL / INFERENCE_IMAGE_MODEL env vars |
| No CLI tool — API and MCP only | Use curl or the MCP server for automation |
| MCP server cannot delete bookmarks | Use the REST API: DELETE /api/v1/bookmarks/{id} |
| No bulk delete API | Loop with xargs -P and curl (see above) |
| Cannot view archived page content via REST API | Use MCP get-bookmark-content tool or web UI |
| API key generation requires SQLite access on first run | Playbook handles this automatically |