Gutenberg APIgutenberg.org ↗
Search the Project Gutenberg catalog of public domain eBooks by author, title, or subject. Returns title, authors, language, audio availability, and eText number.
What is the Gutenberg API?
The Project Gutenberg API exposes one endpoint, search_books, that queries the full Gutenberg catalog of over 70,000 public domain eBooks. A single call returns up to 100 results per page, each including the eText number, title, author list with roles, language, and whether an audio version exists. Searches accept partial matches on author, title, and subject, and can be combined.
curl -X GET 'https://api.parse.bot/scraper/71cc784f-ad40-4cb7-b84f-af798e166a55/search_books?author=Shakespeare' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace gutenberg-org-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Project Gutenberg SDK — search the free eBook catalog."""
from parse_apis.gutenberg_org_api import Gutenberg, InputFormatInvalid
client = Gutenberg()
# Search by author, cap total items to 5.
for book in client.books.search(author="Shakespeare", limit=5):
print(book.title, "|", ", ".join(book.authors), "|", book.language)
# Drill-down: find the first tragedy-related book by title.
book = client.books.search(title="hamlet", subject="tragedy", limit=1).first()
if book is not None:
print(f"Found: {book.title} (eText #{book.etext_no}, audio={book.has_audio})")
print(f" URL: {book.url}")
# Demonstrate error handling for invalid input.
try:
client.books.search(title="x", limit=1).first()
except InputFormatInvalid as e:
print(f"Invalid input: {e.message}")
print("exercised: books.search")
Search books in the Project Gutenberg catalog by author name, title, and/or subject. At least one search term must be provided. Returns paginated results with up to 100 books per page. Results include the eText number, title, authors with roles, language, audio availability, and a link to the book page.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination. Each page returns up to 100 results. |
| title | string | Book title to search for (partial match). At least one of author, title, or subject must be provided. |
| author | string | Author name to search for (partial match). At least one of author, title, or subject must be provided. |
| subject | string | Subject to search for (partial match). At least one of author, title, or subject must be provided. |
{
"type": "object",
"fields": {
"page": "Current page number.",
"books": "Array of book results, each containing etext_no, title, authors, language, has_audio, and url.",
"total": "Total number of matching books across all pages."
},
"sample": {
"data": {
"page": 1,
"books": [
{
"url": "https://www.gutenberg.org/ebooks/56851",
"title": "Shakspeare's Mental Photographs",
"authors": [
"Anonymous [Compiler]",
"Shakespeare, William, 1564-1616"
],
"etext_no": "56851",
"language": "English",
"has_audio": false
}
],
"total": 350
},
"status": "success"
}
}About the Gutenberg API
What the API Returns
The search_books endpoint searches the Project Gutenberg catalog and returns a paginated result set. Each page holds up to 100 books, and the total field tells you how many matching records exist across all pages. Individual book objects include etext_no (the canonical Gutenberg identifier), title, language, a boolean has_audio flag, and a url pointing to the book's Gutenberg page. The authors field is an array, so multi-author works and entries with editorial roles are represented correctly.
Search Parameters
At least one of author, title, or subject must be supplied — all three accept partial string matches, so searching author=dickens returns works by Charles Dickens without requiring an exact full name. Parameters can be combined: passing both author=tolstoy and subject=war narrows results to Tolstoy's war-related titles. The page integer steps through paginated results when total exceeds 100.
Coverage and Scope
The catalog covers public domain works — predominantly classic literature, historical texts, and reference works whose copyright has expired. Language coverage is multilingual; the language field on each result identifies the primary language of that edition. The has_audio field indicates when a LibriVox or similar audio recording is associated with the Gutenberg record, which is useful for filtering to audiobook-compatible titles without a separate lookup.
The Gutenberg API is a managed, monitored endpoint for gutenberg.org — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when gutenberg.org changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official gutenberg.org API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a reading list app that lets users browse public domain books by subject and language.
- Populate an audiobook index by filtering results where
has_audiois true. - Create an author bibliography page by querying
search_bookswith a specific author name. - Feed a recommendation engine with metadata (etext_no, title, subject) from the Gutenberg catalog.
- Check multilingual availability of a classic text by combining title and language filters.
- Generate citation data for academic tools using eText numbers and author roles from the
authorsarray. - Build a subject-based discovery tool that groups public domain titles by topic across multiple pages.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Project Gutenberg have an official developer API?+
What does the `authors` field contain, and how does it handle edited or translated works?+
authors field is an array of objects, so a translated work can list both the original author and the translator, each with their respective roles. This means you can distinguish primary authors from editors and translators without additional processing.Does the API return the full text or download links for each book?+
Can I filter results by language directly in the search query?+
author, title, and subject inputs drive search, and the language field appears in each result for post-retrieval filtering. You can fork this API on Parse and revise it to add a language filter parameter to narrow results server-side.