Sync Readwise Highlights to AI Knowledge Base

Readwise collects your highlights from Kindle, Instapaper, Pocket, web articles, and podcasts. This guide shows how to pipe those highlights into REM Labs so your AI can recall what you have read, surface relevant quotes, and connect ideas across sources.

What Gets Imported

Step 1: Get Your Readwise API Token

# Get your token at readwise.io/access_token # Store it as an environment variable export READWISE_TOKEN="your-readwise-token" export REMLABS_API_KEY="your-rem-api-key"

Step 2: Fetch and Import Highlights

import { RemClient } from "@remlabs/sdk"; const rem = new RemClient({ apiKey: process.env.REMLABS_API_KEY }); async function fetchHighlights(updatedAfter) { let url = "https://readwise.io/api/v2/highlights/"; const params = new URLSearchParams({ page_size: "100" }); if (updatedAfter) params.set("updated__gt", updatedAfter); const allHighlights = []; while (url) { const res = await fetch(`${url}?${params}`, { headers: { Authorization: `Token ${process.env.READWISE_TOKEN}` } }); const data = await res.json(); allHighlights.push(...data.results); url = data.next; } return allHighlights; } const highlights = await fetchHighlights(); console.log(`Fetched ${highlights.length} highlights`); let count = 0; for (const h of highlights) { const content = h.note ? `"${h.text}"\n\nNote: ${h.note}` : `"${h.text}"`; await rem.remember({ content, namespace: "readwise", tags: [h.book_title, h.author, h.category].filter(Boolean), metadata: { readwise_id: h.id, book_title: h.book_title, author: h.author, category: h.category, highlighted_at: h.highlighted_at, source: "readwise" } }); count++; } console.log(`Imported ${count} highlights`);

Step 3: Fetch Books for Context

Import book-level metadata to enrich recall results:

async function fetchBooks() { const res = await fetch("https://readwise.io/api/v2/books/", { headers: { Authorization: `Token ${process.env.READWISE_TOKEN}` } }); return (await res.json()).results; } const books = await fetchBooks(); for (const book of books) { if (book.num_highlights === 0) continue; await rem.remember({ content: `Book: ${book.title} by ${book.author}\n` + `Category: ${book.category}\n` + `Highlights: ${book.num_highlights}\n` + `Summary: ${book.summary || "No summary"}`, namespace: "readwise:books", tags: [book.category, book.author], metadata: { readwise_book_id: book.id, title: book.title, author: book.author } }); }

Step 4: Query Your Reading

// Ask about concepts across all your reading const results = await rem.recall({ query: "What have I read about habit formation?", namespace: "readwise", limit: 10 }); results.forEach(m => { console.log(`From "${m.metadata.book_title}" by ${m.metadata.author}:`); console.log(` ${m.content.slice(0, 150)}...\n`); });

Incremental Sync

Track the last sync time and only fetch new highlights on subsequent runs:

import fs from "fs"; const stateFile = ".readwise-sync-state.json"; let lastSync = null; if (fs.existsSync(stateFile)) { lastSync = JSON.parse(fs.readFileSync(stateFile, "utf-8")).lastSync; } const newHighlights = await fetchHighlights(lastSync); console.log(`${newHighlights.length} new highlights since last sync`); // ... import logic ... fs.writeFileSync(stateFile, JSON.stringify({ lastSync: new Date().toISOString() }));

Cross-source connections: REM Labs entity extraction automatically links related concepts across books and articles. A highlight about "spaced repetition" from a psychology book will surface alongside a blog post about "learning techniques" -- connections Readwise alone cannot make.

Turn your highlights into AI memory

Free tier. Readwise API sync. Semantic search across everything you read.

Get Started