sosoreads
v0.1.1
Published
Another Node Goodreads wrapper
Downloads
4
Readme
Sosoreads
Another Node Goodreads wrapper
Apparently when Amazon acquired Goodreads they decided to ship their half-built API and never finish it. Thanks, Amazon.
So there are lots of wrappers:
- Goodreads (Ruby) looks like the most popular.
- BetterReads (Python) was my first name idea and looks great. It was built on goodreads2, another Python wrapper.
- A bunch of Node versions: fff-graphql-goodreads, goodreads.js, goodreads-json, goodreads-json-api, Goodreads review JSON export, node-goodreads.
The best Node implementation is goodreads-api-node: it's mostly complete, including OAuth methods. Unfortunately, for the resources where OAuth is possible, it is required. To avoid that, and to provide my own take on the best API, I've created Sosoreads.
Roadmap
- [x] Documentation
- [x] Basic structure
- [x] Unit test framework
- [x] Reviews (v0.1)
- [x] Add to npm
- [ ] Author (v0.2)
- [ ] Book (v0.3)
- [ ] Books (v0.4)
- [ ] BooksByAuthor (v0.5)
- [ ] Review (v0.6)
- [ ] Series (v0.7)
- [ ] Shelves (v0.8)
- [ ] User (v1.0)
- [ ] Write resources (Comments, Shelves, UserBook)
- [ ] OAuth resources (Notifications, UserBook)
General Notes
My goal is to provide a clean interface to the book-related resources. However, I will prioritize performance over "purity". For example, if I were building an API from scratch, I would only return authorIds with a Book; but Sosoreads will also return the additional author information provided by Goodreads.
I will not implement the social resources (friends, notifications, etc.).
- v1 - read-only resources
- v2 - write resources (Books to Shelves (shelves.add_to_shelf, shelves.add_books_to_shelves), Comments, Reviews (reviews, owned_books), Shelves)
- v3 - resources requiring OAuth (Notifications, Reviews (owned_books))
Properties with falsy values ("", 0, false, null, undefined) will not be returned.
All dates follow the ISO_8601 standard.
The Goodreads API's default page size for paged collections is 30 (the exception is shelves are paged by 100). This page size is not configurable in the Goodreads API (the exception is when searching Books by UserId). However, for simplicity, sosoreads allows a custom page size for all paged collections. Be aware that custom page sizes that overlap the Goodreads page size may require multiple Goodreads API calls behind the scenes, affecting performance.
Installation
npm install --save sosoreads
const sosoreads = require('sosoreads');
Initialization
const options = {
"goodreads_developer_key": 'YOUR_GOODREADS_DEVELOPER_KEY',
"oauth_token": "YOUR_OAUTH_TOKEN"
};
const api = sosoreads(options);
Done
Reviews
Example Requests
const options = {
"userId": "4812558",
"paging": {
"count": 30,
"number": 1
},
"searchQuery": "iliad", // optional
"shelf": "to-read", // optional
"sort": { // optional
"field": "title",
"order": "desc"
}
}
api.getReviews(options).then(books => {});
Example Response
{
"reviews": [{
"body": "I'm a fan of the bad book club podcast 372 Pages We'll Never Get Back, and a fan of many of the books they've covered. I built a fan-fiction Choose Your Own Adventure game (372adventure.com). I wrote a 3,212 word review of Trucking through Time, the highest-rated review of Trucking through Time on Goodreads. We've invited friends over for an Eye of Argon reading party.<br /><br />I don't say any of this to brag. I say it so that you can fully understand the following statement: Moon People is the greatest of them all. I didn't think I could love a 1-star book more than Trucking through Time, but I was wrong. So very wrong.",
"book": {
"authors": [{
"id": "2975072",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/user/u_200x266-e183445fd1a1b5cc7075bb1cf7043306.png",
"small": "https://s.gr-assets.com/assets/nophoto/user/u_50x66-632230dc9882b4352d753eedf9396530.png"
},
"name": "Dale M. Courtney",
"ratings": {
"average": 2.77,
"count": 135
},
"role": "author",
"url": "https://www.goodreads.com/author/show/2975072.Dale_M_Courtney"
}],
"descriptions": {
"short": "This Book is based on the turning point for Earth into a new era of space travel and the beginning of the Age of Aquarius.",
"full": "This Book is based on the turning point for Earth into a new era of space travel and the beginning of the Age of Aquarius. The story focuses on one Man by the Name of David Braymer and his adventures from High school teacher to 1st Science Officer on board the Lunar Base 1 Mobile Base Station and his encounters with Alien Life forms through out our universe and the space Battle of all battles David experiences. I hope you enjoy the many adventures of David Braymer and his conquest in space and our journey into the Age of Aquarius"
},
"edition": {
"format": "Mass Market Paperback",
"pageCount": 123,
"publisher": "Penguin Classics",
"year": "2008"
},
"id": "6584471",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
"small": "https://s.gr-assets.com/assets/nophoto/book/50x75-a91bf249278a81aabab721ef782c4a74.png"
},
"isbn": "1436372135",
"isbn13": "9781436372138",
"owned": false,
"ratings": {
"average": 2.63,
"count": 120
},
"reviewCount": 49,
"shelves": [
{
"exclusive": true,
"id": "15377251",
"name": "read"
}, {
"exclusive": false,
"id": "302308344",
"name": "372-pages"
}
],
"title": "Moon People",
"url": "https://www.goodreads.com/book/show/6584471-moon-people"
},
"commentsCount": 0,
"dates": {
"add": "2020-02-16T11:33:07-08:00",
"end": "2020-03-04T14:44:57-08:00",
"start": "2020-02-16T06:03:22-08:00",
"update": "2020-03-04T19:54:53-08:00"
},
"id": "3193280293",
"isSpoiler": false,
"rating": 1,
"readCount": 1,
"recommendedBy": "372 Pages We'll Never Get Back Podcast",
"recommendedFor": "Fans of bad books",
"url": "https://www.goodreads.com/review/show/3193280293",
"votesCount": 0
}
}
Comments
- A review is a many-to-many link between users and books. The entity contains reviews, ratings, shelves, and book and user data.
- The maximum
paging.count
is 200. searchQuery
search matches against title and author fields.sort.field
default isdate_updated
sort.order
default isdesc
- Goodreads never returns more than one author for this resource. To get all authors, use
Book
. - The possible values for
authors.role
are:- author
- translator
descriptions.long
is provided by Goodreads.descriptions.short
will be the first sentence from the long description.popularShelves
will return at most 100 shelves.publicationYear
will be a negative number for books published BC.
Goodreads API endpoints
- reviews.list
To Do
Author
Example Requests
const options = {
"authorId": "2687"
};
api.getAuthor(options).then(author => {});
const options = {
"authorName": "Simmons"
};
api.getAuthor(options).then(author => {});
Example Response
{
"about": "<b>Dan Simmons</b> grew up in various cities and small towns in the Midwest, including Brimfield, Illinois, which was the source of his fictional \"Elm Haven\" in 1991's SUMMER OF NIGHT and 2002's A WINTER HAUNTING.",
"booksCount": 188,
"dates": {
"born": "1948-04-04",
"died": "2024-07-09"
},
"followerCount": 8641,
"gender": "male",
"id": "2687",
"hometown": "Peoria, Illinois",
"images": {
"large": "https://images.gr-assets.com/authors/1427999015p7/2687.jpg",
"medium": "https://images.gr-assets.com/authors/1427999015p5/2687.jpg",
"small": "https://images.gr-assets.com/authors/1427999015p2/2687.jpg"
},
"influences": [{
"id": "7415",
"name": "Harlan Ellison",
"url": "https://www.goodreads.com/author/show/7415.Harlan_Ellison"
}, {
"id": "3389",
"name": "Stephen King",
"url": "https://www.goodreads.com/author/show/3389.Stephen_King"
}],
"name": "Dan Simmons",
"ratings": {
"average": 4.08,
"count": 4184744
},
"url": "https://www.goodreads.com/author/show/2687.Dan_Simmons"
}
Comments
- For requests, if
authorId
is provided,authorName
is ignored. - Calls Goodreads endpoint
book.show
to getratings
.
Goodreads API endpoints
- author.show
- book.show
- search.author
Book
Example Requests
const options = {
"bookId": "117929"
}
api.getBook(options).then(book => {});
const options = {
"isbn": "0140445927"
}
api.getBook(options).then(book => {});
Example Response
{
"authors": [{
"id": "903",
"images": {
"large": "https://images.gr-assets.com/authors/1390672749p7/903.jpg",
"small": "https://images.gr-assets.com/authors/1390672749p2/903.jpg"
},
"name": "Homer",
"ratings": {
"average": 3.81,
"count": 1282996
},
"role": "author",
"url": "https://www.goodreads.com/author/show/903.Homer"
}, {
"id": "1005",
"images": {
"large": "https://images.gr-assets.com/authors/1279895687p5/1005.jpg",
"small": "https://images.gr-assets.com/authors/1279895687p2/1005.jpg"
},
"name": "Robert Fagles",
"ratings": {
"average": 3.89,
"count": 407366
},
"role": "translator",
"url": "https://www.goodreads.com/author/show/1005.Robert_Fagles"
}],
"descriptions": {
"short": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem.",
"full": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem. The verse translation has been hailed by scholars as the new standard, providing an Iliad that delights modern sensibility and aesthetic without sacrificing the grandeur and particular genius of Homer's own style and language. The Iliad is one of the two great epics of Homer, and is typically described as one of the greatest war stories of all time, but to say the Iliad is a war story does not begin to describe the emotional sweep of its action and characters: Achilles, Helen, Hector, and other heroes of Greek myth and history in the tenth and final year of the Greek siege of Troy."
},
"id": "117929",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SY75_.jpg"
},
"isbn": "0140445927",
"isbn13": "9780140445923",
"originalPublicationYear": "-750",
"pageCount": 683,
"popularShelves": [{
"count": 215075,
"name": "to-read"
}, {
"count": 15438,
"name": "currently-reading"
}],
"publisher": "Penguin Classics",
"ratings": {
"average": 3.87,
"count": 346167,
"distribution": {
"five": 115210,
"four": 113155,
"three": 83415,
"two": 24967,
"one": 9420
}
},
"series": [{
"count": 8,
"name": "Epic Cycle",
"positionInSeries": 2
}],
"similarBooks": [{
"author": {
"id": "919",
"name": "Virgil",
"url": "https://www.goodreads.com/author/show/919.Virgil"
},
"id": "12914",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
"small": "https://s.gr-assets.com/assets/nophoto/book/50x75-a91bf249278a81aabab721ef782c4a74.png"
},
"isbn": "0679729526",
"isbn13": "9780679729525",
"pageCount": 442,
"ratings": {
"average": 3.87,
"count": 346167
},
"title": "The Aeneid",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}, {
"author": {
"id": "4699102",
"name": "Unknown",
"url": "https://www.goodreads.com/author/show/4699102.Unknown"
},
"id": "52357",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SY75_.jpg"
},
"isbn": "0393320979",
"isbn13": "9780393320978",
"pageCount": 245,
"ratings": {
"average": 3.87,
"count": 346167
},
"title": "Beowulf",
"url": "https://www.goodreads.com/book/show/52357.Beowulf"
}],
"title": "The Iliad",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}
Comments
- For requests, if
bookId
is provided,isbn
is ignored. - The possible values for
authors.role
:- "author"
- "translator"
description.long
is provided by Goodreads.description.short
will be the first sentence from the long description.pageCount
andpublisher
are obviously dependent on edition; I don't know how Goodreads determines which edition to provide.popularShelves
will return at most 100 shelves.publicationYear
will be a negative number for books published BC.
Goodreads API endpoints
- book.show
- book.show_by_isbn
Books
Example Requests
const options = {
"searchQuery": "iliad",
"paging": { // optional
"count": 30,
"number": 1
},
"sort": { // optional
"field": "title",
"order": "desc"
}
}
api.getBooks(options).then(books => {});
Example Response
{
"books": [{
"authors": [{
"id": "903",
"images": {
"large": "https://images.gr-assets.com/authors/1390672749p7/903.jpg",
"small": "https://images.gr-assets.com/authors/1390672749p2/903.jpg"
},
"name": "Homer",
"ratings": {
"average": 3.81,
"count": 1282996
},
"role": "author",
"url": "https://www.goodreads.com/author/show/903.Homer"
}, {
"id": "1005",
"images": {
"large": "https://images.gr-assets.com/authors/1279895687p5/1005.jpg",
"small": "https://images.gr-assets.com/authors/1279895687p2/1005.jpg"
},
"name": "Robert Fagles",
"ratings": {
"average": 3.89,
"count": 407366
},
"role": "translator",
"url": "https://www.goodreads.com/author/show/1005.Robert_Fagles"
}],
"descriptions": {
"short": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem.",
"full": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem. The verse translation has been hailed by scholars as the new standard, providing an Iliad that delights modern sensibility and aesthetic without sacrificing the grandeur and particular genius of Homer's own style and language. The Iliad is one of the two great epics of Homer, and is typically described as one of the greatest war stories of all time, but to say the Iliad is a war story does not begin to describe the emotional sweep of its action and characters: Achilles, Helen, Hector, and other heroes of Greek myth and history in the tenth and final year of the Greek siege of Troy."
},
"id": "117929",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SY75_.jpg"
},
"isbn": "0140445927",
"isbn13": "9780140445923",
"originalPublicationYear": "-750",
"pageCount": 683,
"popularShelves": [{
"count": 215075,
"name": "to-read"
}, {
"count": 15438,
"name": "currently-reading"
}],
"publisher": "Penguin Classics",
"ratings": {
"average": "3.87",
"count": 346167,
"distribution": {
"five": 115210,
"four": 113155,
"three": 83415,
"two": 24967,
"one": 9420
}
},
"series": [{
"count": 8,
"name": "Epic Cycle",
"positionInSeries": 2
}],
"similarBooks": [{
"author": {
"id": "919",
"name": "Virgil",
"url": "https://www.goodreads.com/author/show/919.Virgil"
},
"id": "12914",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
"small": "https://s.gr-assets.com/assets/nophoto/book/50x75-a91bf249278a81aabab721ef782c4a74.png"
},
"isbn": "0679729526",
"isbn13": "9780679729525",
"pageCount": 442,
"ratings": {
"average": 3.87,
"count": 346167
},
"title": "The Aeneid",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}, {
"author": {
"id": "4699102",
"name": "Unknown",
"url": "https://www.goodreads.com/author/show/4699102.Unknown"
},
"id": "52357",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SY75_.jpg"
},
"isbn": "0393320979",
"isbn13": "9780393320978",
"pageCount": 245,
"ratings": {
"average": 3.87,
"count": 346167
},
"title": "Beowulf",
"url": "https://www.goodreads.com/book/show/52357.Beowulf"
}],
"title": "The Iliad",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}]
}
Comments
searchQuery
search matches against title and author fields.- The possible values for
authors.role
are- "author"
- "translator"
description.long
is provided by Goodreads.description.short
will be the first sentence from the long description.pageCount
andpublisher
are obviously dependent on edition; I don't know how Goodreads determines which edition to provide.popularShelves
will return at most 100 shelves.publicationYear
will be a negative number for books published BC.
Goodreads API endpoints
- search.books
Books by Author
Example Requests
const options = {
"authorId": "903",
"paging": { // optional
"count": 30,
"number": 1
},
"sort": { // optional
"field": "title",
"order": "desc"
}
}
api.getBooks(options).then(books => {});
Example Response
{
"books": [{
"authors": [{
"id": "903",
"images": {
"large": "https://images.gr-assets.com/authors/1390672749p7/903.jpg",
"small": "https://images.gr-assets.com/authors/1390672749p2/903.jpg"
},
"name": "Homer",
"ratings": {
"average": 3.81,
"count": 1282996
},
"role": "author",
"url": "https://www.goodreads.com/author/show/903.Homer"
}, {
"id": "1005",
"images": {
"large": "https://images.gr-assets.com/authors/1279895687p5/1005.jpg",
"small": "https://images.gr-assets.com/authors/1279895687p2/1005.jpg"
},
"name": "Robert Fagles",
"ratings": {
"average": 3.89,
"count": 407366
},
"role": "translator",
"url": "https://www.goodreads.com/author/show/1005.Robert_Fagles"
}],
"descriptions": {
"short": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem.",
"full": "This groundbreaking English version by Robert Fagles is the most important recent translation of Homer's great epic poem. The verse translation has been hailed by scholars as the new standard, providing an Iliad that delights modern sensibility and aesthetic without sacrificing the grandeur and particular genius of Homer's own style and language. The Iliad is one of the two great epics of Homer, and is typically described as one of the greatest war stories of all time, but to say the Iliad is a war story does not begin to describe the emotional sweep of its action and characters: Achilles, Helen, Hector, and other heroes of Greek myth and history in the tenth and final year of the Greek siege of Troy."
},
"id": "117929",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1482528464l/117929._SY75_.jpg"
},
"isbn": "0140445927",
"isbn13": "9780140445923",
"originalPublicationYear": "-750",
"pageCount": 683,
"popularShelves": [{
"count": 215075,
"name": "to-read"
}, {
"count": 15438,
"name": "currently-reading"
}],
"publisher": "Penguin Classics",
"ratings": {
"average": 3.87,
"count": 346167,
"distribution": {
"five": 115210,
"four": 113155,
"three": 83415,
"two": 24967,
"one": 9420
}
},
"series": [{
"count": 8,
"name": "Epic Cycle",
"positionInSeries": 2
}],
"similarBooks": [{
"author": {
"id": "919",
"name": "Virgil",
"url": "https://www.goodreads.com/author/show/919.Virgil"
},
"id": "12914",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
"small": "https://s.gr-assets.com/assets/nophoto/book/50x75-a91bf249278a81aabab721ef782c4a74.png"
},
"isbn": "0679729526",
"isbn13": "9780679729525",
"pageCount": 442,
"ratings": {
"average": "3.87",
"count": 346167
},
"title": "The Aeneid",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}, {
"author": {
"id": "4699102",
"name": "Unknown",
"url": "https://www.goodreads.com/author/show/4699102.Unknown"
},
"id": "52357",
"images": {
"large": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SX98_.jpg",
"small": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1327878125l/52357._SY75_.jpg"
},
"isbn": "0393320979",
"isbn13": "9780393320978",
"pageCount": 245,
"ratings": {
"average": 3.87,
"count": 346167
},
"title": "Beowulf",
"url": "https://www.goodreads.com/book/show/52357.Beowulf"
}],
"title": "The Iliad",
"url": "https://www.goodreads.com/book/show/117929.The_Iliad"
}]
}
Comments
- The possible values for
authors.role
are- "author"
- "translator"
description.long
is provided by Goodreads.description.short
will be the first sentence from the long description.pageCount
andpublisher
are obviously dependent on edition; I don't know how Goodreads determines which edition to provide.popularShelves
will return at most 100 shelves.publicationYear
will be a negative number for books published BC.
Goodreads API endpoints
- author.books
Notifications
Example Requests
const options = {
"paging": {
"count": 30,
"number": 1
}
}
api.getNotifications(options).then(notifications => {});
Example Response
{
"notifications": [
{
"actors": [
{
"id": "119659909",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/user/u_111x148-9394ebedbb3c6c218f64be9549657029.png",
"small": "https://s.gr-assets.com/assets/nophoto/user/u_50x66-632230dc9882b4352d753eedf9396530.png"
},
"location": "Hoboken, NJ",
"names": {
"display": "Castlearrgh",
"full": "Castlearrgh"
},
"url": "https://www.goodreads.com/user/show/119659909-castlearrgh"
}
],
"body": {
"html": "<a href=\"/user/show/119659909-castlearrgh\">Castlearrgh<\/a> liked <a href=\"https://www.goodreads.com/review/show/3193280293?type=review#rating_316913376\">your review of Moon People<\/a>",
"text": "Castlearrgh liked your review of Moon People"
},
"resource": {
"id": "3193280293",
"type": "Review"
},
"timestamp": "2020-10-15T21:38:47-07:00",
"type": "Rating",
"url": "https://www.goodreads.com/review/show/3193280293?type=review#rating_316913376"
}
]
}
Comments
- Requires OAuth
- Viewing notifications marks them as "viewed".
type
is the type of action the actor(s) made. Known values:- Comment
- Rating
- ReadingNotesCollectionData
- UserFollowing
resource.type
is the type of action the original user made. Known values:- ReadingNotesCollectionData
- ReadStatus
- Review
- UserFollowing
Goodreads API endpoints
- notifications
Review
Example Requests
const options = {
"reviewId": "2kYIBVxcqaN4mdfclzwVQ"
}
api.getReview(options).then(review => {});
const options = {
"userId": "4812558",
"bookId": "50"
}
api.getReview(options).then(review => {});
Example Response
{
"book": {
"authors": [{
"id": "2975072",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/user/u_200x266-e183445fd1a1b5cc7075bb1cf7043306.png",
"small": "https://s.gr-assets.com/assets/nophoto/user/u_50x66-632230dc9882b4352d753eedf9396530.png"
},
"name": "Dale M. Courtney",
"ratings": {
"average": 2.77,
"count": 135
},
"role": "author",
"url": "https://www.goodreads.com/author/show/2975072.Dale_M_Courtney"
}],
"descriptions": {
"short": "This Book is based on the turning point for Earth into a new era of space travel and the beginning of the Age of Aquarius.",
"full": "This Book is based on the turning point for Earth into a new era of space travel and the beginning of the Age of Aquarius. The story focuses on one Man by the Name of David Braymer and his adventures from High school teacher to 1st Science Officer on board the Lunar Base 1 Mobile Base Station and his encounters with Alien Life forms through out our universe and the space Battle of all battles David experiences. I hope you enjoy the many adventures of David Braymer and his conquest in space and our journey into the Age of Aquarius"
},
"id": "6584471",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
"small": "https://s.gr-assets.com/assets/nophoto/book/50x75-a91bf249278a81aabab721ef782c4a74.png"
},
"isbn": "1436372135",
"isbn13": "9781436372138",
"originalPublicationYear": "2008",
"pageCount": 123,
"publisher": "Penguin Classics",
"ratings": {
"average": 2.63,
"count": 120
},
"reviewCount": 49,
"title": "Moon People",
"url": "https://www.goodreads.com/book/show/6584471-moon-people"
},
"owned": false,
"review": {
"body": "I'm a fan of the bad book club podcast 372 Pages We'll Never Get Back, and a fan of many of the books they've covered. I built a fan-fiction Choose Your Own Adventure game (372adventure.com). I wrote a 3,212 word review of Trucking through Time, the highest-rated review of Trucking through Time on Goodreads. We've invited friends over for an Eye of Argon reading party.<br /><br />I don't say any of this to brag. I say it so that you can fully understand the following statement: Moon People is the greatest of them all. I didn't think I could love a 1-star book more than Trucking through Time, but I was wrong. So very wrong.<br /><br />It's like Dale M. Courtney studied me secretly for years, learning all about me, and then wrote Moon People solely to make me happy.<br /><br />The main quirk is that DMC must have written the book with text to speech software. That's the only explanation for the lack of commas and quotation marks, and all the homophones. But it would take me far more than 80 pages to catalog everything I like about Moon People, because every sentence is bad in an amazing new way. You really have to read it yourself. Here's just a taste:<br /><br />The main character David talking to the spaceship admiral: <br /><br /> By the way did you realize that Monday was Halloween. Yes sir, I know, it does bother me a little bit. You have until then to change your mind. You are going to have to be here a good 24 hours earlier for launch preparations and a quick health check up. Then after that the only thing you are going to see is the stars. Don't worry I'll be there right along side of you? That's my flight too. Great. The truth about it is I am a little scared of that shuttle launch to the base station especially on Halloween. But I think I will be all right after that. Good Captain Braymer because you and I are going on one hell of a ride Monday morning, trick or treat. I will show you wonders you always dreamed about. That's pretty cool sir. I can't wait.<br /><br />Romance:<br /><br /> She leaned in toward David and they kissed passionately for about a minute and then stopped.<br /><br />First contact with alien life:<br /><br /> If you like asparagus then I bet you'll like to try some of these. We call this a baked potato. We stir it up into a soft pudding and then we add butter and salt. Potatoes also grow well in space. I hope you will like it. Captain Tudmoke replied, I believe I will try it. MMM that's good. We have something like this on our planet its called stemage.<br /><br />The Burj Khalifa, the Mona Lisa, the crack cocaine of bad books.",
"commentsCount": 0,
"dates": {
"add": "2020-02-16T11:33:07-08:00",
"end": "2020-03-04",
"start": "2020-02-16",
"update": "2020-03-04T19:54:53-08:00"
},
"id": "3193280293",
"isSpoiler": false,
"rating": 1,
"readCount": 1,
"recommendedBy": "372 Pages We'll Never Get Back Podcast",
"recommendedFor": "Fans of bad books",
"url": "https://www.goodreads.com/review/show/3193280293",
"votes": "0"
},
"shelves": [
{
"exclusive": true,
"id": "15377251",
"name": "read"
}, {
"exclusive": false,
"id": "302308344",
"name": "372-pages"
}
],
"statuses": [
{
"commentsCount": 0,
"id": "3444255000",
"statuses": {
"current": "read",
"previous": "currently-reading"
},
"ratingsCount": 0,
"timestamp": "2020-03-04T19:26:52-08:00"
},
{
"commentsCount": 0,
"id": "3410671962",
"statuses": {
"current": "currently-reading"
},
"ratingsCount": 0,
"timestamp": "2020-02-16T11:33:08-08:00"
}
],
"user": {
"id": "4812558",
"images": {
"large": "https://images.gr-assets.com/users/1529893704p3/4812558.jpg",
"small": "https://images.gr-assets.com/users/1529893704p2/4812558.jpg"
},
"location": "Mobile, AL",
"names": {
"display": "Brian",
"full": "Brian Koser"
},
"url": "https://www.goodreads.com/user/show/4812558-brian-koser"
}
}
Comments
- A review is a many-to-many link between users and books. The entity contains reviews, ratings, shelves, and book and user data.
- For requests, if
reviewId
is provided,userId
andbookId
are ignored. - Will require registered app and OAuth after adding
owned_books
data.
Goodreads API endpoints
- owned_books - will add in v3
- review.show
- review.show_by_user_and_book
Series
Example Requests
const options = {
"authorId": "7963"
}
api.getSeries(options).then(series => {});
Example Response
{
"author": {
"id": "7963",
"name": "P.G. Wodehouse"
},
"series": [{
"bestBook": {
"id": "1094403",
"title": "The Man With Two Left Feet and Other Stories",
"image": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1348936569l/1094403._SX98_.jpg",
"published": "1917"
},
"bookCount": "16",
"description": "P.G. Wodehouse's series of comic novels featuring young British dilettante Bertram \"Bertie\" Wooster, and his wry valet Jeeves, who is often the cause of his salvation from increasingly entangled social situations.",
"id": "52643",
"title": "Jeeves"
}, {
"bestBook": {
"id": "13707720",
"title": "Leave it to Psmith",
"image": "https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1342025763l/13707720._SX98_.jpg",
"published": "1923"
},
"bookCount": "12",
"description": "P.G. Wodehouse's stories set at Blandings Castle.",
"id": "60684",
"title": "Blandings Castle"
}]
}
Comments
- Goodreads makes you retrieve a single series by some weird combination of an ID (not the series ID provided in the book resource) and slug; I don't see the point in implementing that since I'm not sure how to get that combination ID. To get a single series by
bookId
orisbn
, usegetBook()
. - I believe
bestBook
is the highest rated on Goodreads in that series.
Goodreads API endpoints
- series.list
Shelves
Example Requests
const options = {
"userId": "4812558",
"paging": { // optional
"count": 100,
"number": 1
}
}
api.getShelves(options).then(shelves => {});
Example Response
{
"start": 1,
"end": 100,
"total": 183,
"shelves": [
{
"count": 1220,
"featured": true,
"exclusive": true,
"id": "15377251",
"name": "read"
}, {
"count": 93,
"featured": false,
"exclusive": false,
"id": "350589097",
"name": "100-books-2020"
}
]
}
Comments
- Creating and editing shelves will be added in v2
Goodreads API endpoints
- shelves.list
- user_shelves
User
Example Requests
const options = {
"userId": "4812558"
}
api.getUser(options).then(user => {});
Example Response
{
"bookCount": 2228,
"dates": {
"lastActive": "2020-07",
"join": "2011-01"
},
"favoriteAuthors": [{
"id": "8842",
"name": "Susanna Clarke"
}],
"favorites": "Science-fiction, fantasy, Christian, the classics, quirky non-fiction, history, mystery...",
"id": "4812558",
"images": {
"large": "https://images.gr-assets.com/users/1529893704p3/4812558.jpg",
"small": "https://images.gr-assets.com/users/1529893704p2/4812558.jpg"
},
"interests": "Reading, web programming, modern board games",
"location": "Mobile, AL",
"name": "Brian Koser",
"recentUpdates": [{
"action": "wants to read",
"bookId": "200138",
"timestamp": "2020-07-22T18:13:24-07:00",
"type": "readstatus",
"url": "https://www.goodreads.com/read_statuses/3763771994"
}, {
"excerpt": "Emoji Bible > LolCats Bible <a target=\"_blank\" href=\"https://en.m.wikipedia.org/wiki/LOLCat_Bible_Translation_Project\" rel=\"nofollow\">https://en.m.wikipedia.org/wiki/LOLCa...</a>",
"location": "Melissa's review",
"timestamp": "2020-07-22T18:13:24-07:00",
"type": "comment",
"url": "https://www.goodreads.com/review/show/3443441422"
}, {
"book": {
"authors": [{
"id": "4788285",
"name": "Tara Gilesbie",
"ratings": {
"average": 3.88,
"count": 1275
},
"role": "author",
"images": {
"large": "https://s.gr-assets.com/assets/nophoto/user/f_200x266-3061b784cc8e7f021c6430c9aba94587.png",
"small": "https://s.gr-assets.com/assets/nophoto/user/f_50x66-6a03a5c12233c941481992b82eea8d23.png"
},
"url": "https://www.goodreads.com/author/show/4788285.Tara_Gilesbie"
}],
"id": "11099295",
"title": "My Immortal",
"url": "https://www.goodreads.com/book/show/11099295-my-immortal"
},
"excerpt": "The newest \"worst thing I've ever read\". I mostly enjoyed reading it for the podcast, but eventually it got tiresome.<br/><br/>Some of the mistakes seem too good for it not to be a hoax:<br/><br/>- Tom Bombodil<br/>- We hugged each udder happily.<br/>- “Yah, siriusly [...]” Serious said deviantly.<br/><br/>If it's not a hoax, I guess some<a href=\"https://www.goodreads.com/review/show/3411248043\">more...</a>",
"rating": 1,
"timestamp": "2020-07-19T20:51:24-07:00",
"type": "review",
"url": "https://www.goodreads.com/review/show/3411248043"
}],
"rss": {
"reviews": "https://www.goodreads.com/review/list_rss/4812558?key=39eMNtqSb_HWJQpihlEiCX178ZHpyQDxjiWtnFFtNeWZMUSK&shelf=%23ALL%23",
"updates": "https://www.goodreads.com/user/updates_rss/4812558?key=39eMNtqSb_HWJQpihlEiCX178ZHpyQDxjiWtnFFtNeWZMUSK"
},
"shelves": [{
"count": 1197,
"featured": true,
"exclusive": true,
"id": "15377251",
"name": "read"
}, {
"count": 12,
"featured": false,
"exclusive": false,
"id": "302308344",
"name": "372-pages"
}],
"urls": {
"goodreads": "https://www.goodreads.com/user/show/4812558-brian-koser",
"personal": "http://koser.us"
}
}
Comments
bookCount
is the number of books shelvedshelves.exclusive
allows you to have one set ofrecentUpdates.type
possible values:- comment
location
- review
book
rating
field with value 1-5
- readstatus
action
bookId
- lots of book information is provided (some not available from any other endpoint), but also much is missing, so we will just returnbookId
- comment
Goodreads API endpoints
- user.show
Not planning to implement
- auth
- author_following
- events
- fanship
- followers
- friend
- friends
- group
- list (not sure what Listopia is, and this resource requires "extra permission" to use)
- quotes (only functionality is creating quotes)
- read_statuses
- Not currently useful, because the only way to get a Read Status ID is from User, which also returns all the Read Status data.
- recommendations (user-to-user recommendations, only functionality is retrieving individual recommendation)
- review.recent_reviews (reviews from all users)
- topic
- user_status
- user_status.show takes a user_status ID that I can't find in any other resource
- user_status.index is a stream of all updates of every site user
- work