# Books & ISBN Scraper: Open Library (`glitchbound/books-scraper`) Actor

Search millions of books by title, author or subject, or look up exact editions by ISBN: authors, publishers, publication year, page count, subjects, ratings, cover images and full-text availability. Open, freely licensed bibliographic data, no key.

- **URL**: https://apify.com/glitchbound/books-scraper.md
- **Developed by:** [Daniel Meshulam](https://apify.com/glitchbound) (community)
- **Categories:** E-commerce, AI, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 books

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Books & ISBN Scraper: Open Library

Search **millions of books** by title, author or subject, or look up an exact edition by ISBN.

Built on Open Library, the Internet Archive's open bibliographic database. Official free API, no key, and the data is **openly licensed** rather than scraped off a retailer's page.

### Two lookup paths

**Search**: `searchQueries: ["dune"]`, `author: "Frank Herbert"`, `subject: "science fiction"`
Answers *"what books exist about X / by Y"*. Returns works with edition counts, ratings and cover art. `author` and `subject` work on their own, leave the query empty to pull an author's whole catalogue.

**ISBN**: `isbns: ["978-0-441-01359-3"]`
Answers *"what exactly is this barcode"*. Returns the specific edition: page count, publisher, publish date, cover, and cross-IDs (ISBN-10/13, Goodreads, Open Library). Hyphens and spaces are fine.

### What you get

| Field | Example |
|---|---|
| `title`, `subtitle`, `authors` | `Dune`, `["Frank Herbert"]` |
| `firstPublishYear`, `publishDate` | `1965` |
| `publishers`, `numberOfPages` | `["Ace Books"]`, `528` |
| `isbn`, `isbn10`, `isbn13`, `isbns` | |
| `editionCount` | `77` |
| `ratingsAverage`, `ratingsCount`, `wantToReadCount` | `4.2`, `1841` |
| `subjects`, `languages` | |
| **`hasFullText`, `ebookAccess`** | `true`, a readable scan exists |
| `coverUrl` | large cover image |
| `openLibraryKey`, `goodreadsId`, `url` | |
| `excerpt` | on ISBN lookups, when published |

### Filters

- `yearFrom` / `yearTo`, first publication window
- `minRating`, 1-5; books with no ratings are dropped
- **`readableOnly`**: only books with a full-text scan in the Internet Archive. The difference between "this book exists" and "you can actually read it."

Filtered-out books are **not charged**.

### Who this is for

- **Booksellers & resellers**: bulk ISBN enrichment with covers, page counts and publishers
- **Libraries & catalogues**: clean, openly-licensed metadata you may redistribute
- **Reading apps & recommenders**: subject and rating data across millions of works
- **Researchers**: publication history by author, subject or period
- **AI / dataset builders**: structured bibliographic data with no licensing trap

### ISBN lookup and book search, on Open Library

Backed by **Open Library**, the Internet Archive's open bibliographic database.
No key, no quota page, no per-call licence.

| You want | Input |
|---|---|
| A specific edition by its barcode | `isbns`, ISBN-10 or ISBN-13 |
| Books matching a title or keyword | `searchQueries` |
| Everything by one author | `author` |
| A whole subject or genre | `subject` |

**Per book**: title, subtitle, authors, publishers, publication year, page
count, subjects, ISBN-10 and ISBN-13, cover image URLs, the Open Library key and
work ID, ratings where the community has left them, and whether a full-text scan
exists.

**`readableOnly` is the filter worth knowing about.** Turn it on and you get only
books with a scan you can actually read through the Internet Archive, rather than
catalogue records for editions that exist somewhere on a shelf. For building a
reading list or a corpus, that is the difference between a usable result and a
bibliography.

**Filters**: `yearFrom` / `yearTo` for a publication window, `minRating`, and
`maxResultsPerQuery`.

**Licensing.** Open Library data is published under the Open Database License,
so it is free to use and redistribute with attribution. That is a real
difference from retailer catalogue data, which is not.

### Notes

- ISBN-13s must start with `978` or `979`; anything else is rejected as invalid rather than silently returning nothing.
- Ratings come from Open Library's own community and are sparser than a retailer's. `minRating` therefore removes a lot of otherwise valid books, use it deliberately.
- An unknown ISBN returns an `error` row explaining that Open Library holds no record, rather than an empty result.
- Set a **max charge per run** in the run options for a hard spend ceiling. The Actor honors it and stops cleanly.

### Pricing

Pay per result. One row = one book or edition. Failed lookups come back as `error` rows and are **not** charged, and neither is anything your filters removed.

# Actor input Schema

## `searchQueries` (type: `array`):

Titles or keywords to search for, one per line, e.g. "dune", "machine learning".

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

Look up exact editions by ISBN-10 or ISBN-13. Hyphens and spaces are fine.

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

Restrict results to this author, or use it on its own to list an author's whole catalogue.

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

Restrict to a subject, e.g. "science fiction", "cookbooks". Works on its own too.

## `maxResultsPerQuery` (type: `integer`):

Cap per query, before filtering.

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

Only books first published in or after this year.

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

Only books first published in or before this year.

## `minRating` (type: `integer`):

Only books rated at least this (1-5). Books with no ratings are dropped.

## `readableOnly` (type: `boolean`):

Only books with a full-text scan available through the Internet Archive, meaning ones you can actually read, not just records that exist.

## `proxyConfiguration` (type: `object`):

Proxy settings.

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

A hard ceiling on rows for the entire run, across every target. The per-target limits above cap each one separately, so fifty targets at twenty each is still a thousand rows; this caps the total. The run stops cleanly when it is reached and nothing beyond that point is fetched or charged. Leave empty for no ceiling.

## Actor input object example

```json
{
  "searchQueries": [
    "dune"
  ],
  "maxResultsPerQuery": 50,
  "readableOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Books and editions with authors, publisher, ISBN and cover art.

# 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 = {
    "searchQueries": [
        "dune"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("glitchbound/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 = { "searchQueries": ["dune"] }

# Run the Actor and wait for it to finish
run = client.actor("glitchbound/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 '{
  "searchQueries": [
    "dune"
  ]
}' |
apify call glitchbound/books-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,glitchbound/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/dxwBf08s4Co5fKieN/builds/qGVUWa8xWrWOayr5Z/openapi.json
