# Open Library Scraper: Books, Ratings & ISBN Data (`recordsdata/open-library-books-scraper`) Actor

Scrape Open Library books: search by title, author, subject or year with ratings and want-to-read counts, look up ISBNs for publisher and pages, and pull work details with rating breakdowns. Export CSV, Excel, JSON, XML. No login or API key. From $0.013 per book.

- **URL**: https://apify.com/recordsdata/open-library-books-scraper.md
- **Developed by:** [RecordsData](https://apify.com/recordsdata) (community)
- **Categories:** Education, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

<p align="center">
  <img src="https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner?v=3" alt="RecordsData" width="100%" />
</p>

## 📖 Open Library Scraper: Books, Ratings & ISBN Data

> **Open Library Scraper is an Apify actor that exports book, edition, work, author and subject data from openlibrary.org. Search by title, author, subject, publisher, language, ebook access or year and get ratings, want-to-read counts and edition counts per book. Look up ISBNs, work IDs, authors and subjects. Up to 91 fields, no login, no API key. Export CSV, Excel, JSON or XML. Books cost $13 per 1,000 rows on the base tier, with no start fee. Last updated 2026-10-11.**

Open Library Scraper turns the Open Library catalog into clean datasets. A live check on 2026-10-03 found 48,254 results for the query "dune" and 1,407 works for the author Frank Herbert. Dune alone shows 446 ratings, 3,418 want-to-read and 155 editions.

### 📚 What does Open Library Scraper do?

- Search books by keyword with optional author, subject, publisher, language (3-letter code or English name, comma = OR), ebook access, minimum ratings count and first-publication year range. A query needs at least 3 characters, or browse with filters alone.
- Look up ISBNs (one row per edition) and work IDs, following merged works.
- Author mode (names, IDs or URLs) and subject mode (names or slugs such as `place:london`).
- Skip duplicates and never charge for error, not-found or empty rows.

### 🗂️ What data can you extract from Open Library?

The dataset has 91 fields and four views (Books, Authors, Subjects, Editions). Each row has a `recordType`: book, edition, work, author or subject.

| Record type | Main fields |
|---|---|
| Book (search) | title, authors, firstPublishYear, ratingsAverage, ratingsCount, wantToRead, currentlyReading, alreadyRead, editionCount, languages, ebookAccess, subjects, publishers, isbn, coverUrl, url |
| Edition (ISBN) | isbn10, isbn13, title, publishers, publishDate, pages, physicalFormat, workId |
| Work (work ID) | title, description, subjects, ratingsAverage, ratingsBreakdown (1 to 5 stars), reading counts |
| Author | authorId, name, birthDate, workCount, topWork, topSubjects, plus bio, links, remoteIds (Wikidata, VIAF, ISNI) with details |
| Subject | subjectKey, name, workCount, ebookCount, relatedSubjects, topAuthors, topPublishers |

New columns are left out of a row when empty. Every row follows one fixed order of 91 columns and has `scrapedAt`.

### 🧾 Sample output

A real book row from a cloud run (author filter Frank Herbert; newer columns not shown):

```json
{
  "recordType": "book",
  "workId": "OL893414W",
  "title": "Dune",
  "authors": ["Frank Herbert"],
  "firstPublishYear": 1965,
  "ratingsAverage": 4.3,
  "ratingsCount": 446,
  "wantToRead": 3418,
  "alreadyRead": 727,
  "editionCount": 155,
  "subjects": ["Dune (Imaginary place)", "Fiction", "Science fiction"],
  "isbn": "9780441013593",
  "coverUrl": "https://covers.openlibrary.org/b/id/11481354-M.jpg",
  "url": "https://openlibrary.org/works/OL893414W",
  "scrapedAt": "2026-10-04T04:18:23.444Z"
}
```

### 💰 How much does it cost to scrape Open Library?

Pay per event, charged only for rows saved to your dataset. Prices are the base (free plan) tier; paid plans get lower rates (read 2026-10-10).

| Event | What you get | Price (base tier) |
|---|---|---|
| book-record | One searched book with ratings and reading stats | $0.013 ($13 per 1,000); $0.0125 Bronze, $0.012 Silver, $0.01 Gold and above |
| edition-record, work-record, author-record, subject-record | One ISBN edition, work, author or subject | $0.01 on every tier |

Worked examples at the base tier: 10 searched books cost $0.13, 100 cost $1.30 and 1,000 cost $13.00. Looking up 1,000 ISBN editions or work details costs $10.00. 100 author rows cost 100 x $0.01 = $1.00, and 100 subject rows cost $1.00.

There is no start fee. You are not charged for error rows, "ISBN not found" rows, duplicates, empty searches or failed runs. A maximum cost per run is respected.

### 🚀 How to scrape Open Library (3 steps)

1. Click **Try for free**.
2. Enter a query or filters, or paste ISBNs, work IDs, authors or subjects, and set **Max Items**.
3. Click **Start** and download the dataset.

### ⚙️ Input

| Field | Type | Description |
|---|---|---|
| searchQuery | string | Title or keywords, at least 3 characters. Optional |
| author / subject / publisher / language | string | Filters on the book search; language is a code or English name, comma = OR (`eng,French`) |
| ebooksOnly / ebookAccess | boolean / enum | Full-text ebooks only; or any, public, borrowable, printdisabled, no_ebook |
| yearFrom / yearTo, minRatingsCount | integer | Year range, minimum ratings |
| sortBy | enum | relevance, rating, new, old, editions, want_to_read, trending |
| includeWorkDetails, coverSize | boolean, enum | Work details on book rows (off by default); cover size S, M or L |
| isbns, workIds | string list | ISBN-10/13; work IDs such as `OL893414W` |
| authorSearch, authorIds, authorSortBy, includeAuthorDetails | string, list, enum, boolean | Search authors by name or give IDs (`OL79034A`) or URLs; optional biography, links, Wikidata/VIAF/ISNI, photo |
| subjectNames | string list | Names, slugs (`place:london`) or subject URLs |
| maxItems | integer | Row limit, default 10. Free users are capped at 10 |

At least one query, filter, ISBN, work ID, author input or subject is required. A search returns up to 100,000 rows per run; all modes share `maxItems`. An empty or invalid input ends as SUCCEEDED with one free error row.

```json
{
  "searchQuery": "dune",
  "language": "eng",
  "ebooksOnly": true,
  "maxItems": 5
}
```

### 📦 Output

Results go to the default dataset with four views: Overview (books and works), Authors, Subjects and Editions. A search that matches nothing succeeds with "No results found" and charges nothing; if Open Library errors and zero rows are delivered, the run fails.

### ⚖️ Open Library Scraper vs alternatives

Store pages read on 2026-10-10. "Not stated" means the listing does not show it.

| | This actor | parseforge/open-library-scraper | eins332570/book-scraper |
|---|---|---|---|
| Price per row | $0.013 Free, $0.01 Gold, no start fee | $0.012 plus $0.16 per run start | $0.005 |
| Language and ebook filters | Yes, codes or names; access type | Ebooks toggle; language not stated | Language code, search only |
| Authors, subjects, ISBN, work IDs | Yes, all | Authors and subjects by search type | ISBN and work IDs |
| Reading lists, search inside | No | Yes, search types | Not stated in their listing |
| Fields | 91 | Not stated in their listing | 19 |

parseforge is cheaper for small runs (10 rows: $0.13 here against $0.28 there) and about even at 100 rows ($1.30 against $1.36). At 1,000 rows on the base tier we are about 7% dearer ($13.00 against $12.16). logiover/openlibrary-scraper ($0.003 per row) and bovi/openlibrary-scraper ($0.001) are cheaper per row and return fewer fields; neither lists a language or ebook filter. Choose a cheaper actor for bare search rows, this one for reading counts, filters, ISBN editions and author or subject records.

### 💡 Use cases

- **Listing enrichment and apps:** add pages, publisher, cover and ratings to every ISBN.
- **Ebook catalogues:** list borrowable ebooks in one language.

### 🔌 Run via API, schedule and integrations

```bash
curl -X POST "https://api.apify.com/v2/acts/RecordsData~open-library-books-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"dune","language":"eng","ebooksOnly":true,"maxItems":10}'
```

Use the API, schedule runs, and send the dataset to Zapier, Make, n8n or Google Sheets.

### 🤖 Open Library Scraper MCP server for AI agents

AI agents can call Open Library Scraper through the Apify MCP server at `https://mcp.apify.com?tools=RecordsData/open-library-books-scraper`. The URL loads only this Actor as a tool (Claude Desktop, Cursor, VS Code):

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=RecordsData/open-library-books-scraper"
    }
  }
}
```

Example agent prompt:

> Use the Open Library Scraper to list 10 English books with a public ebook about the Roman Empire, sorted by want-to-read, then give me each title with its ratingsAverage, wantToRead and editionCount.

Tool description: choose Open Library Scraper when an agent needs book metadata from Open Library: ratings and reader-demand counts for searched books, language and ebook-access filtering, publisher and page data for an ISBN, the description and rating breakdown for a work ID, or an author or subject record.

### ⚖️ Is it legal to scrape Open Library?

The actor reads Open Library's public API, which serves open catalog data, with an identified user agent and polite delays. It collects book metadata only, not personal data. Follow Open Library's terms and cover image licenses.

### ❓ Frequently asked questions

#### What is the difference between a work and an edition in Open Library Scraper?

A work is the book as a title, such as Dune, and an edition is one of its printings, such as the 155 editions of Dune. The scraper returns works for keyword, author or subject searches, and edition rows for ISBN lookups. Work IDs return full work details.

#### Where do the ratings in Open Library Scraper come from?

They come from Open Library's own reader ratings on openlibrary.org. The scraper returns the average rating and the number of ratings for each book, plus want-to-read, currently-reading and already-read counts, so you can rank titles by reader demand. Work lookups also return the 1 to 5 star breakdown.

#### Does Open Library Scraper need an API key or login?

No. It reads the public Open Library API, which serves open catalog data, so there is no login, no API key and no cookie to set up. You only need an Apify account to run the actor, and the free plan works for small tests.

#### Why did Open Library Scraper return 0 results?

The search matched nothing on Open Library, for example with a very narrow combination of filters. Try fewer filters. The run ends as succeeded with the message "No results found", and nothing is charged for the empty search, so you can test narrow filters freely.

#### What happens if I send an empty or invalid input to Open Library Scraper?

Wrong enum values or types are rejected with a 400 error before any run starts. Other mistakes, such as a query under 3 characters, an unknown language, `yearFrom` later than `yearTo` or no input, end the run as SUCCEEDED with one free error row and no charge.

#### Why is there a row with an error field in Open Library Scraper output?

An ISBN, work ID, author or subject was not found on Open Library, or Open Library returned an error for that lookup. The scraper keeps such a row so you can see which input failed, and never charges for it. A long list of wrong ids stops after max(25, min(maxItems, 1000)) failures.

#### How many rows can I get from Open Library Scraper?

Free users get 10 rows per run. Paid users can request up to 1,000,000 rows through `maxItems`, and a single book search returns up to 100,000 rows. Paid users can raise `maxItems` up to 1,000,000. Split larger harvests into several searches by author, subject, language or year.

#### Can I get cover images from Open Library Scraper?

Yes. Every row for which Open Library has a cover includes a direct covers.openlibrary.org image URL in `coverUrl`, next to the canonical link in `url`. Pick the size with `coverSize`. Only links are returned, so check cover licenses before republishing the images.

#### Can I limit my spend with Open Library Scraper?

Yes. Set Max Items to cap the number of rows, or set the maximum cost per run in Apify. The scraper stops cleanly when the limit is reached and you pay only for rows saved to the dataset. A book row costs $0.013 and other rows $0.01 at the base tier.

#### How do I filter Open Library books by language?

Set `language` to a 3-letter Open Library code or an English name, for example `eng` or `French`. Separate several with commas to match any of them. The filter keeps works with an edition in that language. An unknown language ends with a free error row.

#### How do I get only ebooks with Open Library Scraper?

Turn on `ebooksOnly` to keep books that have a full-text ebook on Open Library or the Internet Archive. For finer control set `ebookAccess` to public, borrowable, printdisabled or no_ebook. Rows carry `ebookAccess`, `hasFulltext` and `ebookCount`, so you can also check access in the dataset.

#### Can Open Library Scraper return author data?

Yes. Use `authorSearch` with a name, or `authorIds` with Open Library author IDs or URLs. Author rows have birth and death dates, work count, top work, top subjects, alternate names and reader counts. `includeAuthorDetails` adds biography, links, Wikidata, VIAF and ISNI ids and a photo.

#### Can Open Library Scraper return subject data?

Yes. Give `subjectNames` as names or slugs such as `science fiction`, `place:london` or `time:20th_century`, or as a subject URL. Each subject gives one row with work count, ebook count, related subjects, places, people, times, top authors and top publishers; books under a subject come from the `subject` filter.

#### Can I browse Open Library without a search query?

Yes. A query is optional. Filters alone, such as `language`, `publisher`, `ebooksOnly`, `ebookAccess`, a year range or `minRatingsCount`, are a valid run. If you do give a query, it needs at least 3 characters; a shorter one ends the run with a free error row and no charge.

#### Can I get 100,000 rows from one Open Library search?

Yes, if your plan allows it. One book search returns up to 100,000 rows per run, and `maxItems` sets the limit (free users get 10). Large runs take longer because Open Library answers deep result pages slowly, so set Max Items or a maximum cost per run to keep them bounded.

#### What does includeWorkDetails do?

It adds `description`, `links` and `firstPublishDate` to each book row. That needs one extra Open Library request per row, so runs are slower, and it is off by default. There is no extra charge, and you only need it on book search rows.

#### Why do very large subjects like history return only a work count?

Open Library sometimes answers a very large subject, such as history or poetry, with a bare record after about 11 seconds. The scraper retries once, then counts the works through the search index and returns the work count with the other subject columns left out.

#### Did the column order change in Open Library Scraper?

Yes. Every row now follows one fixed order of 91 columns, so columns that existed before moved position in CSV and Excel. Names and meanings did not change. If a script reads columns by position, check it once or switch to column names.

#### Can Open Library Scraper return reading lists or search inside books?

No. Open Library reading lists are user-generated, and the search-inside endpoint was failing with HTTP 500 when this version was built, so neither is part of this actor, and no data for them is returned. Books, editions, works, authors and subjects are covered.

### 🔗 Want more data? Other RecordsData scrapers

[Wikipedia Articles Scraper](https://apify.com/RecordsData/wikipedia-articles-scraper), [Hacker News Search Scraper](https://apify.com/RecordsData/hackernews-search-scraper) and [PubMed Articles Scraper](https://apify.com/RecordsData/pubmed-articles-scraper).

### 🛟 Support

Issues tab or email contact.punkrecordsdata@gmail.com.

Last updated: 2026-10-11

# Actor input Schema

## `searchQuery` (type: `string`):

Search Open Library books by title or keywords (at least 3 characters), for example dune or science fiction classics. Leave empty to browse with the filters, or to use only the ISBN, work ID, author or subject inputs. At least one search input is required.

## `author` (type: `string`):

Filter the book search by author name, for example Frank Herbert. Combine with a search query, subject or year range.

## `subject` (type: `string`):

Filter the book search by subject or genre, for example fantasy or biography.

## `language` (type: `string`):

Only return books that have at least one edition in this language. Use the 3-letter Open Library code (eng, fre, ger, spa, por, ita, rus, jpn, chi, lat) or the English name (French, German). Several languages separated by commas return books in any of them, for example eng, fre.

## `ebooksOnly` (type: `boolean`):

Only return books that have a full-text ebook on Open Library or the Internet Archive (free to read or borrowable). Applies to the book search.

## `ebookAccess` (type: `string`):

Filter by how the ebook can be read: public (free to read), borrowable (lending library), printdisabled (print-disabled readers only) or no_ebook (no digital copy). Any applies no filter. Applies to the book search.

## `publisher` (type: `string`):

Only return books with an edition from this publisher, for example Penguin or Ace Books. Applies to the book search.

## `yearFrom` (type: `integer`):

Only return books first published in this year or later, for example 1960. Applies to the book search.

## `yearTo` (type: `integer`):

Only return books first published in this year or earlier, for example 1980. Applies to the book search.

## `minRatingsCount` (type: `integer`):

Only return books with at least this many reader ratings, for example 50. Useful to skip books nobody rated. Applies to the book search.

## `sortBy` (type: `string`):

Order of book search results: relevance, rating (best first), newest, oldest, most editions, most wanted-to-read or trending (Open Library trending score).

## `includeWorkDetails` (type: `boolean`):

Adds the work description, links and first publish date to every book row. Costs one extra request per row, so the run is slower (about 1 second per row). Off by default.

## `coverSize` (type: `string`):

Size of the cover image link in the output: S (small), M (medium, default) or L (large).

## `isbns` (type: `array`):

List of ISBN-10 or ISBN-13 numbers. Each valid ISBN returns one edition row with publisher, publish date, page count and format.

## `workIds` (type: `array`):

List of Open Library work IDs such as OL893414W (or the full work URL). Each returns one work row with description, subjects and the 1-5 star rating breakdown.

## `authorSearch` (type: `string`):

Find authors by name (at least 3 characters), for example Frank Herbert. Each author is one row with birth and death date, number of works, top work, top subjects and reader counts. Wrap a full name in double quotes for an exact phrase.

## `authorSortBy` (type: `string`):

Order of the author search results: relevance (an exact name match comes first), most works first, name A to Z, or birth date oldest or youngest first.

## `authorIds` (type: `array`):

List of Open Library author IDs such as OL79034A (or the full author URL). Each returns one author row.

## `includeAuthorDetails` (type: `boolean`):

Adds biography, links, external ids (Wikidata, VIAF, ISNI) and photo to every author row. Costs one extra request per author, so the run is slower. Off by default.

## `subjectNames` (type: `array`):

List of Open Library subjects, for example science fiction, fantasy or place:london, person:sherlock_holmes, time:20th_century. Each returns one subject row with the number of works, ebooks, related subjects, top authors and publishers. Use the subject filter to list the books of a subject.

## `maxItems` (type: `integer`):

Maximum number of rows to return across book search, ISBN, work, author and subject results. Free Apify users are limited to 10 rows; paid users can go up to 1,000,000. You are only charged for rows delivered.

## Actor input object example

```json
{
  "searchQuery": "dune",
  "author": "",
  "subject": "",
  "language": "",
  "ebooksOnly": false,
  "ebookAccess": "any",
  "publisher": "",
  "sortBy": "relevance",
  "includeWorkDetails": false,
  "coverSize": "M",
  "isbns": [],
  "workIds": [],
  "authorSearch": "",
  "authorSortBy": "relevance",
  "authorIds": [],
  "includeAuthorDetails": false,
  "subjectNames": [],
  "maxItems": 10
}
```

# Actor output Schema

## `overview` (type: `string`):

Key fields per book or work row

## `authors` (type: `string`):

Author rows with birth and death dates, work counts and reader counts

## `subjects` (type: `string`):

Subject rows with work counts, related subjects and top authors

## `editions` (type: `string`):

ISBN edition rows with publisher, pages and format

## `fullData` (type: `string`):

Complete dataset with all fields

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "dune",
    "author": "",
    "subject": "",
    "language": "",
    "publisher": "",
    "isbns": [],
    "workIds": [],
    "authorSearch": "",
    "authorIds": [],
    "subjectNames": [],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("recordsdata/open-library-books-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "dune",
    "author": "",
    "subject": "",
    "language": "",
    "publisher": "",
    "isbns": [],
    "workIds": [],
    "authorSearch": "",
    "authorIds": [],
    "subjectNames": [],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("recordsdata/open-library-books-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "dune",
  "author": "",
  "subject": "",
  "language": "",
  "publisher": "",
  "isbns": [],
  "workIds": [],
  "authorSearch": "",
  "authorIds": [],
  "subjectNames": [],
  "maxItems": 10
}' |
apify call recordsdata/open-library-books-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,recordsdata/open-library-books-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zRLZiJej1hPc8KSha/builds/H2OvBCDd8JvYjkjz8/openapi.json
