Literal API

At Literal, we looove APIs and we do our best to automate everything tech. Our platform runs on GraphQL, which makes it very easy and convenient to share access to the Literal APIs with the community.

Below is a list of our a few handpicked queries and mutations which will allow everyone to get access to their shelves and library. Automation is awesome, isn’t it?

Note: If you cannot find exactly what you’re looking for here, please reach out to us at [email protected] and we’ll try our best to make your use-case possible. You can also join our DEV club to connect with other developers.


API Endpoint

All requests can be sent via POST method at the following address:

https://literal.club/graphql/

Login

Use this mutation to receive an access token, and some of your profile information.

mutation login($email: String!, $password: String!) {
  login(email: $email, password: $password) {
    token
    email
    languages
    profile {
      id
      handle
      name
      bio
      image
    }
  }
}

The access token can be used as an Authorization header for queries or mutations that require it. An access token is valid for 6 months.

Example Authorization header:

Authorization: Bearer c29tZSBqd3QgY29udGVudA==

Your reading states

Get your Literal reading states, together with the book data.

Note: requires authentication (see Login section)

query myReadingStates {
  myReadingStates {
    ...ReadingStateParts   # find fragments below
    book {
      ...BookParts   # find fragments below
    }
  }
}

Update reading state

Update the reading state of a book

mutation updateReadingState(
  $bookId: String!
  $readingStatus: ReadingStatus!   # find fragments below
) {
  updateReadingState(
    bookId: $bookId
    readingStatus: $readingStatus
  ) {
    ...ReadingStateParts   # find fragments below
    book {
      ...BookParts   # find fragments below
    }
  }
}

Your library

Returns all books associated to a profile through readingStates or shelves

query myBooks {
  myBooks {
    ...BookParts   # find fragments below
  }
}

Get highlights

Returns a list of highlights associated with your profile handle and a bookId.

query momentsByHandleAndBookId($bookId: String!, $handle: String) {
  momentsByHandleAndBookId(bookId: $bookId, handle: $handle) {
    ...MomentParts   # find fragments below
    profile {
      ...ProfileParts   # find fragments below
    }
  }
}

Create and update reviews

Create or update a review, associated with a specific bookId.

mutation createReview(
  $bookId: String!
  $text: String
  $spoiler: Boolean!
  $rating: Float!
  $tags: [String!]
) {
  createReview(bookId: $bookId, text: $text, spoiler: $spoiler, rating: $rating, tags: $tags) {
    ...ReviewParts # find fragments below
  }
}

mutation updateReview($id: String!, $text: String, $spoiler: Boolean!, $rating: Float!, $tags: [String!]) {
  updateReview(id: $id, text: $text, spoiler: $spoiler, rating: $rating, tags: $tags) {
    ...ReviewParts # find fragments below
  }
}

Create highlights

Create a highlight, associated with a specific bookId.

mutation createMoment($note: String, $quote: String, $spoiler: Boolean, $bookId: String!, $where: String) {
  createMoment(note: $note, quote: $quote, spoiler: $spoiler, bookId: $bookId, where: $where) {
    ...MomentParts   # find fragments below
  }
}

Get shelf

Returns a shelf by its slug.

query getShelfBySlug($shelfSlug: String!) {
  shelf(where: { slug: $shelfSlug }) {
    ...ShelfFull   # find fragments below
  }
}

Get shelves by profile

Load a list of shelves via profileId.

query getShelvesByProfileId($profileId: String!, $limit: Int!, $offset: Int!) {
  getShelvesByProfileId(profileId: $profileId, limit: $limit, offset: $offset) {
    ...ShelfParts
    books(take: 3) {
      ...BookParts
    }
  }
}

Get books by reading state

Load a paginated list of books by reading status and profile id

query booksByReadingStateAndProfile(
  $limit: Int!
  $offset: Int!
  $readingStatus: ReadingStatus!   # find fragments below
  $profileId: String!
) {
  booksByReadingStateAndProfile(
    limit: $limit
    offset: $offset
    readingStatus: $readingStatus
    profileId: $profileId
  ) {
    ...BookParts   # find fragments below
  }
}

Get profile by handle

Load profile info by handle

query getProfileParts($handle: String!) {
  profile(where: { handle: $handle }) {
    ...ProfileParts   # find fragments below
  }
}

Get book by ISBN

query GetBookByIsbn($isbn13: String!) {
  book(where: {isbn13: $isbn13}) {
    ...BookParts   # find fragments below
  }
}

Get read dates

query getReadDates($bookId: String!, $profileId: String!) {
  getReadDates(bookId: $bookId, profileId: $profileId) {
    ...ReadDateParts   # find fragments below
  }
}

Data fragments

With GraphQL you can define reusable schema fragments, which you can simply refer to in many other queries or mutations.

fragment BookParts on Book {
  id
  slug
  title
  subtitle
  description
  isbn10
  isbn13
  language
  pageCount
  publishedDate
  publisher
  cover
  authors {
    id
    name
  }
  gradientColors
}

fragment MomentParts on Moment {
  id
  note
  noteJson
  quote
  quoteJson
  where
  spoiler
  profileId
  bookId
  createdAt
}

fragment ReviewParts on Review {
  id
  rating
  spoiler
  text
  createdAt
  updatedAt
  tags
}

fragment ShelfFull on Shelf {
  ...ShelfParts
  owner {
    ...ProfileParts
  }
  books {
    ...BookParts
  }
}

fragment ShelfParts on Shelf {
  id
  slug
  title
  description
  profileId
}

fragment ReadingStateParts on ReadingState {
  id
  status
  bookId
  profileId
  createdAt
}

fragment ProfileParts on Profile {
  id
  handle
  name
  bio
  image
  invitedByProfileId
}

enum ReadingStatus {
  WANTS_TO_READ
  IS_READING
  FINISHED
  DROPPED
  NONE
}

fragment ReadDateParts on ReadDate {
  id
  started
  finished
  followingStatus
  updatedAt
  createdAt
}

Further reading