---
title: "Open Library book and edition finder"
type: "skill"
url: "https://useaiblocks.com/skills/open-library-book-and-edition-finder"
updated: "2026-10-28"
first_published: "2026-10-25"
job: "Research a topic properly"
tested: true
licence: "MIT"
source: "https://github.com/magnus919/agent-skills/tree/92c327e525da69c9ad3812fd223a1770e977c2e3/openlibrary"
instructions: "https://useaiblocks.com/skills/open-library-book-and-edition-finder/SKILL.md"
---

# Open Library book and edition finder

> Find a book, its editions, author details and cover links from a title, author or ISBN. Uses the free Open Library catalog. No account needed.

Share a book title, author, ISBN, or Open Library record number. It looks up the public catalog and follows links between books, editions, and authors. You get matching records and source details. Live lookups need Python, its requests package, and internet access.

Free skill for the job "Research a topic properly" · Level: intermediate · Thinking: medium · Tested · Updated 2026-10-28

## Links

- Page: https://useaiblocks.com/skills/open-library-book-and-edition-finder
- Instructions (SKILL.md): https://useaiblocks.com/skills/open-library-book-and-edition-finder/SKILL.md
- All files (zip): https://useaiblocks.com/skills/open-library-book-and-edition-finder.zip
- JSON version: https://useaiblocks.com/skills/open-library-book-and-edition-finder.json
- In your AI: connect https://useaiblocks.com/mcp and ask "Use AI Blocks to get open-library-book-and-edition-finder"

## What you give it

- A title, author, ISBN, or Open Library identifier, plus desired language or result limit.

## What you get

- Book and author matches, edition details, public ratings when available, and cover links.

## Example: what goes in and what comes out

### What goes in

- A book title, author name or ISBN
- An Open Library record number (optional)
- Your language or result limit (optional)

### Before you start

- An AI that can run code, with Python 3.8 or later and the requests package
- Internet access for live lookups

### What comes out

- **Book search results**: Matching books with title, authors, first year published, edition count and the work key.
- **Author details**: Bio, dates and photo link for an author, or a list of name matches.
- **Work record**: Description, subjects and cover link for one book across all its editions.
- **ISBN match**: The edition your ISBN points to, with its work and author keys and cover link.
- **Edition list**: Publisher, date and ISBN for each edition of a work, with a way to page through more.
- **Ratings**: Average rating, star counts and how many people want to read, are reading or have read it.

## Skip it when

- You run a library system, such as Koha, MARC batch work or patron records. Ask your library system vendor or admin team instead.
- You need paid book data feeds, such as ISBNdb or Google Books. Use that provider's own service.
- You want to manage your own Open Library reading lists or account. Do that by signing in on the Open Library site.

## How to use it

1. Add the skill to an AI that can read it and run its helper script. The folder includes the helper.
2. The bundled helper needs Python 3.8 or later, the requests package, and internet access for live catalog lookups.
3. Check the setup first. Ask your AI to run the helper with --help. If that fails, Python or the requests package is missing.
4. Give a title, author, ISBN, or record number. Say whether you want a work, one edition, all editions, or author details. A work is a book as an idea, an edition is one printing of it, and each has its own ID.
5. Ask for source record links and missing details. An offline plan does not mean a lookup has run.
6. Next, use the work key it finds to list every edition or read the ratings. Or take the ISBN and cover links to your library or bookshelf tool.

## What to do next

- [Zotero library manager](https://useaiblocks.com/skills/zotero-library-manager): Zotero library manager

## Sources and credits

- From Magnus Hedemark: https://github.com/magnus919/agent-skills/tree/92c327e525da69c9ad3812fd223a1770e977c2e3/openlibrary, shared under the MIT licence (original name: openlibrary).
- [openlibrary skill](https://github.com/magnus919/agent-skills/tree/92c327e525da69c9ad3812fd223a1770e977c2e3/openlibrary), Magnus Hedemark: Copied under the MIT licence. We gave it a plain name. We added Before you start and After this sections that link to other AI Blocks steps.

## Instructions (SKILL.md)

## openlibrary — Book Metadata from Open Library

> In plain words (added by AI Blocks): this skill looks up books, editions, authors and covers in the free Open Library catalog. An OL key ending in M is an edition, W is a work (the book as an idea) and A is an author. A 302 is a redirect that the tool follows for you. Report only what the catalog returned, and say so when a record is missing.

Query Open Library's 50M+ record catalog over its public HTTP API: search works
and authors, walk the edition/work/author graph by ISBN or OLID, enumerate
editions, and read community ratings. No API key exists; everything here is a
keyless GET.

<!-- needs: written by tools/add-needs.mjs for AI Blocks; not part of the original skill. Edit that tool, not this section. -->
### Before you start
Use the material below to do this job. If facts or tool access are missing, explain what you can finish and what must wait.

**What you need** (use your own material or the linked skill):
- **Your question** (yours): the decision or problem, and what a good outcome looks like.

How to start:
1. **Look first.** Use what they've already attached, pasted or put in their about-me note. In a coding assistant with file access, look in the project too for these by name.
2. **Check what's missing.** Look for your question. They can attach files, paste the details, or share a file path your assistant can read. Ask only for missing facts that change the result. If they ask you to start with what they have, complete the parts you can and mark the gaps.
3. **Do the job.** Follow the skill below with the facts and tools you have. Mark each gap with `MISSING:` where it belongs and never invent a fact to fill it.

**Tools that do this best:**
- **Python with requests and internet access:** The included lookup helper needs these tools. Offline instruction checks do not prove that live catalog access works.
<!-- /needs -->

### Setup

Nothing to authenticate: **the public Open Library API requires no API key** for
reads. There is no token, no registration step, no lazy-auth dance.

```bash
# Optional etiquette: identified User-Agent gets ~3x rate budget (~3 req/s vs ~1)
export OL_EMAIL="you@example.com"
```

Requires Python 3.8+ and `requests` only. `--help` and `--dry-run` work with no
environment at all. Write endpoints exist upstream but require an authenticated
Internet Archive session and are effectively internal — treat this surface as
read-only.

Three hosts matter and they serve different things:

| Host | Serves |
|------|--------|
| `openlibrary.org` | metadata JSON: search, records, ratings |
| `covers.openlibrary.org` | cover images + author photos (separate service) |
| `archive.org` | scan content / bulk dumps (redirect targets) |

### Essential Commands

#### find books — search

```bash
openlibrary search --query "dune"                       # relevance order
openlibrary search --query "dune" --sort editions       # most editions first
openlibrary search --query "dune" --sort new            # newest first
openlibrary search --query "foundation" --lang fr       # prefer French editions
openlibrary search --query "dune" --limit 5 --offset 10 # paginate
openlibrary search --query "dune" --json                # machine-readable
```

Results carry title, authors, `first_publish_year`, edition count, and the work
key (`/works/OL…W`) that feeds the other commands. The CLI validates `--sort`
choices client-side because an unknown sort value makes the server return a
plain-text HTTP 500.

#### find people who write — author search

```bash
openlibrary search-authors --query "asimov"             # name candidates
openlibrary search-authors --query "le guin" --limit 5
openlibrary search-authors --query "asimov" --json      # includes top_work, work_count
```

Author docs arrive with bare keys (`OL23919A`), unlike book search's path keys.

#### inspect records — author / work

```bash
openlibrary author OL23919A                # bio, dates, photo URL
openlibrary work OL1168083W                # description, subjects, cover URL
openlibrary work OL1168083W --json         # full record
```

Keys may be passed bare (`OL23919A`) or as paths (`/authors/OL23919A`) — the CLI
normalizes both.

#### resolve an ISBN

```bash
openlibrary isbn 9780451524935             # ISBN-10 or ISBN-13
openlibrary isbn 9780451524935 --json      # + resolved edition_key, work_keys, cover_url
```

Upstream, `/isbn/<isbn>.json` answers a **302 redirect** to the canonical
edition JSON (`/books/<OL…M>.json`). The CLI follows it and reports which
edition matched via `edition_key`. If the edition record lacks author names
(some ship `authors:null`), the CLI recovers them from the linked work.

#### list every edition of a work

```bash
openlibrary editions OL81699W                          # publisher/date/ISBN per edition
openlibrary editions OL81699W --limit 50 --offset 50   # page through large sets
openlibrary editions OL81699W --json                   # + next_offset when more exist
```

Backs onto `/works/<key>/editions.json`; `next_offset` is computed from the
server's prebuilt next-page link.

#### read the room — community signals

```bash
openlibrary ratings OL45804W               # average rating + shelf counts
openlibrary ratings OL45804W --json        # full distribution + bookshelves
```

Joins `/works/<key>/ratings.json` (`summary.average`, per-star `counts`) with
`/works/<key>/bookshelves.json` (`want_to_read`, `currently_reading`,
`already_read`).

### Global Flags

Position-independent; put them before or after the subcommand:

```bash
openlibrary --json search --query "dune"     # machine output anywhere
openlibrary --dry-run isbn 9780451524935     # preview the exact URL, no network
openlibrary --quiet search --query "dune"    # suppress diagnostics
```

| Flag | Effect |
|------|--------|
| `--json` | One JSON object on stdout instead of human text |
| `--dry-run` | Print the planned request as JSON without executing it |
| `--quiet` | Suppress non-essential output |
| `--verbose` | Verbose logging |

### Multi-Step Pipeline Recipes

#### ISBN → edition → work → author bio

The canonical walk across all three key types:

```bash
openlibrary isbn 9780451524935 --json | jq -r '.work_keys[0]'   # OL1168083W
openlibrary work OL1168083W --json | jq -r '.authors[0]'        # bare OL…A key
openlibrary author OL118077A                                    # bio, dates
```

The CLI keeps this pipeline type-safe: every command that emits an `authors`
field under `--json` (`isbn`, `work`) uses the same shape — an array of bare
OL…A keys — while human output renders comma-separated labels instead. Each hop
uses a different key suffix (M → W → A); see Known Gotchas before hand-assembling
these URLs yourself.

#### Rank a series by community love

```bash
for w in $(openlibrary search --query 'series:dune' --limit 8 --json | jq -r '.results[].key'); do
  openlibrary ratings "${w##*/}" --json \
    | jq -c '{work: .key, avg: .average, rated: .ratings_count,
              want_to_read: .bookshelves.want_to_read}'
done
```

#### Find readable ebooks, then their print editions

```bash
openlibrary search --query 'title:"moby dick"' --sort editions --json \
  | jq '.results[] | select(.has_fulltext) | {title, key}'
openlibrary editions OL81699W --json | jq '.editions[] | {key, isbn_13}'
```

### Using --json with jq

```bash
openlibrary search --query "voracious" --json | jq '.results[] | {title, first_publish_year}'
openlibrary search-authors --query "butler" --json | jq '.results[0] | {name, key, top_work}'
openlibrary isbn 9780451524935 --json | jq -r '.cover_url'          # covers host URL
openlibrary editions OL81699W --json | jq '[.editions[].publish_date]'
openlibrary ratings OL45804W --json | jq '.rating_distribution'
```

### Known Gotchas

- **ISBN endpoints answer 302, not JSON** — `/isbn/<isbn>.json`, `/lccn/*.json`,
  `/oclc/*.json` redirect to `/books/<OL…M>.json`. Clients must follow redirects
  (`curl -L`; `requests` does by default) or they parse an HTML redirect page.
  Direct `/books/<OLID>.json` calls return 200 immediately.
- **Merged keys return redirect stubs inside HTTP 200** — Open Library is a wiki;
  when duplicate works merge, the old key keeps answering 200 with
  `{"type":{"key":"/type/redirect"},"location":"/works/<master>"}` instead of a
  3xx. Detect the stub type in success responses and re-fetch. The bundled CLI
  does this automatically (and appends `.json` to stub locations, since
  extension-less URLs redirect to HTML pages).
- **Key types are encoded in the suffix** — `OL…M` = edition (`/books/`),
  `OL…W` = work (`/works/`), `OL…A` = author (`/authors/`). Works link to
  authors double-nested (`authors[].author.key`); editions nest flat
  (`authors[].key`) — or ship `authors:null` entirely, recovering names from the
  linked work. Requesting a key under the wrong collection yields a 301 reroute.
- **Search empties are not errors** — malformed queries parse loosely and come
  back HTTP 200 with `numFound:0`; conversely a bad `sort=` enum is a plain-text
  HTTP 500 and non-integer `limit` is a FastAPI 422. Branch on bodies, not just
  status codes.
- **`availability` needs `ia`** — in raw `/search.json` calls, requesting
  `fields=availability` silently returns nothing unless `ia` is also requested.
- **Covers live on another host** — image URLs are always
  `covers.openlibrary.org/b/id/<cover_id>-{S,M,L}.jpg` (or `/b/isbn/...`,
  `/a/id/...` for author photos). Missing covers return a blank placeholder with
  HTTP 200 unless you add `?default=false`; non-ID/non-OLID lookups cap at 100
  req/IP per 5 min then 403; cover URLs often 302 into archive.org zip shards.
- **Rate limits are policy, not headers** — no Retry-After/X-Rate-Limit headers
  exist. Anonymous ≈1 req/s; a `User-Agent: App (email)` (set `OL_EMAIL`)
  raises it to ≈3 req/s. Batch with one search rather than hundreds of lookups;
  bulk belongs in monthly dumps.
- **Text fields nest `{type,value}` objects** — older records wrap `bio`,
  `description`, `notes` as `{"type":"/type/text","value":"..."}` while newer
  ones use plain strings. Handle both; the CLI unwraps centrally.
- **OLID ≠ long-term identity** — deleted keys can be reassigned to unrelated
  books, and merged-away keys become redirect stubs. Pair OLIDs with title/ISBN
  in any cache.
- **`.json` placement matters for slugged URLs** — append `.json` to the bare
  key (`/authors/OL23919A.json`), never after a slug path.

### When to use

- Any question about books, authors, or works Open Library's public catalog can answer
- Resolving ISBNs/OLID keys to canonical records and walking edition/work/author graphs
- Finding readable or borrowable scans, cover images, community ratings/shelf counts

### When not to use

Do not use this skill for local library-catalog administration — Koha/Evergreen
ILS configuration, MARC batch processing, patron management — or for licensed
commercial data feeds (ISBNdb, Google Books), citation formatting, or managing
your own Open Library reading account/lists (that requires site login this skill
deliberately does not handle). For movie/TV metadata use tmdb instead.

### Reference Files

| File | Topic | Read when |
|------|-------|-----------|
| [references/api-overview-and-key-graph.md](references/api-overview-and-key-graph.md) | Access model, rate-limit etiquette, OLID M/W/A key graph, cross-collection 301s, merge-stub handling, `{type,value}` text wrapping | Assembling record URLs by hand, handling merges/wrong-key errors, or planning request pacing |
| [references/search-api-guide.md](references/search-api-guide.md) | `/search.json` parameters, sort keys, field scopes (`title:`, `isbn:`, …), `fields=` projection incl. the availability/ia interaction, `/search/authors.json`, `/subjects/<name>.json`, inside-book search, error model | Building precise queries, paginating deep result sets, or debugging empty results |
| [references/books-isbn-and-covers.md](references/books-isbn-and-covers.md) | Identifier endpoints and their 302 resolution, raw records vs legacy `/api/books` view models, editions listing, ratings/bookshelves shapes, covers-host URL rules and limits | Working with ISBNs/LCCNs/OCLCs, enumerating editions, or fetching images |
| [references/recipes-and-gotchas.md](references/recipes-and-gotchas.md) | End-to-end curl/jq pipelines (ISBN→work→author chain, ebook discovery, cover assembly, disambiguation) plus a symptom-indexed gotcha table | Wiring multi-step workflows or diagnosing an unexpected response |

### Available Scripts

| Script | Purpose | Invocation |
|---|---|---|
| `scripts/openlibrary` | The CLI this skill drives: `search`, `search-authors`, `author`, `work`, `isbn`, `editions`, `ratings` — all with `--json`/`--dry-run`, automatic 302 + merge-stub resolution, `{type,value}` unwrapping, covers-host URL assembly, and client-side sort validation. Run it for every book-metadata question above. | `scripts/openlibrary search --query "dune" --json` |
| `scripts/test_openlibrary.py` | Offline pytest/unittest suite covering help, argument errors, dry-run plans, mocked-client logic (redirect stubs, author fallback, editions paging), plus two env-guarded live probes (`OPENLIBRARY_LIVE_TESTS=1`). Zero egress otherwise. | `.venv/bin/python3 -m pytest -p no:cacheprovider --strict-markers scripts/test_openlibrary.py` |

### Prerequisites

- Python 3.8+ with `requests` (stdlib otherwise); invoke as `python3 scripts/openlibrary ...` if not executable directly
- No credentials of any kind; optional `OL_EMAIL` for rate-limit etiquette
- `jq` recommended for `--json` post-processing

<!-- next: written by tools/add-needs.mjs for AI Blocks; not part of the original skill. Edit that tool, not this section. -->
### After this
When you've handed it back, suggest what they could do next in one short question. It's a suggestion: if they're done, that's fine. Offer these, and say they can type their own:
- The [Zotero library manager](https://useaiblocks.com/skills/zotero-library-manager). It takes the shortlist.
If they pick one and that skill is added here, carry straight on with what you just made. If not, give the link and say what to bring.
<!-- /next -->
