Integration
April 13, 2026
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
- Book highlights -- Kindle annotations with book title and author
- Article clippings -- Instapaper, Pocket, and Reader highlights
- Podcast notes -- Snipd and Airr captures
- Your annotations -- notes you added to each highlight
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