Open Library & Gutenberg Book Lookup avatar

Open Library & Gutenberg Book Lookup

Pricing

from $3.70 / 1,000 book records

Go to Apify Store
Open Library & Gutenberg Book Lookup

Open Library & Gutenberg Book Lookup

Open Library Lookup that returns title, authors, publisher, subjects and cover art. 21 typed fields per book record. Add free full-text links from Project Gutenberg. Export to JSON, CSV or Excel, run it on a schedule, or call it from the Apify API.

Pricing

from $3.70 / 1,000 book records

Rating

0.0

(0)

Developer

angel nguyen

angel nguyen

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 days ago

Last modified

Share

What this Actor does

Project Gutenberg and Open Library in one call: give this Actor a list of ISBNs and you get back clean book records — title, authors, publisher, subjects and cover — with free full-text links attached wherever the book is in the public domain. Neither source needs an account or an API key.

Actor icon

It also runs the other way round. Feed it titles or author names instead of ISBNs and it searches Open Library for matching editions, so a messy list of "book-ish strings" comes back as structured rows you can actually join on.

Key features

  • Three ways in. ISBN-10 or ISBN-13 (hyphens and spaces are stripped), free-text titles, or author names.
  • 21 fields per record, counted from a real run — title, subtitle, authors, both ISBNs, publishers, publish date, first publication year, page count, subjects, languages, cover URL and the Open Library key.
  • Project Gutenberg join. Where a public-domain match exists, the record carries gutenbergId, gutenbergFormats (the actual download links) and gutenbergDownloadCount — a real popularity signal, not an estimate.
  • A strict robots-clean mode. gutenbergOnly skips Open Library entirely and uses only Gutendex, whose robots.txt explicitly allows this.
  • Every row says how it was resolved. queriedBy, query and resolved travel with the record, so an unmatched input is visible rather than silently missing.
  • Deliberately unhurried. Concurrency defaults to 2 and is capped at 5, because this source throttles rather than scaling.

How it works

  1. You supply ISBNs, titles or authors, and choose whether to attach Project Gutenberg matches.
  2. ISBNs are normalised — hyphens and spaces stripped — and resolved against Open Library to exactly one edition each.
  3. Titles and authors go through Open Library search instead, returning up to limit editions per query.
  4. If includeGutenberg is on, each resolved book is looked up in Gutendex for a public-domain match, and any download formats found are attached.
  5. If gutenbergOnly is on, steps 2 and 3 are skipped and Gutendex alone answers the query.
  6. Each result is flattened to one typed row and pushed to the dataset, carrying the query that produced it.

An identifier that resolves to nothing still tells you so: the row records what was queried and that it did not resolve, rather than vanishing from the output.

Input

At least one of isbns, titles or authors must be non-empty.

Input fields

FieldTypeDefaultWhat it does
isbnsarray["9780261103283","9780141439518"] (prefilled)ISBN-10 or ISBN-13. Hyphens and spaces are stripped. The most precise input — resolves to exactly one edition.
titlesarray[]Free-text title search against Open Library.
authorsarray[]Free-text author search against Open Library.
includeGutenbergbooleantrueAlso query Gutendex for a public-domain match and attach download links plus download_count (a real popularity signal). Gutendex is the fully robots-clean source; leaving this on is recommended.
gutenbergOnlybooleanfalseSkip Open Library entirely and use only Gutendex, whose robots.txt explicitly allows this. Open Library's robots.txt disallows /search and /api — see RESPONSIBLE-USE.md. Turning this on removes that flag at the cost of non-public-domain coverage.
limitinteger10Max results per title/author query. Ignored for ISBN lookups, which return one edition each.
languagestring""Optional ISO-639-2 code, e.g. 'eng'. Leave blank for no filter.
maxConcurrencyinteger2Kept low on purpose: a 30-request burst to Open Library measured 2x HTTP 429 and a connection reset, at a 1.76s median. Raising this will get you throttled, not served faster.

Example input

Two real ISBN-13s — 9780261103283 is The Lord of the Rings, 9780553293357 is Foundation — with the Gutenberg join on.

{
"isbns": [
"9780261103283",
"9780553293357"
],
"includeGutenberg": true,
"maxConcurrency": 2
}

Output

One dataset item per resolved book. The record below is a real row from a real run of this Actor, copied unedited.

Example output

{
"source": "openlibrary",
"title": "The hobbit",
"subtitle": "or There and back again",
"authors": [
"J.R.R. Tolkien"
],
"isbn10": [],
"isbn13": [
"9780261103283"
],
"publishers": [
"HarperCollins"
],
"publishDate": "2020",
"firstPublishYear": null,
"numberOfPages": 300,
"subjects": [],
"languages": [
"eng"
],
"coverUrl": "https://covers.openlibrary.org/b/id/149276-L.jpg",
"openLibraryKey": "/works/OL27482W",
"gutenbergId": null,
"gutenbergDownloadCount": null,
"gutenbergFormats": null,
"queriedBy": "isbn",
"query": "9780261103283",
"resolved": true,
"scrapedAt": "2026-08-22T07:33:40.342Z"
}

Output fields

Every field below is taken from that same real record. Values are truncated for width, never invented.

FieldTypeValue from a real run
sourcestringopenlibrary
titlestringThe hobbit
subtitlestringor There and back again
authorsarray["J.R.R. Tolkien"]
isbn10array[]
isbn13array["9780261103283"]
publishersarray["HarperCollins"]
publishDatestring2020
firstPublishYearnullnull
numberOfPagesnumber300
subjectsarray[]
languagesarray["eng"]
coverUrlstringhttps://covers.openlibrary.org/b/id/149276-L.jpg
openLibraryKeystring/works/OL27482W
gutenbergIdnullnull
gutenbergDownloadCountnullnull
gutenbergFormatsnullnull
queriedBystringisbn
querystring9780261103283
resolvedbooleantrue
scrapedAtstring2026-08-22T07:33:40.342Z

The Gutenberg fields are populated only where a public-domain match exists — which is most of the pre-1929 canon and almost none of the modern catalogue. An empty gutenbergId means "no free full text found", not "lookup failed".

Pricing

Pay-per-event. You are charged per book record delivered; platform compute is not billed on top, and an identifier that resolves to nothing is never billed.

EventPriceCharged when
Book record$0.004One resolved book: Open Library metadata plus the Project Gutenberg full-text join where one exists.
Actor start$0.00001Starting a run is charged at the platform minimum of $0.00001 - effectively free. You pay for what the run actually delivers. An identifier we cannot resolve is never billed.

What a run actually costs

Worked from the prices in the table above:

  • A 500-ISBN backlist, resolved once. 500 records x $0.004 = $2.00, plus $0.00001 to start the run.
  • A 20-book weekly refresh. 20 x $0.004 = $0.08 per run, about $0.35 a month.
  • One ISBN. $0.00001 to start plus $0.004 for the record = $0.00401.

Unresolved identifiers cost nothing beyond the run start, so a dirty input list is cheap to discover.

FAQ

Do I need an API key for Open Library or Project Gutenberg?

No. Both are public, keyless sources. The Actor calls Open Library and Gutendex over plain HTTPS with no account and no token.

What is Gutendex?

Gutendex is the public JSON API over the Project Gutenberg catalogue. It is what the Actor queries for public-domain matches and download links, and its robots.txt explicitly allows this.

Why is maxConcurrency capped so low?

Because raising it does not make this faster. A 30-request burst against Open Library was measured returning two HTTP 429s and a connection reset, at a 1.76-second median. The default of 2 is the setting that actually finishes.

What does gutenbergOnly do, and why would I use it?

It skips Open Library entirely and answers from Gutendex alone. Open Library's robots.txt disallows /search and /api; gutenbergOnly removes that consideration completely, at the cost of losing every book that is not public domain.

Can I search by title instead of ISBN?

Yes — put strings in titles or authors. They run as free-text searches and return up to limit editions each. ISBNs remain the precise path: one ISBN resolves to exactly one edition.

Are the cover images included?

The record carries coverUrl, a link to the cover hosted by the source. The image bytes are not copied into your dataset.

Is the download count real?

Yes. gutenbergDownloadCount is Project Gutenberg's own published count for that book, passed through unchanged.

Limits and error handling

  • limit caps results per title or author query at 100; it is ignored for ISBN lookups, which return one edition each.
  • maxConcurrency is capped at 5 and defaults to 2. This is a source-imposed ceiling, not caution: a 30-request burst measured 2 x HTTP 429 plus a connection reset.
  • language takes an ISO-639-2 code such as eng; leave it blank for no filter.
  • An ISBN that matches no edition produces a row marked unresolved rather than disappearing.
  • Books still in copyright will never carry Gutenberg fields — that is the licence, not a lookup failure.

Integrations and API

Everything below works on any Apify account, including the free tier.

Run it from the Apify API

Start a run and wait for the dataset in one call. Replace <YOUR_TOKEN> with your own Apify API token.

curl -X POST "https://api.apify.com/v2/acts/praise-most-high~book-isbn-catalog/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"isbns":["9780261103283","9780553293357"],"includeGutenberg":true,"maxConcurrency":2}'

Use it from JavaScript or Python

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('praise-most-high/book-isbn-catalog').call({"isbns":["9780261103283","9780553293357"],"includeGutenberg":true,"maxConcurrency":2});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Schedules, webhooks and integrations

Run it on a schedule — hourly, daily, or a cron expression — and have the output pushed where you already work. Apify ships first-party integrations for Zapier, Make, n8n, Slack, Google Drive, GitHub and generic webhooks, and any run can fire a webhook on success or failure. The dataset is also readable directly as JSON, CSV, XLSX, XML or RSS from its own URL, so a spreadsheet or a BI tool can point straight at it.

Where the data comes from

Two public, keyless sources:

  • Open Library — the Internet Archive's open bibliographic catalogue. Supplies title, authors, publishers, dates, page counts, subjects, languages and cover URLs.
  • Project Gutenberg, via the Gutendex API — supplies the public-domain full-text match, its download formats, and Project Gutenberg's own download count.

Both are read live over plain HTTPS on every run. No account, no API key, no session cookie, no headless browser and no proxy rotation. Open Library's robots.txt disallows /search and /api, which is why gutenbergOnly exists as a strict mode for users who want to stay entirely inside a source that allows this explicitly.

Unofficial. This Actor is not affiliated with, endorsed by, or sponsored by the Internet Archive, Open Library or Project Gutenberg. Their names are used only to describe the public data sources it reads.

No personal data. Bibliographic metadata about published works only — no borrower records, no reader accounts, no reviews.

Your obligations. Public-domain status is per-work and per-jurisdiction. Project Gutenberg texts are public domain in the United States; that does not automatically hold where you are. Open Library metadata carries its own terms. Check before you republish.

Support and feedback

Found a bug, a wrong field, or a source that changed shape? Open an issue on the Issues tab of this Actor and it goes straight to the maintainer. Feature requests are welcome on the same tab. If a run failed, include the run ID — the log is what makes it fixable.