MENU navbar-image

Introduction

The API documentation for Bookshelves to use endpoints with another app.

This documentation aims to provide all the information you need to work with our API.

Base URL

https://bookshelves.ink

Authenticating requests

This API is authenticated by sending an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your token by visiting your dashboard and clicking Generate API token.

Laravel Sanctum

TODO
https://bookshelves.ink/sanctum/csrf-cookie

Application

GET Enums.

Route name: api.enums

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/enums" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/enums"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/enums',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4999
vary: Origin
 

{
    "data": {
        "authorRoles": {
            "aut": "Author"
        },
        "bookFormats": {
            "pdf": "PDF",
            "cbr": "cbr",
            "cbz": "CBZ",
            "epub": "EPUB"
        },
        "bookTypes": {
            "audio": "Audio",
            "comic": "Comic",
            "essay": "Essay",
            "handbook": "Handbook",
            "novel": "Novel"
        },
        "countSizes": {
            "xl": "xl",
            "lg": "lg",
            "md": "md",
            "sm": "sm",
            "xs": "xs"
        },
        "entities": {
            "book": "book",
            "author": "author",
            "serie": "serie",
            "entity": "entity",
            "feed": "feed"
        },
        "genders": {
            "unknown": "Unknown",
            "woman": "Woman",
            "nonbinary": "Non binary",
            "genderfluid": "Genderfluid",
            "agender": "Agender",
            "man": "Man"
        },
        "postStatus": {
            "draft": "Draft",
            "scheduled": "Scheduled",
            "published": "Published"
        },
        "roles": {
            "super_admin": "Super admin",
            "admin": "Admin",
            "publisher": "publisher",
            "user": "User"
        },
        "submissionsReasons": {
            "idea": "Idea",
            "issue": "Issue",
            "book_problem": "Book: problem",
            "book_adding": "Book: to add",
            "other": "Other"
        },
        "tagTypes": {
            "tag": "Tag",
            "genre": "Genre"
        },
        "models": {
            "author": "Author",
            "book": "Book",
            "language": "Language",
            "publisher": "Publisher",
            "serie": "Serie",
            "tagextended": "TagExtended"
        }
    }
}
 

Request      

GET api/enums

GET Count.

Get count of entities for a selected collection. Available for Book, Serie and Author.

Route name: api.count

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/count?entities=author%2Cbook%2Cserie&languages=fr%2Cen" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/count"
);

const params = {
    "entities": "author,book,serie",
    "languages": "fr,en",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/count',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'entities'=> 'author,book,serie',
            'languages'=> 'fr,en',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4998
vary: Origin
 

{
    "data": {
        "entities": {
            "author": 26,
            "book": 198,
            "serie": 21
        },
        "languages": {
            "fr": 187,
            "en": 11
        }
    }
}
 

Request      

GET api/count

Query Parameters

entities  string  

key of enums.models' list.

languages  string  

slug of languages' list meta.slug.

GET Application.

Useful for CMS at front-end init with enums, languages and application.

Route name: api.application

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/application" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/application"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/application',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4997
vary: Origin
 

{
    "data": {
        "enums": {
            "authorRoles": {
                "aut": "Author"
            },
            "bookFormats": {
                "pdf": "PDF",
                "cbr": "cbr",
                "cbz": "CBZ",
                "epub": "EPUB"
            },
            "bookTypes": {
                "audio": "Audio",
                "comic": "Comic",
                "essay": "Essay",
                "handbook": "Handbook",
                "novel": "Novel"
            },
            "countSizes": {
                "xl": "xl",
                "lg": "lg",
                "md": "md",
                "sm": "sm",
                "xs": "xs"
            },
            "entities": {
                "book": "book",
                "author": "author",
                "serie": "serie",
                "entity": "entity",
                "feed": "feed"
            },
            "genders": {
                "unknown": "Unknown",
                "woman": "Woman",
                "nonbinary": "Non binary",
                "genderfluid": "Genderfluid",
                "agender": "Agender",
                "man": "Man"
            },
            "postStatus": {
                "draft": "Draft",
                "scheduled": "Scheduled",
                "published": "Published"
            },
            "roles": {
                "super_admin": "Super admin",
                "admin": "Admin",
                "publisher": "publisher",
                "user": "User"
            },
            "submissionsReasons": {
                "idea": "Idea",
                "issue": "Issue",
                "book_problem": "Book: problem",
                "book_adding": "Book: to add",
                "other": "Other"
            },
            "tagTypes": {
                "tag": "Tag",
                "genre": "Genre"
            },
            "models": {
                "author": "Author",
                "book": "Book",
                "language": "Language",
                "publisher": "Publisher",
                "serie": "Serie",
                "tagextended": "TagExtended"
            }
        },
        "languages": [
            {
                "name": "French",
                "meta": {
                    "slug": "fr",
                    "show": "https://bookshelves.ink/api/languages/fr"
                },
                "firstChar": "F",
                "count": null
            },
            {
                "name": "English",
                "meta": {
                    "slug": "en",
                    "show": "https://bookshelves.ink/api/languages/en"
                },
                "firstChar": "E",
                "count": null
            }
        ],
        "application": {
            "name": "Bookshelves",
            "title_template": "%s · Bookshelves",
            "slug": "bookshelves",
            "favicon": "https://bookshelves.ink/storage/media/cms/1/bookshelves-favicon.svg",
            "icon": "https://bookshelves.ink/storage/media/cms/2/bookshelves-icon.svg",
            "logo": "https://bookshelves.ink/storage/media/cms/3/bookshelves-logo.png",
            "og": "https://bookshelves.ink/storage/media/cms/4/bookshelves-og.jpg",
            "meta_title": "Bookshelves, reading in complete tranquility...",
            "meta_description": "For people with eReaders, download books and reading in complete tranquility, your digital library that goes everywhere with you.",
            "meta_author": "Bookshelves Team",
            "meta_twitter_creator": "@ewilanriviere",
            "meta_twitter_site": "@bookshelves_ink"
        }
    }
}
 

Request      

GET api/application

GET api/navigation

Route name: api.navigation

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/navigation" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/navigation"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/navigation',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4996
vary: Origin
 

{
    "data": {
        "navbar": [
            {
                "title": "Books",
                "route": "/books",
                "category": "navbar"
            },
            {
                "title": "Series",
                "route": "/series",
                "category": "navbar"
            },
            {
                "title": "Authors",
                "route": "/authors",
                "category": "navbar"
            },
            {
                "title": "Tags & genres",
                "route": "/tags",
                "category": "navbar"
            }
        ],
        "footer": []
    }
}
 

Request      

GET api/navigation

CMS

GET Home page.

Route name: api.cms.home-page

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/cms/home-page" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/cms/home-page"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/cms/home-page',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4990
vary: Origin
 

{
    "data": {
        "hero": {
            "title": "reading in complete tranquility...",
            "text": "If you have an eReader and are looking for plenty of books to take everywhere with you, you've come to the right place, hours of reading in perspective.",
            "picture": "https://bookshelves.ink/storage/media/cms/5/cms_hero.svg"
        },
        "statistics": {
            "eyebrow": "A quick tour of books count",
            "title": "Lots of books for ever more insatiable readers",
            "text": "More and more books for more and more reading, each day brings its own novelties (or almost). Don't hesitate to come back from time to time to discover the new books.",
            "list": [
                {
                    "label": "Books available",
                    "link": "",
                    "count": 198
                },
                {
                    "label": "Authors",
                    "link": "",
                    "count": 26
                },
                {
                    "label": "Series",
                    "link": "",
                    "count": 21
                },
                {
                    "label": "Books available in french",
                    "link": "",
                    "count": 187
                },
                {
                    "label": "Books available in english",
                    "link": "",
                    "count": 11
                }
            ]
        },
        "logos": {
            "title": "Special thanks to these softwares or websites because they help our work.",
            "list": [
                {
                    "label": "Calibre",
                    "slug": "calibre",
                    "link": "https://calibre-ebook.com",
                    "picture": "https://bookshelves.ink/storage/media/cms/6/calibre.webp"
                },
                {
                    "label": "Pandoc",
                    "slug": "pandoc",
                    "link": "https://pandoc.org",
                    "picture": "https://bookshelves.ink/storage/media/cms/7/pandoc.webp"
                },
                {
                    "label": "Team AlexandriZ",
                    "slug": "team-alexandriz",
                    "link": "https://twitter.com/teamalexandriz",
                    "picture": "https://bookshelves.ink/storage/media/cms/8/team-alexandriz.webp"
                },
                {
                    "label": "Lulu",
                    "slug": "lulu",
                    "link": "https://www.lulu.com",
                    "picture": "https://bookshelves.ink/storage/media/cms/9/lulu.webp"
                },
                {
                    "label": "OPDS",
                    "slug": "opds",
                    "link": "https://opds.io",
                    "picture": "https://bookshelves.ink/storage/media/cms/10/opds.webp"
                }
            ]
        },
        "features": {
            "title": "How to use Bookshelves",
            "text": "Let Bookshelves guide you through hundreds of books and let yourself be tempted by vast universes directly accessible by your eReader.",
            "list": [
                {
                    "title": "Open formats",
                    "text": "The available files are in open format, you can share and modify them.",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/11/epub.svg"
                },
                {
                    "title": "Regardless of eReader",
                    "text": "Kobo, Bookeen, Vivlio or even Kindle (with Calibre), you can use books in EPUB format on many eReaders (for eBooks).",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/12/ereader.svg"
                },
                {
                    "title": "Download & read",
                    "text": "Download a book and/or a serie of books add them to your eReader and start reading!",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/13/download.svg"
                },
                {
                    "title": "Metadata",
                    "text": "All these informations that allows you to sort and find your books by author or series are integrated into each book.",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/14/metadata.svg"
                },
                {
                    "title": "Multi languages",
                    "text": "Books in several languages according to your preferences in order to reach a maximum number of readers.",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/15/languages.svg"
                },
                {
                    "title": "OPDS, Catalog & Webreader",
                    "text": "With OPDS feed, you can access content from any source, on any device and with Catalog you can download books from your eReader or read an eBook in your browser with Webreader.",
                    "link": "",
                    "picture": "https://bookshelves.ink/storage/media/cms/16/feed.svg"
                }
            ]
        },
        "highlights": [
            {
                "title": "Find the book that fits you!",
                "text": "A selection of more than a hundred works, find the one that will strike a chord with your soul. And come back for ten more. Search by title, author or series then download all the books of an author or series if you wish!",
                "ctaText": "Discover all books",
                "ctaLink": {
                    "name": "books"
                },
                "quoteText": "Maybe it's not quite legal but it's cool!",
                "quoteAuthor": "An enthusiastic reader",
                "icon": "https://bookshelves.ink/storage/media/cms/17/books.svg",
                "picture": "https://bookshelves.ink/storage/media/cms/18/books.svg"
            },
            {
                "title": "Want to know your eReader?",
                "text": "Detailed guides are there to explain how to best manage your eReader but also to get to know the books better in order to modify them if you wish.",
                "ctaText": "Discover guides",
                "ctaLink": {
                    "name": "guides"
                },
                "quoteText": "The world of eReaders is so vast!",
                "quoteAuthor": "A novice user",
                "icon": "https://bookshelves.ink/storage/media/cms/19/guides.svg",
                "picture": "https://bookshelves.ink/storage/media/cms/20/guides.svg"
            },
            {
                "title": "Features, read as you wish",
                "text": "Features offer a lot of extra options to find and read books. You can download directly books from your eReader with Catalog or you can use OPDS (Open Publication Distribution System) feed to get all books on your favorite application. And if you want to read eBook directly in your browser with Webreader.",
                "ctaText": "Discover Features",
                "ctaLink": {
                    "name": "slug",
                    "params": {
                        "slug": "features"
                    }
                },
                "quoteText": "I am only interested in OPDS feeds adapted to my eReader with Koreader OS.",
                "quoteAuthor": "A very experimented reader",
                "icon": "https://bookshelves.ink/storage/media/cms/21/features.svg",
                "picture": "https://bookshelves.ink/storage/media/cms/22/features.svg"
            }
        ],
        "displayLatest": true,
        "displaySelection": true
    }
}
 

Request      

GET api/cms/home-page

CMS: Page

Endpoint to get Pages data.

GET Page[].

Route name: api.pages.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/pages" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/pages"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/pages',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6IkI1Nit5cTE1Q1JrYXZDYkt3N1RHQUE9PSIsInZhbHVlIjoicTltRlFySnlKY0x5MnNFTzRGTHVpam9uQzlGQ0FxS2hhTkpVcjN5RjNYTHVvKy9KR2pyOVVKZDVESi9GWkY2VjdhRkJldnVoSDMzTmcrZndWSVJweTZ1MGJ1YTV5QUI0RVJTOWtpRkZUN3pQdmc4SjdLUzc3aURmbVo0Q3ZBdWQiLCJtYWMiOiJiMmFkOWFhNTM0MzY0ZWNkYTc0YzJmYzBlZTc1MzVjOTI2ZmJhNzgxZjc3ZGE1YTUxMmZiY2ZiNDM2NjhkZDUwIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6Ii9aVzR1VjdUTkU0bDI4UFh0cURZSHc9PSIsInZhbHVlIjoiOXVQdjZzdy9kZVFMY3dibFRpd2x1anpVZUV3cVc5cWc3MlM1RDVNM3I2N0ZlUHJGMHBaOFMydTZwYm9yankvTDlFWG02Yzc1NzlBRCt0VndEVEswNDJYRHBsSDZsaEJhVlBkUjVQaFZ1Y2Q1WlZaMGpBZUNMSmtyejZmcDRKUzQiLCJtYWMiOiI4NTk4Mjc3M2IwNTI2NTUxNjA3NjcwZmZjOTUwYzliNzIyOWVmZjYzNGI0Mzc5ZDM0NmQ4NmRmNzUwYmRjOTllIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 

{
    "data": [
        {
            "title": "About",
            "meta": {
                "slug": "about",
                "title": "About",
                "description": "About this project",
                "show": "https://bookshelves.ink/api/pages/about"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/562/about.webp",
            "summary": "About this project",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        },
        {
            "title": "FAQ",
            "meta": {
                "slug": "faq",
                "title": "FAQ",
                "description": "Frequently Asked Questions",
                "show": "https://bookshelves.ink/api/pages/faq"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/564/faq.webp",
            "summary": "Frequently Asked Questions",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        },
        {
            "title": "Features: OPDS, Catalog & more",
            "meta": {
                "slug": "features",
                "title": "Features: OPDS, Catalog & more",
                "description": "On other ways",
                "show": "https://bookshelves.ink/api/pages/features"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/565/features.webp",
            "summary": "On other ways",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        },
        {
            "title": "Legal",
            "meta": {
                "slug": "legal",
                "title": "Legal",
                "description": "About legal",
                "show": "https://bookshelves.ink/api/pages/legal"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/566/legal.webp",
            "summary": "About legal",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        },
        {
            "title": "More eBooks",
            "meta": {
                "slug": "more-ebooks",
                "title": "More eBooks",
                "description": "About more eBooks projects",
                "show": "https://bookshelves.ink/api/pages/more-ebooks"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/567/more-ebooks.webp",
            "summary": "About more eBooks projects",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        },
        {
            "title": "Privacy",
            "meta": {
                "slug": "privacy",
                "title": "Privacy",
                "description": "Your privacy & your data",
                "show": "https://bookshelves.ink/api/pages/privacy"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/568/privacy.webp",
            "summary": "Your privacy & your data",
            "publishedAt": "2022-04-24T06:25:01.000000Z",
            "updatedAt": "2022-04-24T06:25:01.000000Z"
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/pages?page=1",
        "last": "https://bookshelves.ink/api/pages?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/pages?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/pages",
        "per_page": 32,
        "to": 6,
        "total": 6
    }
}
 

Request      

GET api/pages

GET Page.

Route name: api.pages.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/pages/features" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/pages/features"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/pages/features',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6IllwYU1jK3hTcEZxbFZjY0lreENOOEE9PSIsInZhbHVlIjoiMHNDZXZFTkFoVENIZ2ZyMXdHeGZLb0N4RUE1MzBkQlNjeFR4bEhhWVBoa1R1V3lQanVwbXVHakIyZzcrRVd1VUNINWQvWmRXRlg1Sm4zTEVYeDhHdVBXQmliVHVRNDY4WWlrbWk1M3I0R1MwZThVWmV3Sk1kLzNDYmpUcVRmNFYiLCJtYWMiOiJlMTBhZTgzN2VjNDIzMzE4YWM2ZTY4ODgxMDQ4NjU2ZGU0NWE5MTQxNmU2MzZmYTU3M2E4YzVhM2NjMmFlNGI1IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6IkF4OW5UTHEzUmFSVkk0OFU5a1kzRWc9PSIsInZhbHVlIjoiMWxHcms1Y016VTg2dzFIdS9TRXJ2WTZNVWM1eitRMHMyUjYwb1NVUE8vTS9ZbXRPN0JvT1ZGemtCVlg3eEcwRUFsQVZUUGkrN0xRdnhwd3ZCZTBTVlJkWkxLSjVkSlJTdlhYSmxmRFAvQzluZy93Q2lzVWVnSHFadkRiSituWGkiLCJtYWMiOiIyMmMxOGMxMDUzNjAyMjFlYTg3MGY3ODAwODVmMzE4ZmFjNzMxZjQ1YWVlYTc3M2M0MzhlYTRiMGU4OGU3YWRmIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 

{
    "data": {
        "title": "Features: OPDS, Catalog & more",
        "meta": {
            "slug": "features",
            "title": "Features: OPDS, Catalog & more",
            "description": "On other ways",
            "show": "https://bookshelves.ink/api/pages/features"
        },
        "cover": "https://bookshelves.ink/storage/media/cms/565/features.webp",
        "summary": "On other ways",
        "publishedAt": "2022-04-24T06:25:01.000000Z",
        "updatedAt": "2022-04-24T06:25:01.000000Z",
        "body": "<p><em>With Features, you can use some extra options like OPDS feed, Catalog to browse eBooks from your eReader or read an eBook in your web browser. If you are a developer, you will find Wiki for application usage, API documentation and more.</em></p>\n<h2 id=\"opds\">OPDS</h2>\n<blockquote>\n<p>The Open Publication Distribution System (OPDS) catalog format is a syndication format for electronic publications based on Atom and HTTP. OPDS catalogs enable the aggregation, distribution, discovery, and acquisition of electronic publications. OPDS catalogs use existing or emergent open standards and conventions, with a priority on simplicity.</p>\n<p>The Open Publication Distribution System specification is prepared by an informal grouping of partners, combining Internet Archive, O'Reilly Media, Feedbooks, OLPC, and others.</p>\n</blockquote>\n<p>Bookshelves is also available with OPDS feed, if you have any application with OPDS feature, you can add feed of Bookshelves, just add <a href=\"https://bookshelves.ink/opds?version=1.2_12\" target=\"_blank\" rel=\"noopener noreferrer\">https://bookshelves.ink/opds?version=1.2_12</a> to your application. To known more about application which can use OPDS, check <a href=\"/pages/more-ebooks#opds\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>More eBooks</strong></a>. You can check <a href=\"https://opds.io/\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>opds.io</strong></a> to know more about OPDS, Bookshelves OPDS is based on <a href=\"https://specs.opds.io/\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>specs.opds.io</strong></a>.</p>\n<h3 id=\"versions\">Versions</h3>\n<p>OPDS versions available</p>\n<ul>\n<li>v1.2: <a href=\"https://bookshelves.ink/opds?version=1.2_12\" target=\"_blank\" rel=\"noopener noreferrer\">https://bookshelves.ink/opds?version=1.2_12</a>\n</li>\n</ul>\n<h2 id=\"catalog\">Catalog</h2>\n<p>Most of eReader can't read OPDS feeds, so to download directly eBooks you have to use a computer and set manually eBooks on your device, etc... But <strong>Catalog</strong> is the solution <strong>to download directly eBooks on your eReader without any computer</strong>.</p>\n<p>If you have any eReader with browser, you can use <strong>Catalog</strong>, it's an very simple interface for your eReader like any shop to directly search and download eBooks. You have just to put <a href=\"https://bookshelves.ink/catalog\" target=\"_blank\" rel=\"noopener noreferrer\">https://bookshelves.ink/catalog</a> URL into your eReader browser. To know more about download of eBooks with browser from your eReader, check <a href=\"/guides/ereader-download-ebook-from-ereader\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Download eBook from eReader guide</strong></a>.</p>\n<h3 id=\"limitations\">Limitations</h3>\n<ul>\n<li>you will <strong>not be able to have the series associated with an eBook</strong> with this method because of the limitations of the EPUB format used. The only solution* is to add the series with the Calibre software, as explained in this guide <a href=\"/guides/ereader-series\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Get series on your Kobo</strong></a> for Kobo eReaders, with a file added on your eReader.</li>\n<li>you will <strong>not be able to download a whole series or all the eBooks of an author</strong> because it is a .zip format that is proposed and your eReader only reads the formats linked to the eBooks.</li>\n</ul>\n<h3 id=\"why\">Why ?</h3>\n<p>The eReader's web browser is not very powerful, it's can be difficult to use because the touch on an eReader is not very responsive. Therefore, the OPDS adapts to this difficulty and proposes to search directly for the desired eBook, series or author in order to limit the results and to find the eReader more easily.</p>\n<h2 id=\"webreader\">Webreader</h2>\n<p>You can read any eBook available on Bookshelves <strong>directly in your browser with Webreader</strong>, you can <strong>access it from the detail page of any book</strong> in the available actions. Webreader is a simple and effective feature aimed at allowing you to quickly read an eBook but not having all the options like on an eReader. You can <strong>discover Webreader right now</strong> by trying it with a random eBook from <a href=\"https://bookshelves.ink/webreader\" target=\"_blank\" rel=\"noopener noreferrer\">https://bookshelves.ink/webreader</a>.</p>\n<p>*: You may have noticed that the store allows you to display the series of the books you add from it but this is because as an internal program of your eReader, the store can modify the information related to an eBook and thus add the series, which Calibre can do more manually.</p>\n"
    }
}
 

Request      

GET api/pages/{page_slug}

URL Parameters

page_slug  string  

slug of page in meta.slug pages' list, example: features

CMS: Post

Endpoint to get Posts data.

GET Post[].

Route name: api.posts.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/posts" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/posts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/posts',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6IklYOVZIdllhWkxxRnpDQWVBK1FISGc9PSIsInZhbHVlIjoiaysrSTUvMk1LT1M4WHhlMVZJazJhb3RqZjZWZEdpVlJBZElJaEpDWVlCdXZINnJMRXVvdEVrS1lDckNEdURUQzNqUUdVNnI3aDVNbC9BRHlKNGVZZkYyWUNjNUFmMXQvVm9XTGNCbzhuMXhJL0srQk9aL0trU09KTWkzbjNwRU8iLCJtYWMiOiI1YjYxODA2MDI2MTBlNzJjOTIyYWZlOGZjMTIzNjFkMTFmYWM4NDllNzY3MWVhNTk5MjQ0ZWYwNTA1OTQwZTYwIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6IityRXg5RnNBa3pSU3lhbEZSVUNnZkE9PSIsInZhbHVlIjoidUppUUY3Z2paWWJnNVh2d2kwdktnQXNiTTBCU1NPVlA2NVZ6Z3lIM01QSGlRNVFiZXYwZ20xejFqM2YyK3JmREpXL3pXOTlmK0dOTjNXNzN1NGRpam5JZ1IxQ2hRVGpMRGY5WU1nMEVNMUdLdGFrNGZNeHJXTGxURGQyOG9KalIiLCJtYWMiOiI4MjZhMjllNzQ5ZTBiYjRiOGRlNmQ3YzNlNDViNjBiN2NmMGMzYTRkYjUxNWEyOTI5YmVhNTY2OWE5Njg3MzM3IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 

{
    "data": [
        {
            "title": "Presentation",
            "meta": {
                "slug": "presentation",
                "title": "Presentation",
                "description": "What is Calibre and why it's a very cool software",
                "show": "https://bookshelves.ink/api/posts/presentation"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/544/presentation.webp",
            "category": "Calibre",
            "user": "Super Admin",
            "summary": "What is Calibre and why it's a very cool software",
            "publishedAt": "2022-04-24T06:24:54.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": false
        },
        {
            "title": "Download eBook from eReader",
            "meta": {
                "slug": "download-ebook-from-ereader",
                "title": "Download eBook from eReader",
                "description": "How to download an eBook directly from your eReader?",
                "show": "https://bookshelves.ink/api/posts/download-ebook-from-ereader"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/546/download-ebook-from-ereader.webp",
            "category": "eReader",
            "user": "Super Admin",
            "summary": "How to download an eBook directly from your eReader?",
            "publishedAt": "2021-05-12T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": false
        },
        {
            "title": "Remove DRM",
            "meta": {
                "slug": "remove-drm",
                "title": "Remove DRM",
                "description": "Shut down DRM now!",
                "show": "https://bookshelves.ink/api/posts/remove-drm"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/545/remove-drm.webp",
            "category": "Calibre",
            "user": "Super Admin",
            "summary": "Shut down DRM now!",
            "publishedAt": "2021-04-23T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": false
        },
        {
            "title": "Tips",
            "meta": {
                "slug": "tips",
                "title": "Tips",
                "description": "Do you know really your Kobo?",
                "show": "https://bookshelves.ink/api/posts/tips"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/559/tips.webp",
            "category": "eReader",
            "user": "Super Admin",
            "summary": "Do you know really your Kobo?",
            "publishedAt": "2021-04-06T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": false
        },
        {
            "title": "Manage comics or mangas",
            "meta": {
                "slug": "manage-comics-or-mangas",
                "title": "Manage comics or mangas",
                "description": "How to manage comics/mangas with CBZ format on Calibre",
                "show": "https://bookshelves.ink/api/posts/manage-comics-or-mangas"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/531/manage-comics-or-mangas.webp",
            "category": "Calibre",
            "user": "Super Admin",
            "summary": "How to manage comics/mangas with CBZ format on Calibre",
            "publishedAt": "2021-02-03T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:53.000000Z",
            "pin": false
        },
        {
            "title": "Set metadata",
            "meta": {
                "slug": "set-metadata",
                "title": "Set metadata",
                "description": "How to update EPUB metadata with Calibre",
                "show": "https://bookshelves.ink/api/posts/set-metadata"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/532/set-metadata.webp",
            "category": "Calibre",
            "user": "Super Admin",
            "summary": "How to update EPUB metadata with Calibre",
            "publishedAt": "2021-02-03T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": true
        },
        {
            "title": "Get series",
            "meta": {
                "slug": "get-series",
                "title": "Get series",
                "description": "Series can not work on the fly with your eReader, this guide explain to force your eReader to display it",
                "show": "https://bookshelves.ink/api/posts/get-series"
            },
            "cover": "https://bookshelves.ink/storage/media/cms/553/get-series.webp",
            "category": "eReader",
            "user": "Super Admin",
            "summary": "Series can not work on the fly with your eReader, this guide explain to force your eReader to display it",
            "publishedAt": "2021-02-03T00:00:00.000000Z",
            "updatedAt": "2022-04-24T06:24:54.000000Z",
            "pin": false
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/posts?page=1",
        "last": "https://bookshelves.ink/api/posts?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/posts?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/posts",
        "per_page": 32,
        "to": 7,
        "total": 7
    }
}
 

Request      

GET api/posts

GET Post.

Route name: api.posts.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/posts/download-ebook-from-ereader" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/posts/download-ebook-from-ereader"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/posts/download-ebook-from-ereader',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6Ik1LNzVqRE1tVXRleVhPd0FXRC9tdmc9PSIsInZhbHVlIjoiRW9IaEFNZDdRRzJmaS9wQ2JLaHVhS1dpRXk4TUMzOExkblVTTnhhUW4xUk9Dc1Y4YzRETnc4emFXSGtnaDYxcy9xdWFBR0J4MEpMUS9tdzFOdE50KzRWY2VWVWZhamxuek1FdURKZUFQT2hYOFk5OTVRR3UwRHVNeGl4ZlhiOHAiLCJtYWMiOiJlMTUwY2NkNWFkYmJkMDMxMWZkNGU3OWE0ODUyMTQxMDRiZmIwNmQwNzA1ZTU0NTc3NjgxNDlmMDIyOTVhYTM0IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6ImYxRmxmV3V1blhYOW1mY3RrYUJCZ1E9PSIsInZhbHVlIjoicnFkWHQwcWFtVVFKV3NmbEdmdDNNWWVycDBTNDRmNlNXVXVqTzFONU9YM2dGQXVhRkJKY2hjRkd4UHZnektNcGRFZlZaVGdhNGVmcmhtcG1mMEdRVGZNaDVBNmh4dUhEZU94Qld3cmJqODNDNlpCVlQyUGM3NlhEVG8vaVFUU3ciLCJtYWMiOiI2ZjFiY2U3ZjczZDJiMGIyYzM1YTJmOTQ2YjAxODE5YTUwNzU5MjM3ZmVlZTY4NjAyMWIzZDY4ZGE5MDc2OWU4IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 

{
    "data": {
        "title": "Download eBook from eReader",
        "meta": {
            "slug": "download-ebook-from-ereader",
            "title": "Download eBook from eReader",
            "description": "How to download an eBook directly from your eReader?",
            "show": "https://bookshelves.ink/api/posts/download-ebook-from-ereader"
        },
        "cover": "https://bookshelves.ink/storage/media/cms/546/download-ebook-from-ereader.webp",
        "category": "eReader",
        "user": "Super Admin",
        "summary": "How to download an eBook directly from your eReader?",
        "publishedAt": "2021-05-12T00:00:00.000000Z",
        "updatedAt": "2022-04-24T06:24:54.000000Z",
        "pin": false,
        "body": "<p>This article was written using a <strong>Kobo (Clara HD)</strong> to present the use of a web browser with an eReader. Therefore the screenshots presented to show how to use the browser are related to the Kobo interface. Most eReaders offer a browser but its location may differ from one eReader to another, so please refer to specialized articles on your eReader if the present guide is not enough to find it. <strong>If your eReader don't offer any browser, you can't use this guide.</strong></p>\n<p>With your eReader you can download an eBook directly from Internet. To do this, you need to use your eReader's web browser to find a website that will offer you a direct download of an .epub file. The goal is to perform almost the same action as when you download a recently purchased eBook from your eReader's internal store, if your eReader offers one.</p>\n<h2 id=\"find-your-internet-browser\">Find your Internet browser</h2>\n<p>From the Kobo browser example, from the eReader's home screen, tap on \"More\" in bottom navigation and then choose \"Beta Features\"...</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/547/ereader-download-ebook-from-ereader-kobo-more.webp.webp\" alt=\"More menu with Kobo\" loading=\"lazy\">\n<p>...and tap on \"<strong>Start</strong>\" in \"<strong>Web Browser</strong>\".</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/548/ereader-download-ebook-from-ereader-kobo-beta-features.webp.webp\" alt=\"Browser is hidden in submenu\" loading=\"lazy\">\n<p>This will open the home page, usually on Google, you have <strong>URL bar at the top</strong>, <strong>back, next &amp; refresh buttons at the bottom</strong> with a zoom bar, don't leave out the three dots indicating additional options at the bottom right as <strong>you can add websites as favorites</strong>.</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/549/ereader-download-ebook-from-ereader-browser-home.webp.webp\" alt=\"It's a small browser with vital options\" loading=\"lazy\">\n<h2 id=\"an-example\">An example</h2>\n<p>We will take an example with this website, with <a href=\"https://bookshelves.ink/catalog\" target=\"_blank\" rel=\"noopener noreferrer\">Catalog service</a>, just put this URL in URL bar and tap on \"Go\" <a href=\"https://bookshelves.ink/catalog\" target=\"_blank\" rel=\"noopener noreferrer\">https://bookshelves.ink/catalog</a>. You will see Catalog home page with search bar, don't hesitate to add it to your favorites.</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/550/ereader-download-ebook-from-ereader-browser-options.webp.webp\" alt=\"Catalog home page\" loading=\"lazy\">\n<p>Search any book with title, author firstname and lastname or series' title. If you have an author or a series in results, you can tap on it to get all books associate with it, you can't download directly all books, you have to tap on book you want and tap on \"Download\". Here, we've choose a book:</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/551/ereader-download-ebook-from-ereader-browser-ebook-example.webp.webp\" alt=\"An eBook on Catalog\" loading=\"lazy\">\n<p>A popup will appear when you tap on \"Download\", if you continue, your browser will download eBook.</p>\n<img src=\"https://bookshelves.ink/storage/media/cms/552/ereader-download-ebook-from-ereader-brower-download.webp.webp\" alt=\"Browser download popup\" loading=\"lazy\">\n<p>When you have eBook downloaded, you will find it in your books. If the book is associaté with series, you can't display it with this method because .epub files have some limitations about series, to add series informations you will need a computer with Calibre, check <a href=\"/guides/ereader-series\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Set series guide</strong></a> for more informations.</p>\n"
    }
}
 

Request      

GET api/posts/{post_slug}

URL Parameters

post_slug  string  

slug of post in meta.slug posts' list, example: download-ebook-from-ereader

Entities

Endpoint about data from main entities.

Search full-text into authors, books & series.

Route name: api.search

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/search?q=twain" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/search"
);

const params = {
    "q": "twain",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/search',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'q'=> 'twain',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4995
vary: Origin
 

{
    "data": {
        "count": 2,
        "type": "meilisearch",
        "relevant": {
            "authors": [
                {
                    "meta": {
                        "entity": "author",
                        "author": null,
                        "slug": "twain-mark",
                        "show": "https://bookshelves.ink/api/authors/twain-mark"
                    },
                    "title": "Twain Mark",
                    "type": null,
                    "authors": null,
                    "serie": null,
                    "language": null,
                    "volume": null,
                    "count": null,
                    "cover": {
                        "thumbnail": "https://bookshelves.ink/storage/media/covers/497/conversions/twain-mark-thumbnail.webp",
                        "original": "https://bookshelves.ink/storage/media/covers/497/twain-mark.webp",
                        "simple": "https://bookshelves.ink/storage/media/covers/497/conversions/twain-mark-simple.jpg",
                        "color": "#636363"
                    },
                    "first_char": "t"
                }
            ],
            "series": [],
            "books": [
                {
                    "meta": {
                        "entity": "book",
                        "author": "twain-mark",
                        "slug": "adventures-of-huckleberry-finn-novel-en",
                        "show": "https://bookshelves.ink/api/books/twain-mark/adventures-of-huckleberry-finn-novel-en"
                    },
                    "title": "Adventures of Huckleberry Finn",
                    "type": "Novel",
                    "authors": [
                        {
                            "name": "Twain Mark",
                            "meta": {
                                "entity": "author",
                                "slug": "twain-mark",
                                "show": "https://bookshelves.ink/api/authors/twain-mark"
                            }
                        }
                    ],
                    "serie": null,
                    "language": {
                        "name": "English",
                        "meta": {
                            "slug": "en"
                        }
                    },
                    "volume": null,
                    "count": null,
                    "cover": {
                        "thumbnail": "https://bookshelves.ink/storage/media/covers/266/conversions/adventures-of-huckleberry-finn-novel-en-thumbnail.webp",
                        "original": "https://bookshelves.ink/storage/media/covers/266/adventures-of-huckleberry-finn-novel-en.webp",
                        "simple": "https://bookshelves.ink/storage/media/covers/266/conversions/adventures-of-huckleberry-finn-novel-en-simple.jpg",
                        "color": "#94b4ae"
                    },
                    "first_char": null
                }
            ]
        },
        "other": {
            "authors": [],
            "series": [],
            "books": []
        }
    }
}
 

GET Entity[] latest entries.

Get all Books ordered by date updated_at, limited to 10 results (no pagination).

Route name: api.entities.latest

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/entities/latest" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/entities/latest"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/entities/latest',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4994
vary: Origin
 

{
    "data": [
        {
            "meta": {
                "entity": "book",
                "author": "vian-boris",
                "slug": "les-morts-ont-tous-la-meme-peau-novel-fr",
                "show": "https://bookshelves.ink/api/books/vian-boris/les-morts-ont-tous-la-meme-peau-novel-fr"
            },
            "title": "Les Morts ont tous la même peau",
            "type": "Novel",
            "authors": [
                {
                    "name": "Vian Boris",
                    "meta": {
                        "entity": "author",
                        "slug": "vian-boris",
                        "show": "https://bookshelves.ink/api/authors/vian-boris"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/392/conversions/les-morts-ont-tous-la-meme-peau-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/392/les-morts-ont-tous-la-meme-peau-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/392/conversions/les-morts-ont-tous-la-meme-peau-novel-fr-simple.jpg",
                "color": "#d3a09a"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "voltaire",
                "slug": "zadig-ou-la-destinee-orientale-novel-fr",
                "show": "https://bookshelves.ink/api/books/voltaire/zadig-ou-la-destinee-orientale-novel-fr"
            },
            "title": "Zadig ou La Destinée Orientale",
            "type": "Novel",
            "authors": [
                {
                    "name": "Voltaire ",
                    "meta": {
                        "entity": "author",
                        "slug": "voltaire",
                        "show": "https://bookshelves.ink/api/authors/voltaire"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/402/conversions/zadig-ou-la-destinee-orientale-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/402/zadig-ou-la-destinee-orientale-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/402/conversions/zadig-ou-la-destinee-orientale-novel-fr-simple.jpg",
                "color": "#88736c"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "zola-emile",
                "slug": "au-bonheur-des-dames-novel-fr",
                "show": "https://bookshelves.ink/api/books/zola-emile/au-bonheur-des-dames-novel-fr"
            },
            "title": "Au bonheur des dames",
            "type": "Novel",
            "authors": [
                {
                    "name": "Zola Émile",
                    "meta": {
                        "entity": "author",
                        "slug": "zola-emile",
                        "show": "https://bookshelves.ink/api/authors/zola-emile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/408/conversions/au-bonheur-des-dames-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/408/au-bonheur-des-dames-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/408/conversions/au-bonheur-des-dames-novel-fr-simple.jpg",
                "color": "#837453"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "zola-emile",
                "slug": "la-terre-novel-fr",
                "show": "https://bookshelves.ink/api/books/zola-emile/la-terre-novel-fr"
            },
            "title": "La Terre",
            "type": "Novel",
            "authors": [
                {
                    "name": "Zola Émile",
                    "meta": {
                        "entity": "author",
                        "slug": "zola-emile",
                        "show": "https://bookshelves.ink/api/authors/zola-emile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/436/conversions/la-terre-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/436/la-terre-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/436/conversions/la-terre-novel-fr-simple.jpg",
                "color": "#bba898"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "zola-emile",
                "slug": "le-capitaine-burle-novel-fr",
                "show": "https://bookshelves.ink/api/books/zola-emile/le-capitaine-burle-novel-fr"
            },
            "title": "Le Capitaine Burle",
            "type": "Novel",
            "authors": [
                {
                    "name": "Zola Émile",
                    "meta": {
                        "entity": "author",
                        "slug": "zola-emile",
                        "show": "https://bookshelves.ink/api/authors/zola-emile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/438/conversions/le-capitaine-burle-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/438/le-capitaine-burle-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/438/conversions/le-capitaine-burle-novel-fr-simple.jpg",
                "color": "#a57245"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "zola-emile",
                "slug": "nana-novel-fr",
                "show": "https://bookshelves.ink/api/books/zola-emile/nana-novel-fr"
            },
            "title": "Nana",
            "type": "Novel",
            "authors": [
                {
                    "name": "Zola Émile",
                    "meta": {
                        "entity": "author",
                        "slug": "zola-emile",
                        "show": "https://bookshelves.ink/api/authors/zola-emile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/448/conversions/nana-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/448/nana-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/448/conversions/nana-novel-fr-simple.jpg",
                "color": "#8c8a77"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "zola-emile",
                "slug": "pot-bouille-novel-fr",
                "show": "https://bookshelves.ink/api/books/zola-emile/pot-bouille-novel-fr"
            },
            "title": "Pot-Bouille",
            "type": "Novel",
            "authors": [
                {
                    "name": "Zola Émile",
                    "meta": {
                        "entity": "author",
                        "slug": "zola-emile",
                        "show": "https://bookshelves.ink/api/authors/zola-emile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/450/conversions/pot-bouille-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/450/pot-bouille-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/450/conversions/pot-bouille-novel-fr-simple.jpg",
                "color": "#bababa"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "bourses-de-voyage-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/bourses-de-voyage-novel-fr"
            },
            "title": "Bourses de voyage",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/274/conversions/bourses-de-voyage-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/274/bourses-de-voyage-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/274/conversions/bourses-de-voyage-novel-fr-simple.jpg",
                "color": "#a29977"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "cinq-semaines-en-ballon-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/cinq-semaines-en-ballon-novel-fr"
            },
            "title": "Cinq semaines en ballon",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/276/conversions/cinq-semaines-en-ballon-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/276/cinq-semaines-en-ballon-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/276/conversions/cinq-semaines-en-ballon-novel-fr-simple.jpg",
                "color": "#ab6c5f"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "de-la-terre-a-la-lune-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/de-la-terre-a-la-lune-novel-fr"
            },
            "title": "De la Terre à la Lune",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/280/conversions/de-la-terre-a-la-lune-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/280/de-la-terre-a-la-lune-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/280/conversions/de-la-terre-a-la-lune-novel-fr-simple.jpg",
                "color": "#666561"
            },
            "first_char": null
        }
    ]
}
 

Request      

GET api/entities/latest

GET Entity[] from Selectionable.

Get all entities selected, limited to 10 results (no pagination).

Route name: api.entities.selection

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/entities/selection" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/entities/selection"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/entities/selection',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4993
vary: Origin
 

{
    "data": [
        {
            "meta": {
                "entity": "book",
                "author": "dickens-charles",
                "slug": "aventures-de-monsieur-pickwick-novel-en",
                "show": "https://bookshelves.ink/api/books/dickens-charles/aventures-de-monsieur-pickwick-novel-en"
            },
            "title": "Aventures de Monsieur Pickwick",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "English",
                "meta": {
                    "slug": "en"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/77/conversions/aventures-de-monsieur-pickwick-novel-en-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/77/aventures-de-monsieur-pickwick-novel-en.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/77/conversions/aventures-de-monsieur-pickwick-novel-en-simple.jpg",
                "color": "#b19a81"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "la-journee-dun-journaliste-americain-en-2890-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/la-journee-dun-journaliste-americain-en-2890-novel-fr"
            },
            "title": "La journée d'un journaliste américain en 2890",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/314/conversions/la-journee-dun-journaliste-americain-en-2890-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/314/la-journee-dun-journaliste-americain-en-2890-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/314/conversions/la-journee-dun-journaliste-americain-en-2890-novel-fr-simple.jpg",
                "color": "#949494"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "dumas-alexandre",
                "slug": "le-vicomte-de-bragelonne-tome-i-novel-fr",
                "show": "https://bookshelves.ink/api/books/dumas-alexandre/le-vicomte-de-bragelonne-tome-i-novel-fr"
            },
            "title": "Le Vicomte de Bragelonne, tome I",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "serie": "Le Vicomte de Bragelonne",
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": 1,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/181/conversions/le-vicomte-de-bragelonne-tome-i-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/181/le-vicomte-de-bragelonne-tome-i-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/181/conversions/le-vicomte-de-bragelonne-tome-i-novel-fr-simple.jpg",
                "color": "#5a5215"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "famille-sans-nom-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/famille-sans-nom-novel-fr"
            },
            "title": "Famille-sans-nom",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/288/conversions/famille-sans-nom-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/288/famille-sans-nom-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/288/conversions/famille-sans-nom-novel-fr-simple.jpg",
                "color": "#94797d"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "book",
                "author": "verne-jules",
                "slug": "la-maison-a-vapeur-novel-fr",
                "show": "https://bookshelves.ink/api/books/verne-jules/la-maison-a-vapeur-novel-fr"
            },
            "title": "La Maison à vapeur",
            "type": "Novel",
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/316/conversions/la-maison-a-vapeur-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/316/la-maison-a-vapeur-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/316/conversions/la-maison-a-vapeur-novel-fr-simple.jpg",
                "color": "#c37ab2"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "serie",
                "author": "dumas-alexandre",
                "slug": "joseph-balsamo-novel-fr",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/joseph-balsamo-novel-fr"
            },
            "title": "Joseph Balsamo",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": 4,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/467/conversions/joseph-balsamo-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/467/joseph-balsamo-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/467/conversions/joseph-balsamo-novel-fr-simple.jpg",
                "color": "#a59b91"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "serie",
                "author": "dickens-charles",
                "slug": "lami-commun-novel-fr",
                "show": "https://bookshelves.ink/api/series/dickens-charles/lami-commun-novel-fr"
            },
            "title": "L'Ami commun",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": 2,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/462/conversions/lami-commun-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/462/lami-commun-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/462/conversions/lami-commun-novel-fr-simple.jpg",
                "color": "#655360"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "serie",
                "author": "dumas-alexandre",
                "slug": "le-vicomte-de-bragelonne-novel-fr",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/le-vicomte-de-bragelonne-novel-fr"
            },
            "title": "Le Vicomte de Bragelonne",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": 4,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/474/conversions/le-vicomte-de-bragelonne-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/474/le-vicomte-de-bragelonne-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/474/conversions/le-vicomte-de-bragelonne-novel-fr-simple.jpg",
                "color": "#5a5215"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "serie",
                "author": "dickens-charles",
                "slug": "dombey-et-fils-novel-fr",
                "show": "https://bookshelves.ink/api/series/dickens-charles/dombey-et-fils-novel-fr"
            },
            "title": "Dombey Et Fils",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": 3,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/461/conversions/dombey-et-fils-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/461/dombey-et-fils-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/461/conversions/dombey-et-fils-novel-fr-simple.jpg",
                "color": "#29382d"
            },
            "first_char": null
        },
        {
            "meta": {
                "entity": "serie",
                "author": "dumas-alexandre",
                "slug": "les-trois-mousquetaires-novel-fr",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/les-trois-mousquetaires-novel-fr"
            },
            "title": "Les Trois Mousquetaires",
            "type": "Novel",
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": 2,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/477/conversions/les-trois-mousquetaires-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/477/les-trois-mousquetaires-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/477/conversions/les-trois-mousquetaires-novel-fr-simple.jpg",
                "color": "#dfd6d2"
            },
            "first_char": null
        }
    ]
}
 

Request      

GET api/entities/selection

WITH PAGINATION

Get all Series/Books related to selected Book from Tag.

Route name: api.entities.related

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/entities/related/verne-jules/la-chasse-au-meteore-novel-fr?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/entities/related/verne-jules/la-chasse-au-meteore-novel-fr"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/entities/related/verne-jules/la-chasse-au-meteore-novel-fr',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (400):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4992
vary: Origin
 

"No tags or no books related"
 

GET Entity Review[].

Route name: api.entities.reviews

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/entities/reviews/{entity}/{entity_id}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/entities/reviews/{entity}/{entity_id}"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/entities/reviews/{entity}/{entity_id}',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (500):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4991
vary: Origin
 

{
    "message": "App\\Http\\Controllers\\Api\\EntityController::reviews(): Argument #3 ($id) must be of type int, string given, called in /home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Controller.php on line 54",
    "exception": "TypeError",
    "file": "/home/ewilan/www/bookshelves-back/app/Http/Controllers/Api/EntityController.php",
    "line": 84,
    "trace": [
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
            "line": 54,
            "function": "reviews",
            "class": "App\\Http\\Controllers\\Api\\EntityController",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
            "line": 45,
            "function": "callAction",
            "class": "Illuminate\\Routing\\Controller",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 261,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\ControllerDispatcher",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 204,
            "function": "runController",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 725,
            "function": "run",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
            "line": 50,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 126,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 102,
            "function": "handleRequest",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 54,
            "function": "handleRequestUsingNamedLimiter",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 33,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Laravel\\Sanctum\\Http\\Middleware\\{closure}",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 34,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 726,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 703,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 667,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 656,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 167,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/livewire/livewire/src/DisableBrowserCache.php",
            "line": 19,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Livewire\\DisableBrowserCache",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/fruitcake/laravel-cors/src/HandleCors.php",
            "line": 52,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Fruitcake\\Cors\\HandleCors",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php",
            "line": 39,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Http\\Middleware\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 142,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 111,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 299,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 287,
            "function": "callLaravelOrLumenRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 89,
            "function": "makeApiCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 45,
            "function": "makeResponseCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 35,
            "function": "makeResponseCallIfConditionsPass",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 222,
            "function": "__invoke",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 179,
            "function": "iterateThroughStrategies",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 116,
            "function": "fetchResponses",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 118,
            "function": "processRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 75,
            "function": "extractEndpointsInfoFromLaravelApp",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 51,
            "function": "extractEndpointsInfoAndWriteToDisk",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php",
            "line": 50,
            "function": "get",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 36,
            "function": "handle",
            "class": "Knuckles\\Scribe\\Commands\\GenerateDocumentation",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Util.php",
            "line": 41,
            "function": "Illuminate\\Container\\{closure}",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 93,
            "function": "unwrapIfClosure",
            "class": "Illuminate\\Container\\Util",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 37,
            "function": "callBoundMethod",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 651,
            "function": "call",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 136,
            "function": "call",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Command/Command.php",
            "line": 291,
            "function": "execute",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 121,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Command\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 989,
            "function": "run",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 299,
            "function": "doRunCommand",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 171,
            "function": "doRun",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Application.php",
            "line": 102,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php",
            "line": 129,
            "function": "run",
            "class": "Illuminate\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/artisan",
            "line": 37,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Console\\Kernel",
            "type": "->"
        }
    ]
}
 

Request      

GET api/entities/reviews/{entity}/{entity_id}

Entities: download

Endpoint to download entities.

GET Book.

Content-Type application/epub+zip

Download Book format like epub or cbz.

Route name: api.download.book

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/download/book/dumas-alexandre/le-collier-de-la-reine-tome-1-novel-fr" \
    --header "Content-Type: application/epub+zip" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/download/book/dumas-alexandre/le-collier-de-la-reine-tome-1-novel-fr"
);

const headers = {
    "Content-Type": "application/epub+zip",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/download/book/dumas-alexandre/le-collier-de-la-reine-tome-1-novel-fr',
    [
        'headers' => [
            'Content-Type' => 'application/epub+zip',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: public
content-disposition: attachment; filename=dumas-alexandre-collier-de-la-reine-01-collier-de-la-reine-tome-1-fr.epub
content-type: application/epub+zip
accept-ranges: bytes
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6IlhiUk8ybGx4SjhLRFREUjNwNWs4THc9PSIsInZhbHVlIjoiWndaRWNEWlBDK0RxSExXNXZwd1lXRWMrZ0UrejVmeUVyS25jWWJDU1RjdkRMRkkwOU5ZZXVYTk0xZGxBRG95clZaN0NhZnVWYThmV1g1dTlONXNsVWtUU3VITVBwNG1MazJGYzB4ek1BSjdFbjFRVnBZQm9EQ1JyaGx4aHVwd0EiLCJtYWMiOiJkYTNmMjYxY2E0NDg4NWMxMDQ3NTliNDQwYzY2ODJkNDQ3OGNmOGM1YTE3MTRjNjEzZTZlOWY3ZjY2MDM5MmQ2IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6IlRIUkYyR3k0RXlUSW55ajRpd09vNEE9PSIsInZhbHVlIjoiWjRpRkFFdk9rcVpxTUZIY2U0Ymxsa0NFenkrM3Q2YzIrN0p5YzFYa1pRVmF4a2xBeHdBaCtodmY0eEVzeTJRaWZ3ZDByRW56N0Y0SnRZVXZhTHVHSzNEVERPNFVDajhEdDI5czhlS0liN2lTcStya1lxc1h1cG1pOHJLNlErNzEiLCJtYWMiOiJhZTdmZTFhMWVkZjZkYjNmNmFiYmZhOTlhYzU2ZWFhNmUxMmE4YjUwNzQ3NzA3MDU3YzA0NTFmM2Q2ZTcwNjU3IiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 


 

Request      

GET api/download/book/{author_slug}/{book_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: dumas-alexandre

book_slug  string  

slug of book in meta.slug books' list, example: le-collier-de-la-reine-tome-1-novel-fr

format  string optional  

Format for Book or Book[], if null get first format available if format not exist return 404, to have a format list, check api.entities.enums.

GET Book[] belongs to Author.

Content-Type application/octet-stream

Download Author ZIP.

Route name: api.download.author

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/download/author/hawthorne-nathaniel/epub" \
    --header "Content-Type: application/octet-stream" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/download/author/hawthorne-nathaniel/epub"
);

const headers = {
    "Content-Type": "application/octet-stream",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/download/author/hawthorne-nathaniel/epub',
    [
        'headers' => [
            'Content-Type' => 'application/octet-stream',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
content-disposition: attachment; filename="hawthorne-nathaniel-ewhi6q3y.zip"
content-type: application/octet-stream
cache-control: no-cache, private
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6InlmNFJsZXg5OXo5bjgrZUx3ei9yZVE9PSIsInZhbHVlIjoiTU1oYUpXeXFQTCsrTktUWmJpRUtkR1FMd2dVenk2OVFKSldrV3NwcFN1bHN4OU1uOU9KS21NOTlNY0gvYUFzN3BPMlQ2aWJqRlpxeGkxalRUVjVZNFIveGdtRHQrUnN5R3paSURMZE5QcGpaZjJ2NEJWQzA5bXBmV2NoTHQvUmwiLCJtYWMiOiJmODJjM2NhOGExMDA4ZTU3ZDM0OTBkNTA3YmUxYzdmNWI3Mzc1NTYwMTZlODAzZjI0NzI4OGZhNzYxY2NhOGIyIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6Ik1yVkdkeFBGd05tYTUrT3pVb3ZmbEE9PSIsInZhbHVlIjoiL2JYbVdHclJqdXN3U3dDbXBVYTRoZ0x5M3NMSU9STFNBUkk0TXFyZlBGUkVVMHJ1K05TS0RQMllxZ3FFWVdxVFdZeHM4cnpxd3ZGb09hZE9YNXFZc0g3YlZwR1QxcjRldk1FaXZJV2c0SElLd204ek5Idjk4d2NHTUpiVU1RVlYiLCJtYWMiOiJlYjQxYTkyYzUzMDFmNDU4ZDIxNzdiOGQ4ZGM1OThlNGQ3ZDFhODFlOGVmN2U5NWUxODdlZDdhNDU2YmYwYjBhIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 


 

Request      

GET api/download/author/{author_slug}/{format?}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: hawthorne-nathaniel

format  string optional  

Format for Book or Book[], if null get first format available if format not exist return 404, to have a format list, check api.entities.enums.

GET Book[] belongs to Serie.

Content-Type application/octet-stream

Download Serie ZIP.

Route name: api.download.serie

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/download/serie/dumas-alexandre/le-collier-de-la-reine-novel-fr/epub" \
    --header "Content-Type: application/octet-stream" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/download/serie/dumas-alexandre/le-collier-de-la-reine-novel-fr/epub"
);

const headers = {
    "Content-Type": "application/octet-stream",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/download/serie/dumas-alexandre/le-collier-de-la-reine-novel-fr/epub',
    [
        'headers' => [
            'Content-Type' => 'application/octet-stream',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
content-disposition: attachment; filename="dumas-alexandre-le-collier-de-la-reine-novel-fr-osi5psku.zip"
content-type: application/octet-stream
cache-control: no-cache, private
vary: Origin
set-cookie: XSRF-TOKEN=eyJpdiI6Imc1dkJlcWJBams5QjRWdFYyMFVZYWc9PSIsInZhbHVlIjoidkh1S1lXS1pkVElNdXZkNXkvcy92Ry9obTJ1cGF3U3NVYjF0WUhQV1ZlZnAzY2RPeCs4eGwrWmRsbWswbDYrVXdtNjNHNVRkN0VKSkdkWVFsUWxRSURxOU9BKzR1RXVielRLdmM0ZEdNN2p6bzR2Qy9BcW80QmJiWlRwTXdmYlgiLCJtYWMiOiJkNWMwOWRkZWRiYTk2NGU5MWIyNTVhMDFhZmMyMjRiM2FjODE2ZjRiOTEwNWYyM2RkZGYxZmRlNzExMDNiNzYzIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; samesite=lax; bookshelves_session=eyJpdiI6IjEyOW44b2hxaFJvZDduRE55bjRxWEE9PSIsInZhbHVlIjoieWh0RFh5T0lpdWZPOVVzU2xhUi83dE5KQ1daVFh3amFrMk96dG54Sjk2WDk1ajRLSHpYSllJQ3VvM3oxbzFVNEVubzZGUExwN0o2UE9BalRPNlFjZTZvQkZxNVBGQ0pXTDhIMGgvWktCMDRaaWVTbVB1ckRkWWJ0c01FbWxabjQiLCJtYWMiOiI5ZjkxZDk2ZDdjM2U3NGViM2EwNjViZTEzOTU1Yzg0MzFiMWRmZDUxODRhMmZiMmMzN2MzOTVhMTk0NGQ4ODVjIiwidGFnIjoiIn0%3D; expires=Sat, 07-May-2022 20:25:16 GMT; Max-Age=86400; path=/; domain=.bookshelves.ink; httponly; samesite=lax
 


 

Request      

GET api/download/serie/{author_slug}/{serie_slug}/{format?}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: dumas-alexandre

serie_slug  string  

slug of serie in meta.slug series' list, example: le-collier-de-la-reine-novel-fr

format  string optional  

Format for Book or Book[], if null get first format available if format not exist return 404, to have a format list, check api.entities.enums.

Entity: Author

Endpoint to get Authors data.

GET Author[].

WITH PAGINATION

Get all authors ordered by title & serie_title.

Route name: api.authors.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/authors?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/authors"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/authors',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4989
vary: Origin
 

{
    "data": [
        {
            "name": "Andersen Hans Christian",
            "meta": {
                "entity": "author",
                "slug": "andersen-hans-christian",
                "show": "https://bookshelves.ink/api/authors/andersen-hans-christian"
            },
            "lastname": "Andersen",
            "firstname": "Hans Christian",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/479/conversions/andersen-hans-christian-thumbnail.webp",
                "og": "https://bookshelves.ink/storage/media/covers/479/conversions/andersen-hans-christian-og.jpg",
                "simple": "https://bookshelves.ink/storage/media/covers/479/conversions/andersen-hans-christian-simple.jpg",
                "color": "#a18667"
            },
            "count": {
                "books": 1,
                "series": 0
            }
        },
        {
            "name": "Apollinaire Guillaume",
            "meta": {
                "entity": "author",
                "slug": "apollinaire-guillaume",
                "show": "https://bookshelves.ink/api/authors/apollinaire-guillaume"
            },
            "lastname": "Apollinaire",
            "firstname": "Guillaume",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/480/conversions/apollinaire-guillaume-thumbnail.webp",
                "og": "https://bookshelves.ink/storage/media/covers/480/conversions/apollinaire-guillaume-og.jpg",
                "simple": "https://bookshelves.ink/storage/media/covers/480/conversions/apollinaire-guillaume-simple.jpg",
                "color": "#a7a7a7"
            },
            "count": {
                "books": 1,
                "series": 0
            }
        },
        {
            "name": "Austen Jane",
            "meta": {
                "entity": "author",
                "slug": "austen-jane",
                "show": "https://bookshelves.ink/api/authors/austen-jane"
            },
            "lastname": "Austen",
            "firstname": "Jane",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/481/conversions/austen-jane-thumbnail.webp",
                "og": "https://bookshelves.ink/storage/media/covers/481/conversions/austen-jane-og.jpg",
                "simple": "https://bookshelves.ink/storage/media/covers/481/conversions/austen-jane-simple.jpg",
                "color": "#dbd2cc"
            },
            "count": {
                "books": 1,
                "series": 0
            }
        },
        {
            "name": "Carroll Lewis",
            "meta": {
                "entity": "author",
                "slug": "carroll-lewis",
                "show": "https://bookshelves.ink/api/authors/carroll-lewis"
            },
            "lastname": "Carroll",
            "firstname": "Lewis",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/482/conversions/carroll-lewis-thumbnail.webp",
                "og": "https://bookshelves.ink/storage/media/covers/482/conversions/carroll-lewis-og.jpg",
                "simple": "https://bookshelves.ink/storage/media/covers/482/conversions/carroll-lewis-simple.jpg",
                "color": "#58493e"
            },
            "count": {
                "books": 1,
                "series": 0
            }
        },
        {
            "name": "Darwin Charles",
            "meta": {
                "entity": "author",
                "slug": "darwin-charles",
                "show": "https://bookshelves.ink/api/authors/darwin-charles"
            },
            "lastname": "Darwin",
            "firstname": "Charles",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/483/conversions/darwin-charles-thumbnail.webp",
                "og": "https://bookshelves.ink/storage/media/covers/483/conversions/darwin-charles-og.jpg",
                "simple": "https://bookshelves.ink/storage/media/covers/483/conversions/darwin-charles-simple.jpg",
                "color": "#5c5c5c"
            },
            "count": {
                "books": 1,
                "series": 0
            }
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/authors?page=1",
        "last": "https://bookshelves.ink/api/authors?page=6",
        "prev": null,
        "next": "https://bookshelves.ink/api/authors?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 6,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=2",
                "label": "2",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=3",
                "label": "3",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=4",
                "label": "4",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=5",
                "label": "5",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=6",
                "label": "6",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors?page=2",
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/authors",
        "per_page": 5,
        "to": 5,
        "total": 26
    }
}
 

Request      

GET api/authors

Query Parameters

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

Response

Response Fields

data  object[]  

List of authors.

links  object  

Links to get other pages.

meta  object  

Metadata about pagination.

GET Author.

Details for one Author, find by slug.

Route name: api.authors.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/authors/vian-boris" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/authors/vian-boris"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/authors/vian-boris',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4988
vary: Origin
 

{
    "data": {
        "name": "Vian Boris",
        "meta": {
            "entity": "author",
            "slug": "vian-boris",
            "show": "https://bookshelves.ink/api/authors/vian-boris",
            "books": "https://bookshelves.ink/api/authors/books/vian-boris",
            "series": "https://bookshelves.ink/api/authors/series/vian-boris",
            "reviews": "https://bookshelves.ink/api/entities/reviews/author/21"
        },
        "lastname": "Vian",
        "firstname": "Boris",
        "cover": {
            "thumbnail": "https://bookshelves.ink/storage/media/covers/499/conversions/vian-boris-thumbnail.webp",
            "og": "https://bookshelves.ink/storage/media/covers/499/conversions/vian-boris-og.jpg",
            "simple": "https://bookshelves.ink/storage/media/covers/499/conversions/vian-boris-simple.jpg",
            "color": "#3f3d3c"
        },
        "count": {
            "books": 10,
            "series": 0
        },
        "description": "Boris Vian, né le 10 mars 1920 à Ville-d'Avray (Hauts-de-Seine) et mort le 23 juin 1959 à Paris (7e arrondissement), est un écrivain, poète, parolier, chanteur, critique musical, musicien de jazz (trompettiste) et directeur artistique français. Ingénieur formé à l'École centrale, il s'est aussi adonné aux activités de scénariste, de traducteur (anglais américain), de conférencier, d'acteur et de peintre.\nSous le pseudonyme Vernon Sullivan, il a publié plusieurs romans dans le style américain, parmi lesquels J'irai cracher sur vos tombes qui a fait scandale et lui valut un procès retentissant. Si les écrits de Vernon Sullivan ont attiré à Boris Vian beaucoup d'ennuis avec la justice et le fisc, ils l'ont momentanément enrichi à tel point qu'il pouvait dire que Vernon Sullivan faisait vivre Boris Vian. Il a souvent utilisé d'autres pseudonymes, parfois sous la forme d'une anagramme, pour signer une multitude d'écrits.\nBoris Vian a abordé à peu près tous les genres littéraires : poésie, d...",
        "link": "https://fr.wikipedia.org/wiki/Boris_Vian",
        "download": {
            "name": "vian-boris",
            "size": "2.95 Mo",
            "url": "https://bookshelves.ink/api/download/author/vian-boris/epub",
            "reader": null,
            "format": "epub",
            "count": 10,
            "isZip": true
        },
        "files": {
            "pdf": null,
            "cbr": null,
            "cbz": null,
            "epub": {
                "name": "vian-boris",
                "size": "2.95 Mo",
                "url": "https://bookshelves.ink/api/download/author/vian-boris/epub",
                "reader": null,
                "format": "epub",
                "count": 10,
                "isZip": true
            }
        },
        "isFavorite": false,
        "reviews": []
    }
}
 

Request      

GET api/authors/{author_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: vian-boris

GET Book[] belongs to Author.

Books list from an author, find by slug.

Route name: api.authors.show.books

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/authors/books/voltaire?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/authors/books/voltaire"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/authors/books/voltaire',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4987
vary: Origin
 

{
    "data": [
        {
            "title": "Candide ou l'optimisme",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "candide-ou-loptimisme-novel-fr",
                "author": "voltaire",
                "show": "https://bookshelves.ink/api/books/voltaire/candide-ou-loptimisme-novel-fr"
            },
            "authors": [
                {
                    "name": "Voltaire ",
                    "meta": {
                        "entity": "author",
                        "slug": "voltaire",
                        "show": "https://bookshelves.ink/api/authors/voltaire"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2015-07-14T22:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/398/conversions/candide-ou-loptimisme-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/398/conversions/candide-ou-loptimisme-novel-fr-simple.jpg",
                "color": "#6c776a"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "Micromégas",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "micromegas-novel-fr",
                "author": "voltaire",
                "show": "https://bookshelves.ink/api/books/voltaire/micromegas-novel-fr"
            },
            "authors": [
                {
                    "name": "Voltaire ",
                    "meta": {
                        "entity": "author",
                        "slug": "voltaire",
                        "show": "https://bookshelves.ink/api/authors/voltaire"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2015-08-09T22:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/400/conversions/micromegas-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/400/conversions/micromegas-novel-fr-simple.jpg",
                "color": "#505d6c"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "Zadig ou La Destinée Orientale",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "zadig-ou-la-destinee-orientale-novel-fr",
                "author": "voltaire",
                "show": "https://bookshelves.ink/api/books/voltaire/zadig-ou-la-destinee-orientale-novel-fr"
            },
            "authors": [
                {
                    "name": "Voltaire ",
                    "meta": {
                        "entity": "author",
                        "slug": "voltaire",
                        "show": "https://bookshelves.ink/api/authors/voltaire"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2014-03-08T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/402/conversions/zadig-ou-la-destinee-orientale-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/402/conversions/zadig-ou-la-destinee-orientale-novel-fr-simple.jpg",
                "color": "#88736c"
            },
            "volume": null,
            "serie": null
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/authors/books/voltaire?page=1",
        "last": "https://bookshelves.ink/api/authors/books/voltaire?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors/books/voltaire?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/authors/books/voltaire",
        "per_page": 32,
        "to": 3,
        "total": 3
    }
}
 

Request      

GET api/authors/books/{author_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: voltaire

Query Parameters

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

GET Serie[] belongs to Author.

Series list from an author, find by slug.

Route name: api.authors.show.series

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/authors/series/virgile?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/authors/series/virgile"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/authors/series/virgile',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4986
vary: Origin
 

{
    "data": [],
    "links": {
        "first": "https://bookshelves.ink/api/authors/series/virgile?page=1",
        "last": "https://bookshelves.ink/api/authors/series/virgile?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": null,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/authors/series/virgile?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/authors/series/virgile",
        "per_page": 32,
        "to": null,
        "total": 0
    }
}
 

Request      

GET api/authors/series/{author_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: virgile

Query Parameters

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

Entity: Book

GET Book[].

WITH PAGINATION

Get all Books ordered by title & serie_title.

Route name: api.books.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/books?filter[languages]=en%2Cfr&sort=slug_sort&size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/books"
);

const params = {
    "filter[languages]": "en,fr",
    "sort": "slug_sort",
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/books',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[languages]'=> 'en,fr',
            'sort'=> 'slug_sort',
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4985
vary: Origin
 

{
    "data": [
        {
            "title": "20000 lieues sous les mers",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "20000-lieues-sous-les-mers-novel-fr",
                "author": "verne-jules",
                "show": "https://bookshelves.ink/api/books/verne-jules/20000-lieues-sous-les-mers-novel-fr"
            },
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "1871-04-14T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/268/conversions/20000-lieues-sous-les-mers-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/268/conversions/20000-lieues-sous-les-mers-novel-fr-simple.jpg",
                "color": "#9e9c9d"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "À la recherche du temps perdu",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "a-la-recherche-du-temps-perdu-novel-en",
                "author": "proust-marcel",
                "show": "https://bookshelves.ink/api/books/proust-marcel/a-la-recherche-du-temps-perdu-novel-en"
            },
            "authors": [
                {
                    "name": "Proust Marcel",
                    "meta": {
                        "entity": "author",
                        "slug": "proust-marcel",
                        "show": "https://bookshelves.ink/api/authors/proust-marcel"
                    }
                }
            ],
            "language": {
                "name": "English",
                "meta": {
                    "slug": "en"
                }
            },
            "releasedOn": "1921-04-14T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/258/conversions/a-la-recherche-du-temps-perdu-novel-en-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/258/conversions/a-la-recherche-du-temps-perdu-novel-en-simple.jpg",
                "color": "#b7a084"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "À l'ombre des jeunes filles en fleurs",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "a-lombre-des-jeunes-filles-en-fleurs-novel-fr",
                "author": "proust-marcel",
                "show": "https://bookshelves.ink/api/books/proust-marcel/a-lombre-des-jeunes-filles-en-fleurs-novel-fr"
            },
            "authors": [
                {
                    "name": "Proust Marcel",
                    "meta": {
                        "entity": "author",
                        "slug": "proust-marcel",
                        "show": "https://bookshelves.ink/api/authors/proust-marcel"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2016-12-29T00:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/256/conversions/a-lombre-des-jeunes-filles-en-fleurs-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/256/conversions/a-lombre-des-jeunes-filles-en-fleurs-novel-fr-simple.jpg",
                "color": "#b09574"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "Adventures of Huckleberry Finn",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "adventures-of-huckleberry-finn-novel-en",
                "author": "twain-mark",
                "show": "https://bookshelves.ink/api/books/twain-mark/adventures-of-huckleberry-finn-novel-en"
            },
            "authors": [
                {
                    "name": "Twain Mark",
                    "meta": {
                        "entity": "author",
                        "slug": "twain-mark",
                        "show": "https://bookshelves.ink/api/authors/twain-mark"
                    }
                }
            ],
            "language": {
                "name": "English",
                "meta": {
                    "slug": "en"
                }
            },
            "releasedOn": "2012-08-02T10:51:55.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/266/conversions/adventures-of-huckleberry-finn-novel-en-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/266/conversions/adventures-of-huckleberry-finn-novel-en-simple.jpg",
                "color": "#94b4ae"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "L'Affaire Charles Dexter Ward",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "laffaire-charles-dexter-ward-novel-fr",
                "author": "lovecraft-howard-phillips",
                "show": "https://bookshelves.ink/api/books/lovecraft-howard-phillips/laffaire-charles-dexter-ward-novel-fr"
            },
            "authors": [
                {
                    "name": "Lovecraft Howard Phillips",
                    "meta": {
                        "entity": "author",
                        "slug": "lovecraft-howard-phillips",
                        "show": "https://bookshelves.ink/api/authors/lovecraft-howard-phillips"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "1928-04-14T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/238/conversions/laffaire-charles-dexter-ward-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/238/conversions/laffaire-charles-dexter-ward-novel-fr-simple.jpg",
                "color": "#2d1912"
            },
            "volume": null,
            "serie": null
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/books?page=1",
        "last": "https://bookshelves.ink/api/books?page=40",
        "prev": null,
        "next": "https://bookshelves.ink/api/books?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 40,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": "https://bookshelves.ink/api/books?page=2",
                "label": "2",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=3",
                "label": "3",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=4",
                "label": "4",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=5",
                "label": "5",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=6",
                "label": "6",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=7",
                "label": "7",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=8",
                "label": "8",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=9",
                "label": "9",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=10",
                "label": "10",
                "active": false
            },
            {
                "url": null,
                "label": "...",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=39",
                "label": "39",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=40",
                "label": "40",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/books?page=2",
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/books",
        "per_page": 5,
        "to": 5,
        "total": 198
    }
}
 

Request      

GET api/books

Query Parameters

filter[languages]  string optional  

Filter by language, meta.slug from languages' list, null by default.

sort  string optional  

Sorting slug_sort by default, available: title, slug_sort, date, created_at, you can use - before parameter to reverse like -slug_sort.

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

Response

Response Fields

data  object[]  

List of books.

links  object  

Links to get other pages.

meta  object  

Metadata about pagination.

GET Book.

Route name: api.books.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/books/dumas-alexandre/les-trois-mousquetaires-novel-fr" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/books/dumas-alexandre/les-trois-mousquetaires-novel-fr"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/books/dumas-alexandre/les-trois-mousquetaires-novel-fr',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4984
vary: Origin
 

{
    "data": {
        "title": "Les Trois Mousquetaires",
        "type": "Novel",
        "meta": {
            "entity": "book",
            "slug": "les-trois-mousquetaires-novel-fr",
            "author": "dumas-alexandre",
            "show": "https://bookshelves.ink/api/books/dumas-alexandre/les-trois-mousquetaires-novel-fr",
            "related": "https://bookshelves.ink/api/entities/related/dumas-alexandre/les-trois-mousquetaires-novel-fr",
            "reviews": "https://bookshelves.ink/api/entities/reviews/book/70"
        },
        "authors": [
            {
                "name": "Dumas Alexandre",
                "meta": {
                    "entity": "author",
                    "slug": "dumas-alexandre",
                    "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                }
            }
        ],
        "language": {
            "name": "French",
            "meta": {
                "slug": "fr"
            }
        },
        "releasedOn": "2011-01-14T23:00:00.000000Z",
        "cover": {
            "thumbnail": "https://bookshelves.ink/storage/media/covers/199/conversions/les-trois-mousquetaires-novel-fr-thumbnail.webp",
            "og": "https://bookshelves.ink/storage/media/covers/199/conversions/les-trois-mousquetaires-novel-fr-og.jpg",
            "simple": "https://bookshelves.ink/storage/media/covers/199/conversions/les-trois-mousquetaires-novel-fr-simple.jpg",
            "original": "https://bookshelves.ink/storage/media/covers/199/les-trois-mousquetaires-novel-fr.webp",
            "color": "#dfd6d2"
        },
        "volume": 1,
        "serie": {
            "title": "Les Trois Mousquetaires",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "les-trois-mousquetaires-novel-fr",
                "author": "dumas-alexandre",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/les-trois-mousquetaires-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/477/conversions/les-trois-mousquetaires-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/477/conversions/les-trois-mousquetaires-novel-fr-simple.jpg",
                "color": "#dfd6d2"
            }
        },
        "description": "{\"fr\":\"\\u00c0 l'occasion de la com\\u00e9die musicale \\u00e9v\\u00e9nement de la rentr\\u00e9e 2016, re-d\\u00e9couvrez la fabuleuse aventure des ferrets de la Reine. Un ouvrage collector avec le texte original d'Alexandre Dumas et des bonus exclusifs ! Avril 1625, le jeune et valeureux d'Artagnan quitte sa Gascogne natale pour tenter d'int\\u00e9grer la garde rapproch\\u00e9e du Roi Louis XIII et faire fortune \\u00e0 Paris. D\\u00e8s son arriv\\u00e9e dans la capitale, d'Artagnan provoque bien malgr\\u00e9 lui les mousquetaires Athos, Porthos et Aramis en duel. Il heurte l'\\u00e9paule bless\\u00e9e d'Athos, marche sur la cape de Porthos et compromet malencontreusement Aramis avec un mouchoir aux mauvaises initiales. Les duels \\u00e9tant interdits par Richelieu, d'Artagnan et les mousquetaires se retrouvent hors la loi ; les gardes en profitent alors pour tenter de venger une vieille rivalit\\u00e9 qui les oppose aux trois gentilshommes. Mais contre toute attente, d'Artagnan s'allie aux mousquetaires et de ce combat victorieux na\\u00eet une amiti\\u00e9 in\\u00e9branlable.  Sur une suggestion de Richelieu, Louis XIII impose \\u00e0 la Reine de porter au prochain bal de la cour les douze ferrets de diamants offerts par le Roi. Or, le machiav\\u00e9lique Richelieu sait que la Reine a donn\\u00e9 la pr\\u00e9cieuse parure en gage d'amour au Duc, avec qui elle entretient une liaison secr\\u00e8te. Gr\\u00e2ce \\u00e0 la complicit\\u00e9 de la fid\\u00e8le ling\\u00e8re de la Reine, Constance, le quatuor sauve la Reine des man\\u0153uvres sournoises de Richelieu et de son agent, la perfide Milady, en se rendant \\u00e0 Londres pour r\\u00e9cup\\u00e9rer les ferrets. Au terme d'un parcours sem\\u00e9 d'emb\\u00fbches, d'Artagnan et ses trois acolytes Porthos, Athos et Aramis parviennent \\u00e0 remettre \\u00e0 temps les ferrets \\u00e0 la Reine. Promu Lieutenant, d'Artagnan et les trois mousquetaires r\\u00e9ussissent \\u00e0 pr\\u00e9server l'honneur du Royaume, port\\u00e9s par leur unique cr\\u00e9do : \\\"Un pour tous, tous pour un !\\\". 24 pages de bonus \\u2022Une pr\\u00e9face de Franck Ferrand qui pr\\u00e9sente l'\\u0153uvre et son contexte historique  \\u2022Les textes des chansons  \\u2022Un cahier photos en couleurs avec :  v La gen\\u00e8se du spectacle  v Les biographies des principaux com\\u00e9diens  v Des photos des com\\u00e9diens\"}",
        "identifier": {
            "isbn": "9782810420544",
            "isbn10": "2810420548",
            "isbn13": "9782810420544"
        },
        "pageCount": 233,
        "maturityRating": "NOT_MATURE",
        "publisher": {
            "name": "Ebooks libres et gratuits",
            "count": null,
            "firstChar": "E",
            "meta": {
                "slug": "ebooks-libres-et-gratuits",
                "books": "https://bookshelves.ink/api/publishers/books/ebooks-libres-et-gratuits",
                "show": "https://bookshelves.ink/api/publishers/ebooks-libres-et-gratuits"
            }
        },
        "tags": [
            {
                "name": "Fiction",
                "type": "tag",
                "count": null,
                "firstChar": null,
                "meta": {
                    "slug": "fiction",
                    "books": null,
                    "show": null
                }
            },
            {
                "name": "Classics",
                "type": "tag",
                "count": null,
                "firstChar": null,
                "meta": {
                    "slug": "classics",
                    "books": null,
                    "show": null
                }
            }
        ],
        "genres": [],
        "download": {
            "name": "dumas-alexandre-trois-mousquetaires-01-trois-mousquetaires-fr.epub",
            "size": "636.47 Ko",
            "url": "https://bookshelves.ink/api/download/book/dumas-alexandre/les-trois-mousquetaires-novel-fr?format=epub",
            "reader": "https://bookshelves.ink/webreader/dumas-alexandre/les-trois-mousquetaires-novel-fr?format=epub",
            "format": "epub",
            "count": null,
            "isZip": null
        },
        "files": {
            "pdf": null,
            "cbr": null,
            "cbz": null,
            "epub": {
                "name": "dumas-alexandre-trois-mousquetaires-01-trois-mousquetaires-fr.epub",
                "size": "636.47 Ko",
                "url": "https://bookshelves.ink/api/download/book/dumas-alexandre/les-trois-mousquetaires-novel-fr?format=epub",
                "reader": "https://bookshelves.ink/webreader/dumas-alexandre/les-trois-mousquetaires-novel-fr?format=epub",
                "format": "epub",
                "count": null,
                "isZip": null
            }
        },
        "googleBook": {
            "preview_link": "http://books.google.de/books?id=SqEbDQAAQBAJ&printsec=frontcover&dq=isbn:9782810420544&hl=&cd=1&source=gbs_api",
            "buy_link": "https://play.google.com/store/books/details?id=SqEbDQAAQBAJ&rdid=book-SqEbDQAAQBAJ&rdot=1&source=gbs_api",
            "created_at": "2022-04-17T08:35:03.000000Z"
        },
        "isFavorite": false,
        "reviewsCount": 0
    }
}
 

Request      

GET api/books/{author_slug}/{book_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: dumas-alexandre

book_slug  string  

slug of book in meta.slug books' list, example: les-trois-mousquetaires-novel-fr

Entity: Serie

Endpoint to get Series data.

GET Serie[].

WITH PAGINATION

Get all series ordered by title & serie_title.

Route name: api.series.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/series?filter[languages]=en%2Cfr&size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/series"
);

const params = {
    "filter[languages]": "en,fr",
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/series',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'filter[languages]'=> 'en,fr',
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4983
vary: Origin
 

{
    "data": [
        {
            "title": "L'Ami commun",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "lami-commun-novel-fr",
                "author": "dickens-charles",
                "show": "https://bookshelves.ink/api/series/dickens-charles/lami-commun-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dickens-charles/lami-commun-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/462/conversions/lami-commun-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/462/conversions/lami-commun-novel-fr-simple.jpg",
                "color": "#655360"
            },
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "count": 2
        },
        {
            "title": "Ange Pitou",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "ange-pitou-novel-fr",
                "author": "dumas-alexandre",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/ange-pitou-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dumas-alexandre/ange-pitou-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/466/conversions/ange-pitou-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/466/conversions/ange-pitou-novel-fr-simple.jpg",
                "color": "#9f8886"
            },
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "count": 2
        },
        {
            "title": "Aventures De Monsieur Pickwick",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "aventures-de-monsieur-pickwick-novel-fr",
                "author": "dickens-charles",
                "show": "https://bookshelves.ink/api/series/dickens-charles/aventures-de-monsieur-pickwick-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dickens-charles/aventures-de-monsieur-pickwick-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/458/conversions/aventures-de-monsieur-pickwick-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/458/conversions/aventures-de-monsieur-pickwick-novel-fr-simple.jpg",
                "color": "#573d1d"
            },
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "count": 1
        },
        {
            "title": "Barnabé Rudge",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "barnabe-rudge-novel-fr",
                "author": "dickens-charles",
                "show": "https://bookshelves.ink/api/series/dickens-charles/barnabe-rudge-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dickens-charles/barnabe-rudge-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/459/conversions/barnabe-rudge-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/459/conversions/barnabe-rudge-novel-fr-simple.jpg",
                "color": "#f7f1e2"
            },
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "authors": [
                {
                    "name": "Dickens Charles",
                    "meta": {
                        "entity": "author",
                        "slug": "dickens-charles",
                        "show": "https://bookshelves.ink/api/authors/dickens-charles"
                    }
                }
            ],
            "count": 2
        },
        {
            "title": "Les Blancs et les Bleus",
            "type": "Novel",
            "meta": {
                "entity": "serie",
                "slug": "les-blancs-et-les-bleus-novel-fr",
                "author": "dumas-alexandre",
                "show": "https://bookshelves.ink/api/series/dumas-alexandre/les-blancs-et-les-bleus-novel-fr",
                "books": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-blancs-et-les-bleus-novel-fr"
            },
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/475/conversions/les-blancs-et-les-bleus-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/475/conversions/les-blancs-et-les-bleus-novel-fr-simple.jpg",
                "color": "#98887d"
            },
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "count": 2
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/series?page=1",
        "last": "https://bookshelves.ink/api/series?page=5",
        "prev": null,
        "next": "https://bookshelves.ink/api/series?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 5,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": "https://bookshelves.ink/api/series?page=2",
                "label": "2",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series?page=3",
                "label": "3",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series?page=4",
                "label": "4",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series?page=5",
                "label": "5",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series?page=2",
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/series",
        "per_page": 5,
        "to": 5,
        "total": 21
    }
}
 

Request      

GET api/series

Query Parameters

filter[languages]  string optional  

To select specific lang, null by default.

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

Response

Response Fields

data  object[]  

List of series.

links  object  

Links to get other pages.

meta  object  

Metadata about pagination.

GET Serie.

Get details of Serie model, find by slug of serie and slug of author.

Route name: api.series.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/series/dumas-alexandre/la-reine-margot-novel-fr" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/series/dumas-alexandre/la-reine-margot-novel-fr"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/series/dumas-alexandre/la-reine-margot-novel-fr',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4982
vary: Origin
 

{
    "data": {
        "title": "La Reine Margot",
        "type": "Novel",
        "meta": {
            "entity": "serie",
            "slug": "la-reine-margot-novel-fr",
            "author": "dumas-alexandre",
            "show": "https://bookshelves.ink/api/series/dumas-alexandre/la-reine-margot-novel-fr",
            "books": "https://bookshelves.ink/api/series/books/dumas-alexandre/la-reine-margot-novel-fr",
            "reviews": "https://bookshelves.ink/api/entities/reviews/serie/14"
        },
        "cover": {
            "thumbnail": "https://bookshelves.ink/storage/media/covers/471/conversions/la-reine-margot-novel-fr-thumbnail.webp",
            "og": "https://bookshelves.ink/storage/media/covers/471/conversions/la-reine-margot-novel-fr-og.jpg",
            "simple": "https://bookshelves.ink/storage/media/covers/471/conversions/la-reine-margot-novel-fr-simple.jpg",
            "color": "#5a3f20"
        },
        "language": {
            "name": "French",
            "meta": {
                "slug": "fr"
            }
        },
        "authors": [
            {
                "name": "Dumas Alexandre",
                "meta": {
                    "entity": "author",
                    "slug": "dumas-alexandre",
                    "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                }
            }
        ],
        "count": 2,
        "description": "La Reine Margot est un roman écrit par Alexandre Dumas. Sorti en 1845, il a été publié initialement dans le quotidien La Presse en roman-feuilleton entre le 25 décembre 1844 et le 5 avril 1845. Alexandre Dumas en a tiré un drame du même nom, représenté en 1847. Deux romans font suite à La Reine Margot : La Dame de Monsoreau et Les Quarante-cinq, formant ainsi ce qu'on appelle parfois la « trilogie des Valois ». Contexte historique\nL'action du roman se déroule entre le mariage de Marguerite de Valois avec Henri de Navarre, futur Henri IV, en 1572 et la mort de Charles IX de France en 1574.\nAlexandre Dumas y met en scène les intrigues de cour, l'assassinat de l'amiral de Coligny, le massacre de la Saint-Barthélemy, l'idylle inventée entre la reine de Navarre et le comte de la Mole ainsi que la pratique de la torture judiciaire à la Renaissance. Il fait de Catherine de Médicis une figure inquiétante, qui se sert de son astrologue et parfumeur florentin René Bianchi pour faire assassiner s...",
        "link": "https://fr.wikipedia.org/wiki/La_Reine_Margot",
        "tags": [
            {
                "name": "Fiction",
                "type": "tag",
                "count": null,
                "firstChar": null,
                "meta": {
                    "slug": "fiction",
                    "books": null,
                    "show": null
                }
            },
            {
                "name": "Historical",
                "type": "tag",
                "count": null,
                "firstChar": null,
                "meta": {
                    "slug": "historical",
                    "books": null,
                    "show": null
                }
            },
            {
                "name": "Romans   historique",
                "type": "tag",
                "count": null,
                "firstChar": null,
                "meta": {
                    "slug": "romans-historique",
                    "books": null,
                    "show": null
                }
            }
        ],
        "genres": [],
        "download": {
            "name": "la-reine-margot-novel-fr",
            "size": "616.55 Ko",
            "url": "https://bookshelves.ink/api/download/serie/dumas-alexandre/la-reine-margot-novel-fr/epub",
            "reader": null,
            "format": "epub",
            "count": 2,
            "isZip": true
        },
        "files": {
            "pdf": null,
            "cbr": null,
            "cbz": null,
            "epub": {
                "name": "la-reine-margot-novel-fr",
                "size": "616.55 Ko",
                "url": "https://bookshelves.ink/api/download/serie/dumas-alexandre/la-reine-margot-novel-fr/epub",
                "reader": null,
                "format": "epub",
                "count": 2,
                "isZip": true
            }
        },
        "isFavorite": false,
        "reviews": []
    }
}
 

Request      

GET api/series/{author_slug}/{serie_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: dumas-alexandre

serie_slug  string  

slug of serie in meta.slug series' list, example: la-reine-margot-novel-fr

GET Book[] belongs to Serie.

Books list from one Serie, find by slug.

Route name: api.series.show.books

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4981
vary: Origin
 

{
    "data": [
        {
            "title": "Les Trois Mousquetaires",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "les-trois-mousquetaires-novel-fr",
                "author": "dumas-alexandre",
                "show": "https://bookshelves.ink/api/books/dumas-alexandre/les-trois-mousquetaires-novel-fr"
            },
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2011-01-14T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/199/conversions/les-trois-mousquetaires-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/199/conversions/les-trois-mousquetaires-novel-fr-simple.jpg",
                "color": "#dfd6d2"
            },
            "volume": 1,
            "serie": {
                "title": "Les Trois Mousquetaires",
                "meta": {
                    "entity": "serie",
                    "slug": "les-trois-mousquetaires-novel-fr",
                    "author": "dumas-alexandre",
                    "show": "https://bookshelves.ink/api/series/dumas-alexandre/les-trois-mousquetaires-novel-fr"
                }
            }
        },
        {
            "title": "Vingt ans après",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "vingt-ans-apres-novel-fr",
                "author": "dumas-alexandre",
                "show": "https://bookshelves.ink/api/books/dumas-alexandre/vingt-ans-apres-novel-fr"
            },
            "authors": [
                {
                    "name": "Dumas Alexandre",
                    "meta": {
                        "entity": "author",
                        "slug": "dumas-alexandre",
                        "show": "https://bookshelves.ink/api/authors/dumas-alexandre"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2011-01-14T23:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/201/conversions/vingt-ans-apres-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/201/conversions/vingt-ans-apres-novel-fr-simple.jpg",
                "color": "#404b4d"
            },
            "volume": 2,
            "serie": {
                "title": "Les Trois Mousquetaires",
                "meta": {
                    "entity": "serie",
                    "slug": "les-trois-mousquetaires-novel-fr",
                    "author": "dumas-alexandre",
                    "show": "https://bookshelves.ink/api/series/dumas-alexandre/les-trois-mousquetaires-novel-fr"
                }
            }
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr?page=1",
        "last": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/series/books/dumas-alexandre/les-trois-mousquetaires-novel-fr",
        "per_page": 5,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/series/books/{author_slug}/{serie_slug}

URL Parameters

author_slug  string  

slug of author in meta.author books' list, in case of multiple authors, default author is selected so you need to refer to books' list and not authors' list, example: dumas-alexandre

serie_slug  string  

slug of serie in meta.slug series' list, example: les-trois-mousquetaires-novel-fr

Query Parameters

next  integer optional  

Volume to select next Book[] after.

first  boolean optional  

To select only first Book with next.

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

Relation: Language

Endpoint to get Languages data.

GET Language[].

Route name: api.languages.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/languages" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/languages"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/languages',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4973
vary: Origin
 

{
    "data": [
        {
            "name": "French",
            "meta": {
                "slug": "fr",
                "show": "https://bookshelves.ink/api/languages/fr"
            },
            "firstChar": "F",
            "count": 187
        },
        {
            "name": "English",
            "meta": {
                "slug": "en",
                "show": "https://bookshelves.ink/api/languages/en"
            },
            "firstChar": "E",
            "count": 11
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/languages?page=1",
        "last": "https://bookshelves.ink/api/languages?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/languages?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/languages",
        "per_page": 32,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/languages

GET Language.

Route name: api.languages.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/languages/en" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/languages/en"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/languages/en',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4972
vary: Origin
 

{
    "data": {
        "name": "English",
        "meta": {
            "slug": "en",
            "show": "https://bookshelves.ink/api/languages/en"
        },
        "firstChar": "E",
        "count": null
    }
}
 

Request      

GET api/languages/{language_slug}

URL Parameters

language_slug  string  

slug of serie in meta.slug languages' list, example: en

Relation: Publisher

Endpoint to get Publishers data.

GET Publisher[].

WITH PAGINATION

Get all Publishers ordered by 'name'.

Route name: api.publishers.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/publishers" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/publishers"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/publishers',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4976
vary: Origin
 

{
    "data": [
        {
            "name": "Arvensa editions",
            "count": 4,
            "firstChar": "A",
            "meta": {
                "slug": "arvensa-editions",
                "books": "https://bookshelves.ink/api/publishers/books/arvensa-editions",
                "show": "https://bookshelves.ink/api/publishers/arvensa-editions"
            }
        },
        {
            "name": "BoD - Books on Demand",
            "count": 7,
            "firstChar": "B",
            "meta": {
                "slug": "bod-books-on-demand",
                "books": "https://bookshelves.ink/api/publishers/books/bod-books-on-demand",
                "show": "https://bookshelves.ink/api/publishers/bod-books-on-demand"
            }
        },
        {
            "name": "Ebooks libres et gratuits",
            "count": 75,
            "firstChar": "E",
            "meta": {
                "slug": "ebooks-libres-et-gratuits",
                "books": "https://bookshelves.ink/api/publishers/books/ebooks-libres-et-gratuits",
                "show": "https://bookshelves.ink/api/publishers/ebooks-libres-et-gratuits"
            }
        },
        {
            "name": "Feedbooks",
            "count": 20,
            "firstChar": "F",
            "meta": {
                "slug": "feedbooks",
                "books": "https://bookshelves.ink/api/publishers/books/feedbooks",
                "show": "https://bookshelves.ink/api/publishers/feedbooks"
            }
        },
        {
            "name": "Independently Published",
            "count": 7,
            "firstChar": "I",
            "meta": {
                "slug": "independently-published",
                "books": "https://bookshelves.ink/api/publishers/books/independently-published",
                "show": "https://bookshelves.ink/api/publishers/independently-published"
            }
        },
        {
            "name": "J'ai lu",
            "count": 3,
            "firstChar": "J",
            "meta": {
                "slug": "jai-lu",
                "books": "https://bookshelves.ink/api/publishers/books/jai-lu",
                "show": "https://bookshelves.ink/api/publishers/jai-lu"
            }
        },
        {
            "name": "La Gibecière à Mots",
            "count": 4,
            "firstChar": "L",
            "meta": {
                "slug": "la-gibeciere-a-mots",
                "books": "https://bookshelves.ink/api/publishers/books/la-gibeciere-a-mots",
                "show": "https://bookshelves.ink/api/publishers/la-gibeciere-a-mots"
            }
        },
        {
            "name": "Le Livre de Poche",
            "count": 12,
            "firstChar": "L",
            "meta": {
                "slug": "le-livre-de-poche",
                "books": "https://bookshelves.ink/api/publishers/books/le-livre-de-poche",
                "show": "https://bookshelves.ink/api/publishers/le-livre-de-poche"
            }
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/publishers?page=1",
        "last": "https://bookshelves.ink/api/publishers?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/publishers?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/publishers",
        "per_page": 32,
        "to": 8,
        "total": 8
    }
}
 

Request      

GET api/publishers

Query Parameters

size  integer optional  

Entities per page, '32' by default.

full  boolean optional  

Disable pagination.

page  integer optional  

The page number, '1' by default.

GET Publisher.

Details for one Publisher, find by slug.

Route name: api.publishers.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/publishers/primento" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/publishers/primento"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/publishers/primento',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4975
vary: Origin
 

{
    "data": {
        "name": "Primento",
        "count": 1,
        "firstChar": "P",
        "meta": {
            "slug": "primento",
            "books": "https://bookshelves.ink/api/publishers/books/primento",
            "show": "https://bookshelves.ink/api/publishers/primento"
        }
    }
}
 

Request      

GET api/publishers/{publisher_slug}

URL Parameters

publisher_slug  string  

slug of serie in meta.slug publishers' list, example: primento

GET Book[] belongs to Publisher.

WITH PAGINATION

Get all Books of selected Publisher ordered by Books' 'title'.

Route name: api.publishers.show.books

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4974
vary: Origin
 

{
    "data": [
        {
            "title": "Face au drapeau",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "face-au-drapeau-novel-fr",
                "author": "verne-jules",
                "show": "https://bookshelves.ink/api/books/verne-jules/face-au-drapeau-novel-fr"
            },
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2015-03-27T00:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/286/conversions/face-au-drapeau-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/286/conversions/face-au-drapeau-novel-fr-simple.jpg",
                "color": "#95986f"
            },
            "volume": null,
            "serie": null
        },
        {
            "title": "L'Etonnante Aventure de la mission Barsac",
            "type": "Novel",
            "meta": {
                "entity": "book",
                "slug": "letonnante-aventure-de-la-mission-barsac-novel-fr",
                "author": "verne-jules",
                "show": "https://bookshelves.ink/api/books/verne-jules/letonnante-aventure-de-la-mission-barsac-novel-fr"
            },
            "authors": [
                {
                    "name": "Verne Jules",
                    "meta": {
                        "entity": "author",
                        "slug": "verne-jules",
                        "show": "https://bookshelves.ink/api/authors/verne-jules"
                    }
                }
            ],
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "releasedOn": "2015-04-02T00:00:00.000000Z",
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/302/conversions/letonnante-aventure-de-la-mission-barsac-novel-fr-thumbnail.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/302/conversions/letonnante-aventure-de-la-mission-barsac-novel-fr-simple.jpg",
                "color": "#838f65"
            },
            "volume": null,
            "serie": null
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform?page=1",
        "last": "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/publishers/books/createspace-independent-publishing-platform",
        "per_page": 32,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/publishers/books/{publisher_slug}

URL Parameters

publisher_slug  string  

slug of serie in meta.slug publishers' list, example: createspace-independent-publishing-platform

Query Parameters

size  integer optional  

Entities per page, '32' by default.

page  integer optional  

The page number, '1' by default.

Relation: Tag

GET Tag[].

Get all Tags ordered by 'name'.

Route name: api.tags.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/tags" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/tags"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/tags',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4979
vary: Origin
 

{
    "data": [
        {
            "name": "1789 1799    fiction",
            "type": "tag",
            "count": 1,
            "firstChar": "1",
            "meta": {
                "slug": "1789-1799-fiction",
                "books": "https://bookshelves.ink/api/tags/books/1789-1799-fiction",
                "show": "https://bookshelves.ink/api/tags/1789-1799-fiction"
            }
        },
        {
            "name": "1799 avant 1945",
            "type": "tag",
            "count": 1,
            "firstChar": "1",
            "meta": {
                "slug": "1799-avant-1945",
                "books": "https://bookshelves.ink/api/tags/books/1799-avant-1945",
                "show": "https://bookshelves.ink/api/tags/1799-avant-1945"
            }
        },
        {
            "name": "Action & adventures",
            "type": "genre",
            "count": 15,
            "firstChar": "A",
            "meta": {
                "slug": "action-adventures",
                "books": "https://bookshelves.ink/api/tags/books/action-adventures",
                "show": "https://bookshelves.ink/api/tags/action-adventures"
            }
        },
        {
            "name": "Action & aventure",
            "type": "tag",
            "count": 17,
            "firstChar": "A",
            "meta": {
                "slug": "action-aventure",
                "books": "https://bookshelves.ink/api/tags/books/action-aventure",
                "show": "https://bookshelves.ink/api/tags/action-aventure"
            }
        },
        {
            "name": "Adventure stories",
            "type": "tag",
            "count": 2,
            "firstChar": "A",
            "meta": {
                "slug": "adventure-stories",
                "books": "https://bookshelves.ink/api/tags/books/adventure-stories",
                "show": "https://bookshelves.ink/api/tags/adventure-stories"
            }
        },
        {
            "name": "Ahab",
            "type": "tag",
            "count": 1,
            "firstChar": "A",
            "meta": {
                "slug": "ahab",
                "books": "https://bookshelves.ink/api/tags/books/ahab",
                "show": "https://bookshelves.ink/api/tags/ahab"
            }
        },
        {
            "name": "American literature",
            "type": "tag",
            "count": 0,
            "firstChar": "A",
            "meta": {
                "slug": "american-literature",
                "books": "https://bookshelves.ink/api/tags/books/american-literature",
                "show": "https://bookshelves.ink/api/tags/american-literature"
            }
        },
        {
            "name": "Ancient & classical",
            "type": "tag",
            "count": 1,
            "firstChar": "A",
            "meta": {
                "slug": "ancient-classical",
                "books": "https://bookshelves.ink/api/tags/books/ancient-classical",
                "show": "https://bookshelves.ink/api/tags/ancient-classical"
            }
        },
        {
            "name": "Aventures",
            "type": "tag",
            "count": 35,
            "firstChar": "A",
            "meta": {
                "slug": "aventures",
                "books": "https://bookshelves.ink/api/tags/books/aventures",
                "show": "https://bookshelves.ink/api/tags/aventures"
            }
        },
        {
            "name": "Bildungsromans",
            "type": "tag",
            "count": 1,
            "firstChar": "B",
            "meta": {
                "slug": "bildungsromans",
                "books": "https://bookshelves.ink/api/tags/books/bildungsromans",
                "show": "https://bookshelves.ink/api/tags/bildungsromans"
            }
        },
        {
            "name": "Boys    fiction",
            "type": "tag",
            "count": 1,
            "firstChar": "B",
            "meta": {
                "slug": "boys-fiction",
                "books": "https://bookshelves.ink/api/tags/books/boys-fiction",
                "show": "https://bookshelves.ink/api/tags/boys-fiction"
            }
        },
        {
            "name": "Children's stories",
            "type": "tag",
            "count": 1,
            "firstChar": "C",
            "meta": {
                "slug": "childrens-stories",
                "books": "https://bookshelves.ink/api/tags/books/childrens-stories",
                "show": "https://bookshelves.ink/api/tags/childrens-stories"
            }
        },
        {
            "name": "Classics",
            "type": "tag",
            "count": 63,
            "firstChar": "C",
            "meta": {
                "slug": "classics",
                "books": "https://bookshelves.ink/api/tags/books/classics",
                "show": "https://bookshelves.ink/api/tags/classics"
            }
        },
        {
            "name": "Collections générales",
            "type": "tag",
            "count": 3,
            "firstChar": "C",
            "meta": {
                "slug": "collections-generales",
                "books": "https://bookshelves.ink/api/tags/books/collections-generales",
                "show": "https://bookshelves.ink/api/tags/collections-generales"
            }
        },
        {
            "name": "Comedies",
            "type": "tag",
            "count": 1,
            "firstChar": "C",
            "meta": {
                "slug": "comedies",
                "books": "https://bookshelves.ink/api/tags/books/comedies",
                "show": "https://bookshelves.ink/api/tags/comedies"
            }
        },
        {
            "name": "Comics & graphic novels",
            "type": "tag",
            "count": 5,
            "firstChar": "C",
            "meta": {
                "slug": "comics-graphic-novels",
                "books": "https://bookshelves.ink/api/tags/books/comics-graphic-novels",
                "show": "https://bookshelves.ink/api/tags/comics-graphic-novels"
            }
        },
        {
            "name": "Conte",
            "type": "tag",
            "count": 2,
            "firstChar": "C",
            "meta": {
                "slug": "conte",
                "books": "https://bookshelves.ink/api/tags/books/conte",
                "show": "https://bookshelves.ink/api/tags/conte"
            }
        },
        {
            "name": "Contes",
            "type": "tag",
            "count": 1,
            "firstChar": "C",
            "meta": {
                "slug": "contes",
                "books": "https://bookshelves.ink/api/tags/books/contes",
                "show": "https://bookshelves.ink/api/tags/contes"
            }
        },
        {
            "name": "Courtship    fiction",
            "type": "tag",
            "count": 1,
            "firstChar": "C",
            "meta": {
                "slug": "courtship-fiction",
                "books": "https://bookshelves.ink/api/tags/books/courtship-fiction",
                "show": "https://bookshelves.ink/api/tags/courtship-fiction"
            }
        },
        {
            "name": "Crime & mystery",
            "type": "genre",
            "count": 0,
            "firstChar": "C",
            "meta": {
                "slug": "crime-mystery",
                "books": "https://bookshelves.ink/api/tags/books/crime-mystery",
                "show": "https://bookshelves.ink/api/tags/crime-mystery"
            }
        },
        {
            "name": "Documents   essais",
            "type": "tag",
            "count": 1,
            "firstChar": "D",
            "meta": {
                "slug": "documents-essais",
                "books": "https://bookshelves.ink/api/tags/books/documents-essais",
                "show": "https://bookshelves.ink/api/tags/documents-essais"
            }
        },
        {
            "name": "Domestic fiction",
            "type": "tag",
            "count": 1,
            "firstChar": "D",
            "meta": {
                "slug": "domestic-fiction",
                "books": "https://bookshelves.ink/api/tags/books/domestic-fiction",
                "show": "https://bookshelves.ink/api/tags/domestic-fiction"
            }
        },
        {
            "name": "England    drama",
            "type": "tag",
            "count": 1,
            "firstChar": "E",
            "meta": {
                "slug": "england-drama",
                "books": "https://bookshelves.ink/api/tags/books/england-drama",
                "show": "https://bookshelves.ink/api/tags/england-drama"
            }
        },
        {
            "name": "England    fiction",
            "type": "tag",
            "count": 1,
            "firstChar": "E",
            "meta": {
                "slug": "england-fiction",
                "books": "https://bookshelves.ink/api/tags/books/england-fiction",
                "show": "https://bookshelves.ink/api/tags/england-fiction"
            }
        },
        {
            "name": "English",
            "type": "tag",
            "count": 1,
            "firstChar": "E",
            "meta": {
                "slug": "english",
                "books": "https://bookshelves.ink/api/tags/books/english",
                "show": "https://bookshelves.ink/api/tags/english"
            }
        },
        {
            "name": "Epic",
            "type": "tag",
            "count": 1,
            "firstChar": "E",
            "meta": {
                "slug": "epic",
                "books": "https://bookshelves.ink/api/tags/books/epic",
                "show": "https://bookshelves.ink/api/tags/epic"
            }
        },
        {
            "name": "Espionage",
            "type": "tag",
            "count": 1,
            "firstChar": "E",
            "meta": {
                "slug": "espionage",
                "books": "https://bookshelves.ink/api/tags/books/espionage",
                "show": "https://bookshelves.ink/api/tags/espionage"
            }
        },
        {
            "name": "European",
            "type": "tag",
            "count": 3,
            "firstChar": "E",
            "meta": {
                "slug": "european",
                "books": "https://bookshelves.ink/api/tags/books/european",
                "show": "https://bookshelves.ink/api/tags/european"
            }
        },
        {
            "name": "Fairy tales & folklore",
            "type": "tag",
            "count": 1,
            "firstChar": "F",
            "meta": {
                "slug": "fairy-tales-folklore",
                "books": "https://bookshelves.ink/api/tags/books/fairy-tales-folklore",
                "show": "https://bookshelves.ink/api/tags/fairy-tales-folklore"
            }
        },
        {
            "name": "Family life",
            "type": "tag",
            "count": 1,
            "firstChar": "F",
            "meta": {
                "slug": "family-life",
                "books": "https://bookshelves.ink/api/tags/books/family-life",
                "show": "https://bookshelves.ink/api/tags/family-life"
            }
        },
        {
            "name": "Fantastique",
            "type": "tag",
            "count": 6,
            "firstChar": "F",
            "meta": {
                "slug": "fantastique",
                "books": "https://bookshelves.ink/api/tags/books/fantastique",
                "show": "https://bookshelves.ink/api/tags/fantastique"
            }
        },
        {
            "name": "Fantastique   science fiction",
            "type": "tag",
            "count": 3,
            "firstChar": "F",
            "meta": {
                "slug": "fantastique-science-fiction",
                "books": "https://bookshelves.ink/api/tags/books/fantastique-science-fiction",
                "show": "https://bookshelves.ink/api/tags/fantastique-science-fiction"
            }
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/tags?page=1",
        "last": "https://bookshelves.ink/api/tags?page=4",
        "prev": null,
        "next": "https://bookshelves.ink/api/tags?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 4,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/tags?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": "https://bookshelves.ink/api/tags?page=2",
                "label": "2",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/tags?page=3",
                "label": "3",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/tags?page=4",
                "label": "4",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/tags?page=2",
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/tags",
        "per_page": 32,
        "to": 32,
        "total": 117
    }
}
 

Request      

GET api/tags

Query Parameters

filters[type]  string optional  

Filter by type like tag or genre.

full  boolean optional  

Disable pagination.

alpha  boolean optional  

Chunk by first character.

Response

Response Fields

name  string  

Tag's name.

GET Tag.

Get Tag details.

Route name: api.tags.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/tags/mississippi-river-fiction" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/tags/mississippi-river-fiction"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/tags/mississippi-river-fiction',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4978
vary: Origin
 

{
    "data": {
        "name": "Mississippi river    fiction",
        "type": "tag",
        "count": null,
        "firstChar": null,
        "meta": {
            "slug": "mississippi-river-fiction",
            "books": null,
            "show": null
        }
    }
}
 

Request      

GET api/tags/{tag_slug}

URL Parameters

tag_slug  string  

slug of serie in meta.slug tags' list, example: mississippi-river-fiction

Query Parameters

filters[type]  string optional  

Filter by type like tag or genre.

GET Entity[] belongs to Tag.

Get all Books and Series of selected Tag.

Route name: api.tags.show.books

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/tags/books/epic" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/tags/books/epic"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/tags/books/epic',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4977
vary: Origin
 

{
    "data": [
        {
            "meta": {
                "entity": "book",
                "author": "virgile",
                "slug": "leneide-novel-fr",
                "show": "https://bookshelves.ink/api/books/virgile/leneide-novel-fr"
            },
            "title": "L'Énéide",
            "type": "Novel",
            "authors": [
                {
                    "name": "Virgile ",
                    "meta": {
                        "entity": "author",
                        "slug": "virgile",
                        "show": "https://bookshelves.ink/api/authors/virgile"
                    }
                }
            ],
            "serie": null,
            "language": {
                "name": "French",
                "meta": {
                    "slug": "fr"
                }
            },
            "volume": null,
            "count": null,
            "cover": {
                "thumbnail": "https://bookshelves.ink/storage/media/covers/396/conversions/leneide-novel-fr-thumbnail.webp",
                "original": "https://bookshelves.ink/storage/media/covers/396/leneide-novel-fr.webp",
                "simple": "https://bookshelves.ink/storage/media/covers/396/conversions/leneide-novel-fr-simple.jpg",
                "color": "#6f5d58"
            },
            "first_char": null
        }
    ],
    "links": {
        "first": "/?page=1",
        "last": "/?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "/?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "/",
        "per_page": 32,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/tags/books/{tag_slug}

URL Parameters

tag_slug  string  

slug of serie in meta.slug tags' list, example: epic

Submission

POST Send submission.

If honeypot is true, submission will be not sended.

Route name: api.submissions.send

Example request:
curl --request POST \
    "https://bookshelves.ink/api/submission/send" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Name\",
    \"email\": \"user@email.com\",
    \"honeypot\": true,
    \"message\": \"Hello! This is a message for you!\"
}"
const url = new URL(
    "https://bookshelves.ink/api/submission/send"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Name",
    "email": "user@email.com",
    "honeypot": true,
    "message": "Hello! This is a message for you!"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/submission/send',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Name',
            'email' => 'user@email.com',
            'honeypot' => true,
            'message' => 'Hello! This is a message for you!',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/submission/send

Body Parameters

name  string  

User's name.

email  string  

User's email. Must be a valid email address.

honeypot  boolean  

Honeypot: must be false to send notification.

message  string  

User's message. Must be at least 15 characters.

User: Account

Endpoint to get Authors data.

GET Favorites by user.

requires authentication

Route name: api.favorites.user

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/favorites/{user_id}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/favorites/{user_id}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/favorites/{user_id}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/favorites/{user_id}

POST Store new favorite.

requires authentication

Route name: api.favorites.toggle

Example request:
curl --request POST \
    "https://bookshelves.ink/api/favorites/toggle/{model}/{slug}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/favorites/toggle/{model}/{slug}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/favorites/toggle/{model}/{slug}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/favorites/toggle/{model}/{slug}

GET Current user.

requires authentication

Route name: api.profile

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/profile" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/profile"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/profile',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/profile

POST Update current user.

requires authentication

Route name: api.profile.update

Example request:
curl --request POST \
    "https://bookshelves.ink/api/profile/update" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=username" \
    --form "email=user@mail.com" \
    --form "about=Nostrud consequat occaecat dolore id ipsum culpa duis reprehenderit incididunt aute enim sint cillum Lorem. Non qui irure veniam eiusmod dolore mollit elit labore cupidatat eiusmod quis reprehenderit velit ut. Laborum culpa eiusmod laborum nostrud enim dolore incididunt. Consectetur cillum Lorem quis magna magna aliqua duis ut." \
    --form "use_gravatar=" \
    --form "display_favorites=" \
    --form "display_reviews=" \
    --form "display_gender=" \
    --form "gender=unknown" \
    --form "avatar=@/tmp/phpsOMVXE" \
    --form "banner=@/tmp/phpb1ZksH" 
const url = new URL(
    "https://bookshelves.ink/api/profile/update"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'username');
body.append('email', 'user@mail.com');
body.append('about', 'Nostrud consequat occaecat dolore id ipsum culpa duis reprehenderit incididunt aute enim sint cillum Lorem. Non qui irure veniam eiusmod dolore mollit elit labore cupidatat eiusmod quis reprehenderit velit ut. Laborum culpa eiusmod laborum nostrud enim dolore incididunt. Consectetur cillum Lorem quis magna magna aliqua duis ut.');
body.append('use_gravatar', '');
body.append('display_favorites', '');
body.append('display_reviews', '');
body.append('display_gender', '');
body.append('gender', 'unknown');
body.append('avatar', document.querySelector('input[name="avatar"]').files[0]);
body.append('banner', document.querySelector('input[name="banner"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/profile/update',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'username'
            ],
            [
                'name' => 'email',
                'contents' => 'user@mail.com'
            ],
            [
                'name' => 'about',
                'contents' => 'Nostrud consequat occaecat dolore id ipsum culpa duis reprehenderit incididunt aute enim sint cillum Lorem. Non qui irure veniam eiusmod dolore mollit elit labore cupidatat eiusmod quis reprehenderit velit ut. Laborum culpa eiusmod laborum nostrud enim dolore incididunt. Consectetur cillum Lorem quis magna magna aliqua duis ut.'
            ],
            [
                'name' => 'use_gravatar',
                'contents' => ''
            ],
            [
                'name' => 'display_favorites',
                'contents' => ''
            ],
            [
                'name' => 'display_reviews',
                'contents' => ''
            ],
            [
                'name' => 'display_gender',
                'contents' => ''
            ],
            [
                'name' => 'gender',
                'contents' => 'unknown'
            ],
            [
                'name' => 'avatar',
                'contents' => fopen('/tmp/phpsOMVXE', 'r')
            ],
            [
                'name' => 'banner',
                'contents' => fopen('/tmp/phpb1ZksH', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/update

Body Parameters

name  string  

Must not be greater than 256 characters.

email  string  

Must be a valid email address.

about  string optional  

Must not be greater than 2048 characters.

avatar  file optional  

Must be a file. Must not be greater than 2048 kilobytes.

banner  file optional  

Must be a file. Must not be greater than 2048 kilobytes.

use_gravatar  boolean  

display_favorites  boolean  

display_reviews  boolean  

display_gender  boolean  

gender  string optional  

POST Delete current user.

requires authentication

Route name: api.profile.delete

Example request:
curl --request POST \
    "https://bookshelves.ink/api/profile/delete" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"current_password\": \"et-aliquip\",
    \"confirm\": false
}"
const url = new URL(
    "https://bookshelves.ink/api/profile/delete"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "current_password": "et-aliquip",
    "confirm": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/profile/delete',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'current_password' => 'et-aliquip',
            'confirm' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/delete

Body Parameters

current_password  string  

Must not be greater than 256 characters.

confirm  boolean  

GET Delete avatar for current user.

requires authentication

Route name: api.profile.delete.avatar

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/profile/delete/avatar" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/profile/delete/avatar"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/profile/delete/avatar',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/profile/delete/avatar

User: Authentication

GET api/user

Route name: api.user

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/user" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/user"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/user',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (500):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Auth guard [user] is not defined.",
    "exception": "InvalidArgumentException",
    "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php",
    "line": 84,
    "trace": [
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php",
            "line": 68,
            "function": "resolve",
            "class": "Illuminate\\Auth\\AuthManager",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
            "line": 63,
            "function": "guard",
            "class": "Illuminate\\Auth\\AuthManager",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
            "line": 42,
            "function": "authenticate",
            "class": "Illuminate\\Auth\\Middleware\\Authenticate",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Auth\\Middleware\\Authenticate",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 33,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Laravel\\Sanctum\\Http\\Middleware\\{closure}",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 34,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 726,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 703,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 667,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 656,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 167,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/livewire/livewire/src/DisableBrowserCache.php",
            "line": 19,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Livewire\\DisableBrowserCache",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/fruitcake/laravel-cors/src/HandleCors.php",
            "line": 52,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Fruitcake\\Cors\\HandleCors",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php",
            "line": 39,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Http\\Middleware\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 142,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 111,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 299,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 287,
            "function": "callLaravelOrLumenRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 89,
            "function": "makeApiCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 45,
            "function": "makeResponseCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 35,
            "function": "makeResponseCallIfConditionsPass",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 222,
            "function": "__invoke",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 179,
            "function": "iterateThroughStrategies",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 116,
            "function": "fetchResponses",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 118,
            "function": "processRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 75,
            "function": "extractEndpointsInfoFromLaravelApp",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 51,
            "function": "extractEndpointsInfoAndWriteToDisk",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php",
            "line": 50,
            "function": "get",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 36,
            "function": "handle",
            "class": "Knuckles\\Scribe\\Commands\\GenerateDocumentation",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Util.php",
            "line": 41,
            "function": "Illuminate\\Container\\{closure}",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 93,
            "function": "unwrapIfClosure",
            "class": "Illuminate\\Container\\Util",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 37,
            "function": "callBoundMethod",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 651,
            "function": "call",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 136,
            "function": "call",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Command/Command.php",
            "line": 291,
            "function": "execute",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 121,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Command\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 989,
            "function": "run",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 299,
            "function": "doRunCommand",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 171,
            "function": "doRun",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Application.php",
            "line": 102,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php",
            "line": 129,
            "function": "run",
            "class": "Illuminate\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/artisan",
            "line": 37,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Console\\Kernel",
            "type": "->"
        }
    ]
}
 

Request      

GET api/user

POST Password update.

requires authentication

Route name: api.password.update

Example request:
curl --request POST \
    "https://bookshelves.ink/api/password/update" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"current_password\": \"sunt-commodo-ipsum-aliqua\",
    \"password\": \"ea-occaecat-culpa-ut-pariatur\"
}"
const url = new URL(
    "https://bookshelves.ink/api/password/update"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "current_password": "sunt-commodo-ipsum-aliqua",
    "password": "ea-occaecat-culpa-ut-pariatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/password/update',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'current_password' => 'sunt-commodo-ipsum-aliqua',
            'password' => 'ea-occaecat-culpa-ut-pariatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/password/update

Body Parameters

current_password  string  

Must not be greater than 256 characters.

password  string  

Must not be greater than 256 characters.

POST Login.

Route name: api.login

Example request:
curl --request POST \
    "https://bookshelves.ink/api/login" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"rice.jaren@example.net\",
    \"password\": \"mollitia\",
    \"remember\": true
}"
const url = new URL(
    "https://bookshelves.ink/api/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "rice.jaren@example.net",
    "password": "mollitia",
    "remember": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/login',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'rice.jaren@example.net',
            'password' => 'mollitia',
            'remember' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/login

Body Parameters

email  string  

Must be a valid email address.

password  string  

remember  boolean optional  

POST Logout.

requires authentication

Route name: api.logout

Example request:
curl --request POST \
    "https://bookshelves.ink/api/logout" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/logout"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/logout',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/logout

POST Login.

Route name: api.login.token

Example request:
curl --request POST \
    "https://bookshelves.ink/api/login/token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"ruth86@example.net\",
    \"password\": \"placeat\",
    \"remember\": false,
    \"device_name\": \"voluptate\"
}"
const url = new URL(
    "https://bookshelves.ink/api/login/token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "ruth86@example.net",
    "password": "placeat",
    "remember": false,
    "device_name": "voluptate"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/login/token',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'ruth86@example.net',
            'password' => 'placeat',
            'remember' => false,
            'device_name' => 'voluptate',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/login/token

Body Parameters

email  string  

Must be a valid email address.

password  string  

remember  boolean optional  

device_name  string  

POST Logout.

requires authentication

Route name: api.logout.token

Example request:
curl --request POST \
    "https://bookshelves.ink/api/logout/token" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/logout/token"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/logout/token',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/logout/token

POST Register.

Route name: api.register

Example request:
curl --request POST \
    "https://bookshelves.ink/api/register" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/register"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/register',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/register

User: Profile

GET User[].

Route name: api.users.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/users" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/users"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/users',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4971
vary: Origin
 

{
    "data": [
        {
            "id": 2,
            "meta": {
                "slug": "admin-6794",
                "show": "https://bookshelves.ink/api/users/admin-6794"
            },
            "name": "Admin",
            "slug": "admin-6794",
            "email": "admin@example.com",
            "role": "admin",
            "about": "Eligendi porro voluptas dolorem. Deserunt perspiciatis ad sunt. Pariatur recusandae tenetur quisquam qui.",
            "gender": "Unknown",
            "avatar": "https://eu.ui-avatars.com/api/?name=Admin&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 12,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 1,
            "display_gender": 1
        },
        {
            "id": 9,
            "meta": {
                "slug": "alfred-bode-9938",
                "show": "https://bookshelves.ink/api/users/alfred-bode-9938"
            },
            "name": "Alfred Bode",
            "slug": "alfred-bode-9938",
            "email": "lewis.towne@example.org",
            "role": "user",
            "about": "Nulla consequatur optio possimus officia necessitatibus eos ipsam. Eos reiciendis non omnis impedit ex quia distinctio nulla. In voluptatem sapiente architecto aperiam aut deleniti cumque.",
            "gender": "Unknown",
            "avatar": "https://bookshelves.ink/storage/media/users/513/alfred-bode-9938.webp",
            "color": "#726d6f",
            "use_gravatar": 0,
            "reviews_count": 8,
            "favorites_count": 4,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 1,
            "display_gender": 1
        },
        {
            "id": 21,
            "meta": {
                "slug": "alfred-wintheiser-6171",
                "show": "https://bookshelves.ink/api/users/alfred-wintheiser-6171"
            },
            "name": "Alfred Wintheiser",
            "slug": "alfred-wintheiser-6171",
            "email": "nitzsche.muhammad@example.net",
            "role": "user",
            "about": "Eligendi nihil rem autem odio. Dolore repudiandae deserunt soluta minus quod dolores. Doloremque ullam pariatur commodi mollitia. Blanditiis sunt deleniti amet itaque.",
            "gender": "Man",
            "avatar": "https://eu.ui-avatars.com/api/?name=Alfred Wintheiser&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 9,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 17,
            "meta": {
                "slug": "angeline-nitzsche-4596",
                "show": "https://bookshelves.ink/api/users/angeline-nitzsche-4596"
            },
            "name": "Angeline Nitzsche",
            "slug": "angeline-nitzsche-4596",
            "email": "steuber.meta@example.org",
            "role": "user",
            "about": "Cum magnam sed voluptatem et vero ipsa dignissimos. Suscipit sit iure illum necessitatibus et rem non sed. Quia dolorem culpa necessitatibus vel. Ullam itaque similique eligendi hic dolorem.",
            "gender": "Unknown",
            "avatar": "https://bookshelves.ink/storage/media/users/524/angeline-nitzsche-4596.webp",
            "color": "#726d6f",
            "use_gravatar": 0,
            "reviews_count": 8,
            "favorites_count": 11,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 16,
            "meta": {
                "slug": "betty-bauch-3673",
                "show": "https://bookshelves.ink/api/users/betty-bauch-3673"
            },
            "name": "Betty Bauch",
            "slug": "betty-bauch-3673",
            "email": "mortimer.grimes@example.org",
            "role": "user",
            "about": "Qui sed et dicta reprehenderit dolorum enim neque tenetur. Provident eaque aut facere incidunt. Ab quo porro consequatur eum enim. Qui esse incidunt aut voluptatem officia et.",
            "gender": "Genderfluid",
            "avatar": "https://eu.ui-avatars.com/api/?name=Betty Bauch&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 10,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 22,
            "meta": {
                "slug": "burnice-collier-4036",
                "show": "https://bookshelves.ink/api/users/burnice-collier-4036"
            },
            "name": "Burnice Collier",
            "slug": "burnice-collier-4036",
            "email": "asia.wehner@example.net",
            "role": "user",
            "about": "Quasi dolore ut nihil consequatur accusantium. Perferendis minima quo repudiandae et. Voluptas qui quia aut fugiat et quod.",
            "gender": "Woman",
            "avatar": "https://bookshelves.ink/storage/media/users/529/burnice-collier-4036.webp",
            "color": "#414b74",
            "use_gravatar": 0,
            "reviews_count": 11,
            "favorites_count": 6,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 14,
            "meta": {
                "slug": "candido-rice-8701",
                "show": "https://bookshelves.ink/api/users/candido-rice-8701"
            },
            "name": "Candido Rice",
            "slug": "candido-rice-8701",
            "email": "ondricka.elroy@example.net",
            "role": "user",
            "about": "In repellat error cupiditate laborum dolor adipisci. Temporibus animi quibusdam ad sit suscipit dolore. Harum repellat ex possimus aliquid. Est doloremque assumenda quisquam sunt officia.",
            "gender": "Genderfluid",
            "avatar": "https://bookshelves.ink/storage/media/users/521/candido-rice-8701.webp",
            "color": "#c5bfbb",
            "use_gravatar": 0,
            "reviews_count": 9,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 4,
            "meta": {
                "slug": "delphia-satterfield-4030",
                "show": "https://bookshelves.ink/api/users/delphia-satterfield-4030"
            },
            "name": "Delphia Satterfield",
            "slug": "delphia-satterfield-4030",
            "email": "tavares15@example.org",
            "role": "user",
            "about": "Quia suscipit at repellendus sed aut dicta sit minima. Ut voluptates blanditiis recusandae rerum vel ut ipsa non. Neque molestiae tempore iure a. Hic ut aut vero voluptatem perferendis.",
            "gender": "Unknown",
            "avatar": "https://bookshelves.ink/storage/media/users/507/delphia-satterfield-4030.webp",
            "color": "#a98f79",
            "use_gravatar": 0,
            "reviews_count": 10,
            "favorites_count": 4,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 1,
            "display_gender": 0
        },
        {
            "id": 10,
            "meta": {
                "slug": "elenora-kulas-3343",
                "show": "https://bookshelves.ink/api/users/elenora-kulas-3343"
            },
            "name": "Elenora Kulas",
            "slug": "elenora-kulas-3343",
            "email": "adaline.runolfsson@example.net",
            "role": "user",
            "about": "Possimus nam sint enim ipsa quae occaecati est. Odit rem velit qui voluptas labore ad. Consequuntur suscipit et iure officiis repellendus.",
            "gender": "Agender",
            "avatar": "https://bookshelves.ink/storage/media/users/515/elenora-kulas-3343.webp",
            "color": "#414b74",
            "use_gravatar": 0,
            "reviews_count": 10,
            "favorites_count": 7,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 13,
            "meta": {
                "slug": "fiona-bahringer-7052",
                "show": "https://bookshelves.ink/api/users/fiona-bahringer-7052"
            },
            "name": "Fiona Bahringer",
            "slug": "fiona-bahringer-7052",
            "email": "chase66@example.com",
            "role": "user",
            "about": "Laborum ratione deserunt odio sint tempore odio et. Deserunt suscipit quae aut nihil itaque. Ipsa dicta amet quidem dolores alias natus. Dolorem quia saepe deserunt adipisci.",
            "gender": "Woman",
            "avatar": "https://bookshelves.ink/storage/media/users/520/fiona-bahringer-7052.webp",
            "color": "#574c34",
            "use_gravatar": 0,
            "reviews_count": 9,
            "favorites_count": 8,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 11,
            "meta": {
                "slug": "isabelle-gottlieb-5037",
                "show": "https://bookshelves.ink/api/users/isabelle-gottlieb-5037"
            },
            "name": "Isabelle Gottlieb",
            "slug": "isabelle-gottlieb-5037",
            "email": "beier.lorenzo@example.net",
            "role": "user",
            "about": "Vero dolorem et aliquam quasi aut dicta aut. Perspiciatis sit voluptate et fugiat. Quisquam non fugit et.",
            "gender": "Man",
            "avatar": "https://bookshelves.ink/storage/media/users/517/isabelle-gottlieb-5037.webp",
            "color": "#574642",
            "use_gravatar": 0,
            "reviews_count": 11,
            "favorites_count": 9,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 5,
            "meta": {
                "slug": "jeromy-mclaughlin-1714",
                "show": "https://bookshelves.ink/api/users/jeromy-mclaughlin-1714"
            },
            "name": "Jeromy McLaughlin",
            "slug": "jeromy-mclaughlin-1714",
            "email": "jamil.mills@example.org",
            "role": "user",
            "about": "Id sit itaque quam minima sit. Quo debitis praesentium quo unde.",
            "gender": "Genderfluid",
            "avatar": "https://bookshelves.ink/storage/media/users/509/jeromy-mclaughlin-1714.webp",
            "color": "#a98f79",
            "use_gravatar": 0,
            "reviews_count": 12,
            "favorites_count": 3,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 20,
            "meta": {
                "slug": "joanie-greenholt-8531",
                "show": "https://bookshelves.ink/api/users/joanie-greenholt-8531"
            },
            "name": "Joanie Greenholt",
            "slug": "joanie-greenholt-8531",
            "email": "nmitchell@example.com",
            "role": "user",
            "about": "Minus non non a voluptas voluptatem accusantium veniam ea. Eius rem cupiditate similique vel ut reprehenderit quia. Modi voluptates sequi minima doloribus ipsum id blanditiis.",
            "gender": "Man",
            "avatar": "https://bookshelves.ink/storage/media/users/527/joanie-greenholt-8531.webp",
            "color": "#425d40",
            "use_gravatar": 0,
            "reviews_count": 10,
            "favorites_count": 7,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 1,
            "display_gender": 1
        },
        {
            "id": 12,
            "meta": {
                "slug": "julien-bartoletti-7861",
                "show": "https://bookshelves.ink/api/users/julien-bartoletti-7861"
            },
            "name": "Julien Bartoletti",
            "slug": "julien-bartoletti-7861",
            "email": "kveum@example.net",
            "role": "user",
            "about": "Eveniet eveniet neque minus nostrum officia molestiae quae. Inventore placeat quae id aut modi eaque.",
            "gender": "Unknown",
            "avatar": "https://bookshelves.ink/storage/media/users/518/julien-bartoletti-7861.webp",
            "color": "#858585",
            "use_gravatar": 0,
            "reviews_count": 13,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 18,
            "meta": {
                "slug": "kali-hirthe-9673",
                "show": "https://bookshelves.ink/api/users/kali-hirthe-9673"
            },
            "name": "Kali Hirthe",
            "slug": "kali-hirthe-9673",
            "email": "ohoeger@example.org",
            "role": "user",
            "about": "Occaecati eum aliquid iure odit et. Quos nesciunt sed officiis corrupti consequatur delectus corrupti. Qui sit ad velit commodi velit. Vel tenetur inventore numquam inventore.",
            "gender": "Man",
            "avatar": "https://eu.ui-avatars.com/api/?name=Kali Hirthe&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 11,
            "favorites_count": 4,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 3,
            "meta": {
                "slug": "lucius-bechtelar-5161",
                "show": "https://bookshelves.ink/api/users/lucius-bechtelar-5161"
            },
            "name": "Lucius Bechtelar",
            "slug": "lucius-bechtelar-5161",
            "email": "wmedhurst@example.com",
            "role": "user",
            "about": "Sit minus illo inventore omnis dolor eligendi. Tempora soluta tempora voluptatem. Quas itaque laborum minima. Nihil qui rem dolor inventore qui est. Atque quam libero est.",
            "gender": "Genderfluid",
            "avatar": "https://bookshelves.ink/storage/media/users/505/lucius-bechtelar-5161.webp",
            "color": "#5e4239",
            "use_gravatar": 0,
            "reviews_count": 6,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 15,
            "meta": {
                "slug": "molly-legros-4505",
                "show": "https://bookshelves.ink/api/users/molly-legros-4505"
            },
            "name": "Molly Legros",
            "slug": "molly-legros-4505",
            "email": "rolfson.kristina@example.net",
            "role": "user",
            "about": "Ipsam labore et illo itaque. Est nam debitis repellat impedit. Voluptatem minus ea facere praesentium nostrum illum ad et. Facilis consequatur quia qui non error.",
            "gender": "Agender",
            "avatar": "https://bookshelves.ink/storage/media/users/523/molly-legros-4505.webp",
            "color": "#3b331e",
            "use_gravatar": 0,
            "reviews_count": 13,
            "favorites_count": 1,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 0,
            "display_gender": 0
        },
        {
            "id": 6,
            "meta": {
                "slug": "palma-friesen-3358",
                "show": "https://bookshelves.ink/api/users/palma-friesen-3358"
            },
            "name": "Palma Friesen",
            "slug": "palma-friesen-3358",
            "email": "maximilian.stamm@example.org",
            "role": "user",
            "about": "Explicabo et pariatur qui aspernatur quia. Commodi eaque error quo ad laudantium.",
            "gender": "Woman",
            "avatar": "https://bookshelves.ink/storage/media/users/510/palma-friesen-3358.webp",
            "color": "#a98f79",
            "use_gravatar": 0,
            "reviews_count": 11,
            "favorites_count": 5,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 1,
            "display_gender": 1
        },
        {
            "id": 7,
            "meta": {
                "slug": "roma-altenwerth-9103",
                "show": "https://bookshelves.ink/api/users/roma-altenwerth-9103"
            },
            "name": "Roma Altenwerth",
            "slug": "roma-altenwerth-9103",
            "email": "macey11@example.org",
            "role": "user",
            "about": "Fugit impedit eos vitae et ut occaecati. Voluptate ea voluptatem ipsa. Et sed ut iure enim dolores.",
            "gender": "Non binary",
            "avatar": "https://bookshelves.ink/storage/media/users/511/roma-altenwerth-9103.webp",
            "color": "#312823",
            "use_gravatar": 0,
            "reviews_count": 11,
            "favorites_count": 11,
            "is_admin": false,
            "display_reviews": 0,
            "display_favorites": 1,
            "display_gender": 0
        },
        {
            "id": 1,
            "meta": {
                "slug": "super-admin-2443",
                "show": "https://bookshelves.ink/api/users/super-admin-2443"
            },
            "name": "Super Admin",
            "slug": "super-admin-2443",
            "email": "superadmin@example.com",
            "role": "super_admin",
            "about": "Quae commodi ut fugit. Similique ut nobis ea a laboriosam amet beatae cupiditate. Et doloremque iusto aut temporibus temporibus voluptatibus. Voluptatum id aut laborum aut earum.",
            "gender": "Man",
            "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 14,
            "favorites_count": 7,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 19,
            "meta": {
                "slug": "tia-turner-4853",
                "show": "https://bookshelves.ink/api/users/tia-turner-4853"
            },
            "name": "Tia Turner",
            "slug": "tia-turner-4853",
            "email": "art.lehner@example.net",
            "role": "user",
            "about": "Est illo aliquam recusandae ut et molestias nihil. Quas quod voluptatem impedit maiores qui.",
            "gender": "Agender",
            "avatar": "https://bookshelves.ink/storage/media/users/525/tia-turner-4853.webp",
            "color": "#574642",
            "use_gravatar": 0,
            "reviews_count": 4,
            "favorites_count": 1,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 1
        },
        {
            "id": 8,
            "meta": {
                "slug": "zakary-dickinson-4158",
                "show": "https://bookshelves.ink/api/users/zakary-dickinson-4158"
            },
            "name": "Zakary Dickinson",
            "slug": "zakary-dickinson-4158",
            "email": "ellsworth.schumm@example.org",
            "role": "user",
            "about": "Qui animi nemo corrupti ut repellendus qui. Suscipit qui expedita quae dolorem. Sed ex consequatur est aut quod numquam mollitia minima. Accusantium aut qui vero rem.",
            "gender": "Woman",
            "avatar": "https://eu.ui-avatars.com/api/?name=Zakary Dickinson&color=7F9CF5&background=EBF4FF",
            "color": "#",
            "use_gravatar": 0,
            "reviews_count": 13,
            "favorites_count": 4,
            "is_admin": false,
            "display_reviews": 1,
            "display_favorites": 0,
            "display_gender": 0
        }
    ]
}
 

Request      

GET api/users

GET User.

Route name: api.users.show

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/users/zakary-dickinson-4158" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/users/zakary-dickinson-4158"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/users/zakary-dickinson-4158',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4970
vary: Origin
 

{
    "data": {
        "id": 8,
        "meta": {
            "slug": "zakary-dickinson-4158",
            "show": "https://bookshelves.ink/api/users/zakary-dickinson-4158",
            "banner": "https://bookshelves.ink/storage/media/users/512/zakary-dickinson-4158-banner.webp",
            "show_reviews": "https://bookshelves.ink/api/users/reviews/zakary-dickinson-4158",
            "show_favorites": "https://bookshelves.ink/api/users/favorites/zakary-dickinson-4158"
        },
        "name": "Zakary Dickinson",
        "slug": "zakary-dickinson-4158",
        "email": "ellsworth.schumm@example.org",
        "role": "user",
        "about": "Qui animi nemo corrupti ut repellendus qui. Suscipit qui expedita quae dolorem. Sed ex consequatur est aut quod numquam mollitia minima. Accusantium aut qui vero rem.",
        "gender": "Woman",
        "avatar": "https://eu.ui-avatars.com/api/?name=Zakary Dickinson&color=7F9CF5&background=EBF4FF",
        "color": "#",
        "use_gravatar": 0,
        "reviews_count": 13,
        "favorites_count": 4,
        "is_admin": false,
        "display_reviews": 1,
        "display_favorites": 0,
        "display_gender": 0
    }
}
 

Request      

GET api/users/{user_slug}

URL Parameters

user_slug  string  

slug of user in meta.slug users' list, example: zakary-dickinson-4158

GET Review[] belongs to User.

Route name: api.users.reviews

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/users/reviews/super-admin-2443?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/users/reviews/super-admin-2443"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/users/reviews/super-admin-2443',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4969
vary: Origin
 

{
    "data": [
        {
            "meta": {
                "type": "review",
                "for": "author",
                "author": null,
                "slug": "kafka-franz"
            },
            "id": 230,
            "text": "<p><strong>Et</strong> a voluptates non. Iste numquam ducimus minus <em>est</em> <strong>eum</strong> quo laboriosam blanditiis. Quia qui laboriosam <em>aliquam</em> nulla.</p>\n<p>Consequuntur <strong>iure</strong> reprehenderit repellendus consequatur provident ab nulla. Aspernatur ut <strong>quae</strong> saepe saepe ut repellendus optio. Ut iste voluptatum <strong>aut</strong> ullam assumenda minus non. Impedit odit rerum omnis. <strong>Modi</strong> provident autem <em>officia</em> officiis. Suscipit id aut velit <strong>vel</strong> distinctio <em>ut</em> reprehenderit. Inventore molestiae atque aut eligendi. <strong>Aut</strong> <em>quo</em> inventore dolor minima at repellendus. Occaecati autem <strong>voluptas</strong> placeat aut. Aut facere quae quia sint <em>quo</em> excepturi. At non rerum nihil soluta eligendi <em>fuga</em> suscipit vel. Sit adipisci quia et dolores.</p>\n",
            "rating": 2,
            "user": {
                "id": 1,
                "name": "Super Admin",
                "slug": "super-admin-2443",
                "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
                "color": "#"
            },
            "title": "Kafka Franz",
            "cover": "https://bookshelves.ink/storage/media/covers/488/conversions/kafka-franz-thumbnail.webp",
            "color": "#646464",
            "createdAt": "2022-04-12T10:41:34.000000Z",
            "updatedAt": "2022-04-12T10:41:34.000000Z"
        },
        {
            "meta": {
                "type": "review",
                "for": "book",
                "author": "dumas-alexandre",
                "slug": "la-dame-de-monsoreau-tome-i-novel-fr"
            },
            "id": 54,
            "text": "<p><strong>Earum</strong> dolor molestiae consequatur mollitia. Et nihil consectetur <em>qui</em> <strong>ipsam</strong> quasi non odit. In quia nesciunt <em>id</em> aliquam <strong>dolor</strong> laborum aut quia. Vitae modi <em>harum</em> assumenda voluptas. <strong>Nostrum</strong> numquam reiciendis dolores. Dolores <em>labore</em> numquam rerum. Ullam <strong>nostrum</strong> voluptates dignissimos.</p>\n<p>Magnam accusantium <em>enim</em> fuga tempora molestias inventore ipsa. Et voluptate <em>eos</em> id voluptatem occaecati. Reiciendis quae <strong>dolores</strong> magni <em>nesciunt</em> aperiam a. Omnis quo nobis et. <strong>Eveniet</strong> <em>voluptate</em> eum porro laboriosam harum. Dolorem alias dolores <strong>recusandae</strong> velit dolor adipisci sit deleniti.</p>\n",
            "rating": 1,
            "user": {
                "id": 1,
                "name": "Super Admin",
                "slug": "super-admin-2443",
                "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
                "color": "#"
            },
            "title": "La Dame de Monsoreau, tome I",
            "cover": "https://bookshelves.ink/storage/media/covers/159/conversions/la-dame-de-monsoreau-tome-i-novel-fr-thumbnail.webp",
            "color": "#ceaea4",
            "createdAt": "2022-04-08T16:21:35.000000Z",
            "updatedAt": "2022-04-11T09:50:41.000000Z"
        },
        {
            "meta": {
                "type": "review",
                "for": "book",
                "author": "verne-jules",
                "slug": "larchipel-en-feu-novel-fr"
            },
            "id": 157,
            "text": "<p><strong>Sequi</strong> consequatur voluptatem quasi sint cupiditate ex dolorem. <em>Voluptatem</em> <strong>est</strong> officia dolor. Ducimus molestiae beatae sunt eius. Qui <strong>quam</strong> sunt illo. Et tenetur dolor <em>delectus</em> molestias expedita iure. Enim numquam magnam dolor <em>eum</em> corporis quia quia sapiente.</p>\n<p>Repudiandae rerum suscipit commodi. <em>Illo</em> harum qui dolore officiis voluptates. Facilis repudiandae <em>necessitatibus</em> rerum aliquid placeat. Quae ut <strong>sint</strong> occaecati dolore.</p>\n",
            "rating": 5,
            "user": {
                "id": 1,
                "name": "Super Admin",
                "slug": "super-admin-2443",
                "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
                "color": "#"
            },
            "title": "L'Archipel en feu",
            "cover": "https://bookshelves.ink/storage/media/covers/298/conversions/larchipel-en-feu-novel-fr-thumbnail.webp",
            "color": "#a27661",
            "createdAt": "2022-04-08T16:16:29.000000Z",
            "updatedAt": "2022-04-11T14:56:39.000000Z"
        },
        {
            "meta": {
                "type": "review",
                "for": "book",
                "author": "verne-jules",
                "slug": "claudius-bombarnac-carnet-de-reporter-novel-fr"
            },
            "id": 16,
            "text": "<p><strong>Cum</strong> labore omnis odit aut quo. Necessitatibus quis <em>optio</em> <strong>sequi</strong> laborum laboriosam itaque. Voluptatem expedita eaque <em>esse</em> laborum <strong>voluptas</strong> est tempore. Omnis deleniti aut <em>nostrum</em> molestias placeat sapiente.</p>\n<p>Adipisci alias nemo magnam accusantium <em>magni</em> id. Minima harum <strong>dolor</strong> neque iusto dolore <em>vero</em> fuga voluptatibus. Cumque consequatur <strong>nemo</strong> ullam exercitationem qui. Quisquam reprehenderit aliquid et possimus <strong>quia</strong> eum. <em>Illum</em> voluptatibus et voluptatibus. Nemo optio quis <strong>optio</strong> <em>amet</em> voluptatem libero reprehenderit. Commodi ut dicta ut <strong>excepturi</strong> vel voluptas. Vitae necessitatibus sed impedit. Tempora <em>ab</em> <strong>quis</strong> numquam. At et iure quae quas <em>eligendi</em> nostrum voluptatem. Nulla et quos vel nisi <em>dicta</em> sunt porro.</p>\n",
            "rating": 3,
            "user": {
                "id": 1,
                "name": "Super Admin",
                "slug": "super-admin-2443",
                "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
                "color": "#"
            },
            "title": "Claudius Bombarnac - Carnet de reporter",
            "cover": "https://bookshelves.ink/storage/media/covers/278/conversions/claudius-bombarnac-carnet-de-reporter-novel-fr-thumbnail.webp",
            "color": "#ad7d5d",
            "createdAt": "2022-04-02T21:21:28.000000Z",
            "updatedAt": "2022-04-02T21:21:28.000000Z"
        },
        {
            "meta": {
                "type": "review",
                "for": "book",
                "author": "verne-jules",
                "slug": "voyages-et-aventures-du-capitaine-hatteras-novel-fr"
            },
            "id": 10,
            "text": "<p><strong>Ratione</strong> voluptatibus quae ad explicabo. Eos mollitia quis <em>sit</em> <strong>omnis</strong> consequatur. Libero aliquid ullam sit et voluptas. Cupiditate <strong>animi</strong> reprehenderit facilis facilis dignissimos consequatur. <em>Est</em> sed doloremque <strong>id</strong> voluptates et enim. Iusto <em>quia</em> in voluptatibus saepe. <strong>Sit</strong> facilis quia quia <em>nostrum</em> cum consequatur. Cumque molestiae <strong>id</strong> totam assumenda <em>nulla</em> et. Enim perspiciatis quis qui <strong>debitis</strong> repellat <em>ea</em> veritatis reprehenderit. Similique velit nobis quia illo.</p>\n<p>Pariatur <em>voluptatem</em> nostrum sit provident nostrum ex sit eius. <strong>Tempora</strong> ut voluptas quia quod aperiam soluta ipsam. <em>Placeat</em> <strong>ea</strong> perspiciatis nemo eveniet dolor consequuntur quibusdam laudantium. Assumenda <strong>doloribus</strong> omnis dolorem optio quis consequuntur <em>aperiam</em> aut.</p>\n",
            "rating": 0,
            "user": {
                "id": 1,
                "name": "Super Admin",
                "slug": "super-admin-2443",
                "avatar": "https://eu.ui-avatars.com/api/?name=Super Admin&color=7F9CF5&background=EBF4FF",
                "color": "#"
            },
            "title": "Voyages et aventures du capitaine Hatteras",
            "cover": "https://bookshelves.ink/storage/media/covers/374/conversions/voyages-et-aventures-du-capitaine-hatteras-novel-fr-thumbnail.webp",
            "color": "#758b66",
            "createdAt": "2022-04-01T16:20:46.000000Z",
            "updatedAt": "2022-04-01T16:20:46.000000Z"
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=1",
        "last": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=3",
        "prev": null,
        "next": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=2",
                "label": "2",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=3",
                "label": "3",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/users/reviews/super-admin-2443?page=2",
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/users/reviews/super-admin-2443",
        "per_page": 5,
        "to": 5,
        "total": 14
    }
}
 

Request      

GET api/users/reviews/{user_slug}

URL Parameters

user_slug  string  

slug of user in meta.slug users' list, example: super-admin-2443

Query Parameters

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

GET Favorite[] belongs to User.

Route name: api.users.favorites

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/users/favorites/candido-rice-8701?size=5&page=1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/users/favorites/candido-rice-8701"
);

const params = {
    "size": "5",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/users/favorites/candido-rice-8701',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'size'=> '5',
            'page'=> '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4968
vary: Origin
 

{
    "data": [
        {
            "meta": {
                "type": "favorite",
                "for": "author",
                "author": null,
                "slug": "virgile"
            },
            "title": "Virgile ",
            "cover": "https://bookshelves.ink/storage/media/covers/500/conversions/virgile-thumbnail.webp",
            "color": "#848484",
            "createdAt": "2022-04-07T20:13:50.000000Z",
            "updatedAt": "2022-04-17T08:36:29.000000Z"
        },
        {
            "meta": {
                "type": "favorite",
                "for": "book",
                "author": "vian-boris",
                "slug": "lecume-des-jours-novel-fr"
            },
            "title": "L'Ecume des jours",
            "cover": "https://bookshelves.ink/storage/media/covers/384/conversions/lecume-des-jours-novel-fr-thumbnail.webp",
            "color": "#de9aa2",
            "createdAt": "2022-04-04T20:01:09.000000Z",
            "updatedAt": "2022-04-17T08:36:29.000000Z"
        },
        {
            "meta": {
                "type": "favorite",
                "for": "serie",
                "author": "dumas-alexandre",
                "slug": "la-fille-du-marquis-novel-fr"
            },
            "title": "La fille du marquis",
            "cover": "https://bookshelves.ink/storage/media/covers/470/conversions/la-fille-du-marquis-novel-fr-thumbnail.webp",
            "color": "#d3c8c3",
            "createdAt": "2022-04-03T18:05:55.000000Z",
            "updatedAt": "2022-04-17T08:36:29.000000Z"
        },
        {
            "meta": {
                "type": "favorite",
                "for": "book",
                "author": "verne-jules",
                "slug": "keraban-le-tetu-novel-fr"
            },
            "title": "Kéraban-le-têtu",
            "cover": "https://bookshelves.ink/storage/media/covers/296/conversions/keraban-le-tetu-novel-fr-thumbnail.webp",
            "color": "#7b7b7b",
            "createdAt": "2022-03-31T16:23:47.000000Z",
            "updatedAt": "2022-04-17T08:36:29.000000Z"
        },
        {
            "meta": {
                "type": "favorite",
                "for": "book",
                "author": "vian-boris",
                "slug": "lequarissage-pour-tous-novel-fr"
            },
            "title": "L'Équarissage pour tous",
            "cover": "https://bookshelves.ink/storage/media/covers/386/conversions/lequarissage-pour-tous-novel-fr-thumbnail.webp",
            "color": "#a7ab78",
            "createdAt": "2022-03-29T22:17:44.000000Z",
            "updatedAt": "2022-04-17T08:36:29.000000Z"
        }
    ],
    "links": {
        "first": "https://bookshelves.ink/api/users/favorites/candido-rice-8701?page=1",
        "last": "https://bookshelves.ink/api/users/favorites/candido-rice-8701?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "active": false
            },
            {
                "url": "https://bookshelves.ink/api/users/favorites/candido-rice-8701?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "active": false
            }
        ],
        "path": "https://bookshelves.ink/api/users/favorites/candido-rice-8701",
        "per_page": 5,
        "to": 5,
        "total": 5
    }
}
 

Request      

GET api/users/favorites/{user_slug}

URL Parameters

user_slug  string  

slug of user in meta.slug users' list, example: candido-rice-8701

Query Parameters

size  int optional  

Number of entities to return in a page.

page  int optional  

Page number to return, 1 by default

User: Review

GET Reviews for entity.

Route name: api.reviews.index

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/reviews/{model}/{slug}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/{model}/{slug}"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/reviews/{model}/{slug}',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (500):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4980
vary: Origin
 

{
    "message": "Class \"App\\Models\\{model}\" not found",
    "exception": "Error",
    "file": "/home/ewilan/www/bookshelves-back/app/Http/Controllers/Api/ReviewController.php",
    "line": 24,
    "trace": [
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
            "line": 54,
            "function": "index",
            "class": "App\\Http\\Controllers\\Api\\ReviewController",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
            "line": 45,
            "function": "callAction",
            "class": "Illuminate\\Routing\\Controller",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 261,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\ControllerDispatcher",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
            "line": 204,
            "function": "runController",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 725,
            "function": "run",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
            "line": 50,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 126,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 102,
            "function": "handleRequest",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
            "line": 54,
            "function": "handleRequestUsingNamedLimiter",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 33,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Laravel\\Sanctum\\Http\\Middleware\\{closure}",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
            "line": 34,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 726,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 703,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 667,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 656,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 167,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 141,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/livewire/livewire/src/DisableBrowserCache.php",
            "line": 19,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Livewire\\DisableBrowserCache",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
            "line": 31,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
            "line": 40,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
            "line": 86,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/fruitcake/laravel-cors/src/HandleCors.php",
            "line": 52,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Fruitcake\\Cors\\HandleCors",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php",
            "line": 39,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 180,
            "function": "handle",
            "class": "Illuminate\\Http\\Middleware\\TrustProxies",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 116,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 142,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 111,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 299,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 287,
            "function": "callLaravelOrLumenRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 89,
            "function": "makeApiCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 45,
            "function": "makeResponseCall",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Strategies/Responses/ResponseCalls.php",
            "line": 35,
            "function": "makeResponseCallIfConditionsPass",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 222,
            "function": "__invoke",
            "class": "Knuckles\\Scribe\\Extracting\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 179,
            "function": "iterateThroughStrategies",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Extracting/Extractor.php",
            "line": 116,
            "function": "fetchResponses",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 118,
            "function": "processRoute",
            "class": "Knuckles\\Scribe\\Extracting\\Extractor",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 75,
            "function": "extractEndpointsInfoFromLaravelApp",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/GroupedEndpoints/GroupedEndpointsFromApp.php",
            "line": 51,
            "function": "extractEndpointsInfoAndWriteToDisk",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/knuckleswtf/scribe/src/Commands/GenerateDocumentation.php",
            "line": 50,
            "function": "get",
            "class": "Knuckles\\Scribe\\GroupedEndpoints\\GroupedEndpointsFromApp",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 36,
            "function": "handle",
            "class": "Knuckles\\Scribe\\Commands\\GenerateDocumentation",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Util.php",
            "line": 41,
            "function": "Illuminate\\Container\\{closure}",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 93,
            "function": "unwrapIfClosure",
            "class": "Illuminate\\Container\\Util",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php",
            "line": 37,
            "function": "callBoundMethod",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Container/Container.php",
            "line": 651,
            "function": "call",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 136,
            "function": "call",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Command/Command.php",
            "line": 291,
            "function": "execute",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Command.php",
            "line": 121,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Command\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 989,
            "function": "run",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 299,
            "function": "doRunCommand",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/symfony/console/Application.php",
            "line": 171,
            "function": "doRun",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Console/Application.php",
            "line": 102,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php",
            "line": 129,
            "function": "run",
            "class": "Illuminate\\Console\\Application",
            "type": "->"
        },
        {
            "file": "/home/ewilan/www/bookshelves-back/artisan",
            "line": 37,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Console\\Kernel",
            "type": "->"
        }
    ]
}
 

Request      

GET api/reviews/{model}/{slug}

GET Reviews by user.

requires authentication

Route name: api.reviews.user

Example request:
curl --request GET \
    --get "https://bookshelves.ink/api/reviews/{user_id}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/{user_id}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'https://bookshelves.ink/api/reviews/{user_id}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reviews/{user_id}

POST Store new review.

requires authentication

Route name: api.reviews.store

Example request:
curl --request POST \
    "https://bookshelves.ink/api/reviews/store/{model}/{slug}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/store/{model}/{slug}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/reviews/store/{model}/{slug}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reviews/store/{model}/{slug}

POST Edit review.

requires authentication

Route name: api.reviews.edit

Example request:
curl --request POST \
    "https://bookshelves.ink/api/reviews/edit/{book_slug}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/edit/{book_slug}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/reviews/edit/{book_slug}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reviews/edit/{book_slug}

POST Update review.

requires authentication

Route name: api.reviews.update

Example request:
curl --request POST \
    "https://bookshelves.ink/api/reviews/update/{book_slug}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/update/{book_slug}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/reviews/update/{book_slug}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reviews/update/{book_slug}

POST Destroy review.

requires authentication

Route name: api.reviews.destroy

Example request:
curl --request POST \
    "https://bookshelves.ink/api/reviews/destroy/{book_slug}" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://bookshelves.ink/api/reviews/destroy/{book_slug}"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'https://bookshelves.ink/api/reviews/destroy/{book_slug}',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reviews/destroy/{book_slug}