Sync Zotero Annotations to Readwise: The Zotero2Readwise Guide

There is still no official Zotero integration in Readwise as of July 2026 — the working solution is Zotero2Readwise, an open-source Python tool by Essi Alizadeh that pushes your Zotero highlights and notes into Readwise, either from your machine or on an automated schedule via GitHub Actions. It’s actively maintained (v1.4.2 shipped November 2025), the setup takes about twenty minutes, and this guide covers both routes plus the limitations the README won’t volunteer.

If you just want the verdict: the GitHub Actions route is the one to use. Set it up once, and every paper you highlight in Zotero starts appearing in your Readwise daily review without you touching anything again.

Why sync paper annotations into Readwise at all

Zotero is where annotations go to be stored; Readwise is where they go to be seen again. Readwise’s core mechanic is the daily review — a spaced-repetition resurfacing of a handful of your old highlights each morning, weighted so material you engage with returns more often. For book highlights this is a nice habit. For academic reading it addresses a real failure mode: the annotations on papers you read during comps or an early literature review are, functionally, gone. You will not reopen those PDFs unprompted.

Resurfacing changes the economics. A highlight from a paper you read fourteen months ago shows up next to something you’re working on now, and the connection you couldn’t have made then is suddenly available. It’s a weaker version of what a proper literature-note system gives you deliberately — but it runs on annotations you’ve already made, at zero marginal effort. If your workflow ends at highlighting (no judgment; most do), this is the cheapest way to make those highlights earn rent.

What Readwise costs

Verified against Readwise’s pricing page, July 2026:

  • Readwise Lite — $5.59/month billed annually. Daily review, search, and syncing from sources. This is the minimum tier for the Zotero use case.
  • Readwise Full — $9.99/month billed annually, or $12.99 month-to-month. Adds export to Obsidian and Notion, plus Readwise Reader, their read-later app (reviewed separately).
  • Trial: 30 days free. Academic discount: 50% off either plan with student/academic verification — worth claiming, since it puts Full at roughly $5/month.

Zotero2Readwise itself is free and open source. Note the sync consumes no special Readwise API tier; the standard access token works on any paid plan.

Before you start: the three credentials

Both setup routes need the same three values. Collect them first:

  1. Readwise access token — from readwise.io/access_token while logged in.
  2. Zotero API key — at zotero.org → Settings → SecurityCreate new private key. Grant read access to your personal library (read-only is sufficient; the tool never writes to Zotero).
  3. Zotero library ID — your numeric userID, shown on that same API keys settings page (“Your userID for use in API calls is …”). For a group library, use the group ID from the group’s URL instead.

Treat the first two like passwords. The Zotero key in particular grants access to your whole library; never paste either into a public repo file — that’s what the secrets mechanism below is for.

The companion repo Zotero2Readwise-Sync runs the sync on GitHub’s servers on a schedule. No Python on your machine, nothing to remember to run.

  1. Fork the repo. Log into GitHub, open e-alizadeh/Zotero2Readwise-Sync, click Fork. A free GitHub account is fine — the job runs well inside free Actions minutes.
  2. Add your three secrets. In your fork: Settings → Secrets and variables → Actions → New repository secret. Create three, with these exact names: READWISE_TOKEN, ZOTERO_KEY, and ZOTERO_ID. Secrets are encrypted and never visible in logs or to anyone browsing your fork — this is the correct way to handle the keys.
  3. Enable the workflow. GitHub disables scheduled workflows on fresh forks; open the Actions tab and click through the prompt to enable them.
  4. Trigger a first run rather than waiting for the schedule — either via the Actions tab’s manual run button on the workflow, or by pushing an empty commit (git commit --allow-empty -m "trigger sync" && git push). A few minutes later, your Zotero annotations appear in Readwise under their source items.

The default schedule is the cron line 0 3 * * 1,3,5 — 3:00 UTC on Monday, Wednesday, and Friday. Change it by editing .github/workflows/automation.yml in your fork (crontab.guru will sanity-check your expression). Two scheduling realities: GitHub delays scheduled runs by up to an hour under load, and GitHub suspends scheduled workflows in repos with no commit activity for 60 days — it emails you first, and clicking re-enable (or making any commit) revives it. That suspension is the most common way this setup silently dies.

Route 2: local Python

If you’d rather not put API keys on GitHub at all — a defensible position — run it locally. Requires Python 3.8+:

pip install zotero2readwise

Then grab the runner script and execute it with your three credentials as positional arguments:

curl -O https://raw.githubusercontent.com/e-alizadeh/Zotero2Readwise/master/zotero2readwise/run.py
python run.py <READWISE_TOKEN> <ZOTERO_KEY> <ZOTERO_ID>

Useful flags: --library_type group for group libraries, and --include_annotations / --include_notes to control whether PDF annotations, standalone Zotero notes, or both get pushed (annotations on, notes off by default; run python run.py -h for the current full list — recent versions have added filtering options). Re-running is safe: the tool updates rather than duplicates already-synced items.

The catch is the word “run.” A local script executes when you remember it, which for most people converges on never. If you go this route, wrap it in a cron job or scheduled task — otherwise Route 1 exists precisely because you won’t.

Limitations to accept before committing

All verified from the project’s README and issue tracker; none are dealbreakers, all are permanent characteristics.

  • One-way sync, Zotero → Readwise. Nothing flows back. Notes, tags, or edits you add in Readwise never reach Zotero. Zotero remains the source of truth; treat Readwise as a read-only mirror with a resurfacing engine attached.
  • Only Zotero’s own reader counts. The tool reads annotations from Zotero’s built-in PDF reader (the one shipped since Zotero 6; Zotero is at version 9 as of April 2026). Highlights made in external apps — Acrobat, PDF Expert, GoodNotes — live inside the PDF file, invisible to Zotero’s database and therefore to the sync. If you annotate on an iPad, use the Zotero app’s reader.
  • Text only. Image annotations — area selections around figures, equations, tables — don’t transfer. For a figure-heavy reading practice, a meaningful slice of your annotations stays behind.
  • Tag behavior is limited. Don’t architect a workflow around Zotero annotation tags or highlight colors carrying semantic weight into Readwise; historically they haven’t transferred cleanly, and the issue tracker is where to check the current state before relying on it.
  • Edits don’t propagate reliably as deletions. Deleting a highlight in Zotero won’t reliably remove the already-synced copy in Readwise. Expect the Readwise side to accumulate.

Maintenance

Close to zero, with two scheduled exceptions. First, the 60-day Actions suspension above — when the email arrives, click re-enable. Second, credential rot: if you regenerate your Zotero key or Readwise token, update the repository secrets, or runs fail silently until you look at the Actions tab. A calendar reminder to glance at that tab quarterly covers both. Version upgrades are automatic in the Actions route (the workflow pulls the current library release); locally, pip install --upgrade zotero2readwise occasionally.

If you don’t want to touch GitHub at all

The honest answer for non-technical users is to move the annotation step rather than sync it: read your PDFs in Readwise Reader instead. Reader (included in the Full plan) accepts PDF uploads, its highlights land in Readwise natively with zero configuration, and the daily review picks them up like everything else. You lose Zotero’s reader and keep Zotero purely for reference management and citation — a real trade-off for heavy annotators, examined in our Reader review.

What you shouldn’t do is wait for an official integration; Readwise’s Zotero request threads are years old and academic reference managers are visibly not the roadmap priority. And if your endgame is notes you actually work with rather than resurfaced highlights, the deeper fix is routing Zotero annotations into a proper note system — the Zotero-Obsidian workflow — with Readwise as a complement, not the destination. For highlight resurfacing specifically, though, Zotero2Readwise is the answer in 2026: a twenty-minute setup that keeps paying out every morning.