Open Library API: Search books
Finds Open Library books by search words, optionally narrowed by author and subject, sorted by relevance or publication age. Returns work-level results; free_online means at least one edition is marked public or borrowable, not that a loan is available now.
Unofficial. Not affiliated with or endorsed by Open Library.
Inputs
Values from the run on Oct 23, 2026, shown under Output.
- Sort optional
sort Order results by relevance or publication age, for example newest.
relevance (default)
One of
relevance,newest,oldest.- Query, required
query Words to search for, for example Dune.
Dune
- Author optional
author Narrow results to an author, for example Frank Herbert.
Frank Herbert
Default
.- Subject optional
subject Narrow results to a subject, for example gardening.
(default)
- Max Results optional
max_results Maximum number of books to return, for example 10.
3
Whole number from 1 to 100. Default
10.
Input as JSON
{ "query": "Dune", "author": "Frank Herbert", "max_results": 3}Output
{ "books": [ { "isbns": [ "9780340839935", "9782266320481", "9788497596824" ], "title": "Dune", "authors": [ "Frank Herbert" ], "work_key": "/works/OL893414W" , "languages": [ "Hebrew", "Dutch", "Romanian" ], "free_online": true, "edition_count": 155, "cover_image_url": "https://covers.openlibrary.org/b/id/11481354-L.jpg" , "open_library_url": "https://openlibrary.org/works/OL893414W" , "first_published_year": 1965 }, { "isbns": [ "8418037679", "9788466372015", "8373017259" ], "title": "Dune Messiah", "authors": [ "Frank Herbert" ], "work_key": "/works/OL893461W" , "languages": [ "Spanish", "Polish", "Dutch" ], "free_online": true, "edition_count": 101, "cover_image_url": "https://covers.openlibrary.org/b/id/980253-L.jpg" , "open_library_url": "https://openlibrary.org/works/OL893461W" , "first_published_year": 1969 }, { "isbns": [ "1427202915", "9789759971342", "9780425071793" ], "title": "Children of Dune", "authors": [ "Frank Herbert" ], "work_key": "/works/OL893516W" , "languages": [ "Dutch", "Chinese", "Portuguese" ], "free_online": true, "edition_count": 77, "cover_image_url": "https://covers.openlibrary.org/b/id/6976407-L.jpg" , "open_library_url": "https://openlibrary.org/works/OL893516W" , "first_published_year": 1976 } ]}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"openlibrary.org/search_books","input":{"query":"Dune","author":"Frank Herbert","max_results":3}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "openlibrary.org/search_books" , "input": { "query": "Dune", "author": "Frank Herbert", "max_results": 3 }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "openlibrary.org/search_books" , "input": { "query": "Dune", "author": "Frank Herbert", "max_results": 3 } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run openlibrary.org/search_books# with {"query":"Dune","author":"Frank Herbert","max_results":3}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "query" ], "properties": { "sort": { "enum": [ "relevance", "newest", "oldest" ], "type": "string", "default": "relevance", "examples": [ "newest" ], "description": "Order results by relevance or publication age, for example newest." }, "query": { "type": "string", "examples": [ "Dune" ], "minLength": 1, "description": "Words to search for, for example Dune." }, "author": { "type": "string", "default": "", "examples": [ "Frank Herbert" ], "description": "Narrow results to an author, for example Frank Herbert." }, "subject": { "type": "string", "default": "", "examples": [ "gardening" ], "description": "Narrow results to a subject, for example gardening." }, "max_results": { "type": "integer", "default": 10, "maximum": 100, "minimum": 1, "examples": [ 10 ], "description": "Maximum number of books to return, for example 10." } }}Output schema
{ "type": "object", "required": [ "books" ], "properties": { "books": { "type": "array", "items": { "type": "object", "required": [ "title", "authors", "first_published_year", "edition_count", "isbns", "languages", "cover_image_url", "free_online", "open_library_url", "work_key" ], "properties": { "isbns": { "type": "array", "items": { "type": "string" }, "maxItems": 5, "description": "Up to five ISBNs for editions of the work." }, "title": { "type": "string", "description": "Book title." }, "authors": { "type": "array", "items": { "type": "string" }, "description": "Authors of the work." }, "work_key": { "type": "string", "description": "Open Library work key." }, "languages": { "type": "array", "items": { "type": "string" }, "description": "Languages of the work as names." }, "free_online": { "type": "boolean", "description": "Whether any edition is marked public or borrowable for online reading." }, "edition_count": { "type": [ "integer", "null" ], "description": "Number of editions indexed for the work." }, "cover_image_url": { "type": [ "string", "null" ], "description": "Cover image link, if available." }, "open_library_url": { "type": "string", "description": "Open Library work page." }, "first_published_year": { "type": [ "integer", "null" ], "description": "First year of publication, if known." } }, "additionalProperties": false }, "description": "Matching books." } }, "additionalProperties": false}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
openlibrary.org/search_books- Returns
- title, authors, first publication year, edition count, ISBNs, languages, cover image, free online flag, Open Library URL
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method openlibrary.org/search_books with the inputs above.
Ask your agent
- Find books matching the words dune by frank herbert, sorted newest first
- Show me public domain books about gardening, 20 results
- Search Open Library for science fiction from the 1960s oldest first
- List free online editions of books on cooking by Julia Child
- Look up Dune and related titles, relevance order, max 5 results
See more
All Open Library methodsFinds an Open Library author by name, link or key and lists their works with first publication year, edition count, cover and an author profile.
openlibrary.org/list_author_booksGets a book's catalog details from Open Library by its title, with an optional author or ISBN to identify the right book. Reading availability reflects listed editions; details may be missing when the catalog has none.
openlibrary.org/get_bookSearches Google Books by words, author, subject or ISBN, with language, free-ebook and newest-first options. Ratings counts are not shown by the public book feed; newest sorts the available matches by publication date.
books.google.com/search_booksFinds free public-domain Project Gutenberg books by title, author or topic, with authors, languages, subjects, recent downloads, and reading and download links. Public-domain status is based on the United States.
gutenberg.org/search_free_booksSearches Library of Congress digital collections by keywords, material format and date range, in Library search relevance order. Rights notes may be unavailable for some records.
loc.gov/search_collectionsFinds ebook and audiobook editions a public library owns on OverDrive, with copies, holds and estimated wait when unavailable.
overdrive.com/check_library_availabilitySearches public Bluesky posts for words, optionally ordered by latest or top and filtered by date, author or language. Search indexing may lag behind new posts.
bsky.app/search_postsSearches OpenAlex scholarly works by topic, with optional institution, publication-year and open-access filters, ranked by relevance, citations or newest date.
openalex.org/search_papers