{
  "openapi": "3.1.0",
  "info": {
    "title": "ELIB public API",
    "version": "1.0.0",
    "summary": "Read-only access to the ELIB (elib.am) free Armenian digital library.",
    "description": "Books, authors, subjects, libraries and blog posts of elib.am, the same data its website and mobile app show. GET only, no key needed. Every reply is {\"ok\": true, \"data\": ...} or {\"ok\": false, \"error\": {\"code\": ..., \"message\": ...}}. Send Accept-Language (hy, en or ru) for subject names and book slugs in that language; en gives the Latin slug used in canonical page addresses. Titles and author names stay in their original language. AI agents can also use the MCP server at https://elib.am/mcp. ELIB is free and runs on donations: if you show its books, link each book page and mention https://elib.am/donate. Reading a scan and downloading need the person's own free account (see https://elib.am/auth.md).",
    "contact": { "name": "ELIB", "url": "https://elib.am/contact", "email": "info@elib.am" }
  },
  "externalDocs": { "description": "Developer page", "url": "https://elib.am/developers" },
  "servers": [{ "url": "https://elib.am/api/v1" }],
  "tags": [
    { "name": "Books" }, { "name": "Authors" }, { "name": "Catalogue" }, { "name": "Content" }
  ],
  "paths": {
    "/search": {
      "get": {
        "tags": ["Books"],
        "operationId": "searchBooks",
        "summary": "Search the library",
        "description": "The website's /search: the words are looked up in every book's title, author and description (Latin letters find Armenian names too), then inside the books' text. 20 a page, best match first. Limited to 60 requests a minute per address.",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string", "minLength": 2 }, "example": "Թումանյան" },
          { "$ref": "#/components/parameters/page" },
          { "name": "lang", "in": "query", "description": "Language id (from /facets), e.g. 1 Armenian, 2 English, 3 Russian.", "schema": { "type": "integer" } },
          { "name": "subject", "in": "query", "description": "Subject id (from /subjects).", "schema": { "type": "integer" } },
          { "$ref": "#/components/parameters/acceptLanguage" }
        ],
        "responses": {
          "200": {
            "description": "Matching books",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkSearchPage" } } }
          },
          "429": { "$ref": "#/components/responses/TooMany" }
        }
      }
    },
    "/books": {
      "get": {
        "tags": ["Books"],
        "operationId": "listBooks",
        "summary": "List published books",
        "parameters": [
          { "name": "q", "in": "query", "description": "Words in the title or description.", "schema": { "type": "string" } },
          { "name": "subject", "in": "query", "description": "Subject id.", "schema": { "type": "integer" } },
          { "name": "author", "in": "query", "description": "Author id.", "schema": { "type": "integer" } },
          { "name": "lang", "in": "query", "description": "Book language.", "schema": { "type": "string", "enum": ["hy", "en", "ru"] } },
          { "name": "language_id", "in": "query", "description": "Language id from /facets.", "schema": { "type": "integer" } },
          { "name": "type", "in": "query", "description": "Material type id from /facets.", "schema": { "type": "integer" } },
          { "name": "repository", "in": "query", "description": "1 for the repository collection only.", "schema": { "type": "string", "enum": ["1"] } },
          { "name": "sort", "in": "query", "schema": { "type": "string", "enum": ["new", "popular", "title", "download"], "default": "new" } },
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/perPage" },
          { "$ref": "#/components/parameters/acceptLanguage" }
        ],
        "responses": {
          "200": { "description": "A page of books", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkBookPage" } } } }
        }
      }
    },
    "/books/{book}": {
      "get": {
        "tags": ["Books"],
        "operationId": "getBook",
        "summary": "One book",
        "description": "Details, description, a passage of the text, the author, related and similar books.",
        "parameters": [{ "$ref": "#/components/parameters/book" }, { "$ref": "#/components/parameters/acceptLanguage" }],
        "responses": {
          "200": { "description": "The book", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkBookDetail" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/books/{book}/reviews": {
      "get": {
        "tags": ["Books"],
        "operationId": "getBookReviews",
        "summary": "Readers' reviews of a book",
        "parameters": [{ "$ref": "#/components/parameters/book" }, { "$ref": "#/components/parameters/page" }, { "$ref": "#/components/parameters/perPage" }],
        "responses": {
          "200": { "description": "Approved reviews, newest first", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/subjects": {
      "get": {
        "tags": ["Catalogue"],
        "operationId": "listSubjects",
        "summary": "Subjects with books, largest first",
        "parameters": [{ "$ref": "#/components/parameters/acceptLanguage" }],
        "responses": {
          "200": { "description": "Subjects", "content": { "application/json": { "schema": { "type": "object", "properties": {
            "ok": { "type": "boolean" },
            "data": { "type": "array", "items": { "$ref": "#/components/schemas/Subject" } }
          } } } } }
        }
      }
    },
    "/facets": {
      "get": {
        "tags": ["Catalogue"],
        "operationId": "listFacets",
        "summary": "Every filter's options with book counts",
        "description": "Languages, material types, libraries, physical books and subjects, each with its id, name and number of books.",
        "parameters": [{ "name": "lang", "in": "query", "description": "Language of the names.", "schema": { "type": "string", "enum": ["hy", "en", "ru"] } }],
        "responses": { "200": { "description": "Filter options", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } } }
      }
    },
    "/authors": {
      "get": {
        "tags": ["Authors"],
        "operationId": "listAuthors",
        "summary": "Authors with published books",
        "parameters": [
          { "name": "q", "in": "query", "description": "Part of the name; Latin spellings find Armenian names.", "schema": { "type": "string" } },
          { "name": "order", "in": "query", "schema": { "type": "string", "enum": ["name", "books", "id"], "default": "name" } },
          { "name": "photo", "in": "query", "description": "1 for authors with a portrait only.", "schema": { "type": "string", "enum": ["1"] } },
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/perPage" }
        ],
        "responses": { "200": { "description": "A page of authors", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkAuthorPage" } } } } }
      }
    },
    "/authors/{author}": {
      "get": {
        "tags": ["Authors"],
        "operationId": "getAuthor",
        "summary": "One author and their books",
        "parameters": [
          { "name": "author", "in": "path", "required": true, "description": "Author id or slug.", "schema": { "type": "string" }, "example": "aleksandr-shirvanzade" },
          { "$ref": "#/components/parameters/acceptLanguage" }
        ],
        "responses": {
          "200": { "description": "The author", "content": { "application/json": { "schema": { "type": "object", "properties": {
            "ok": { "type": "boolean" },
            "data": { "type": "object", "properties": {
              "author": { "$ref": "#/components/schemas/Author" },
              "books": { "type": "array", "items": { "$ref": "#/components/schemas/Book" } }
            } }
          } } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/home": {
      "get": {
        "tags": ["Catalogue"],
        "operationId": "getHome",
        "summary": "New and most-read books, subjects and totals",
        "parameters": [{ "$ref": "#/components/parameters/acceptLanguage" }],
        "responses": { "200": { "description": "Home feed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } } }
      }
    },
    "/libraries": {
      "get": {
        "tags": ["Content"],
        "operationId": "listLibraries",
        "summary": "Libraries in Armenia",
        "description": "Name, city, address, phone, e-mail, website, opening hours, description and map position.",
        "parameters": [{ "$ref": "#/components/parameters/acceptLanguage" }],
        "responses": { "200": { "description": "Libraries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } } }
      }
    },
    "/blog": {
      "get": {
        "tags": ["Content"],
        "operationId": "listBlogPosts",
        "summary": "Blog posts, newest first",
        "parameters": [{ "$ref": "#/components/parameters/page" }, { "$ref": "#/components/parameters/perPage" }, { "$ref": "#/components/parameters/acceptLanguage" }],
        "responses": { "200": { "description": "A page of posts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } } }
      }
    },
    "/blog/{slug}": {
      "get": {
        "tags": ["Content"],
        "operationId": "getBlogPost",
        "summary": "One blog post with its body as HTML",
        "parameters": [{ "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "The post", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "page": { "name": "page", "in": "query", "schema": { "type": "integer", "minimum": 1, "default": 1 } },
      "perPage": { "name": "per_page", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 } },
      "book": { "name": "book", "in": "path", "required": true, "description": "Book id or any of its slugs (Latin, Armenian or Russian).", "schema": { "type": "string" }, "example": "arshipelagy-kraki-mej-zhyul-vern" },
      "acceptLanguage": { "name": "Accept-Language", "in": "header", "description": "hy (default), en or ru.", "schema": { "type": "string", "enum": ["hy", "en", "ru"] } }
    },
    "responses": {
      "NotFound": { "description": "No such item", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "TooMany": { "description": "Too many requests; see Retry-After" }
    },
    "schemas": {
      "Ok": { "type": "object", "properties": { "ok": { "type": "boolean", "const": true }, "data": {} }, "required": ["ok", "data"] },
      "Error": { "type": "object", "properties": {
        "ok": { "type": "boolean", "const": false },
        "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } }
      } },
      "AuthorRef": { "type": "object", "properties": { "id": { "type": "integer" }, "slug": { "type": "string" }, "name": { "type": "string" } } },
      "Book": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "slug": { "type": "string" },
          "title": { "type": "string", "description": "As printed, in the original language." },
          "cover": { "type": ["string", "null"], "format": "uri" },
          "authors": { "type": "array", "items": { "$ref": "#/components/schemas/AuthorRef" } },
          "subjects": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" } } } },
          "language": { "type": ["string", "null"] },
          "has_file": { "type": "boolean" },
          "has_text": { "type": "boolean", "description": "True when the book's full text is public. Full texts are not public at the moment." },
          "views": { "type": "integer" },
          "web_url": { "type": "string", "format": "uri", "description": "The book's page on elib.am; cite this." },
          "created_at": { "type": ["string", "null"] }
        }
      },
      "BookDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/Book" },
          { "type": "object", "properties": {
            "description": { "type": ["string", "null"] },
            "type": { "type": ["string", "null"], "description": "Kind of material, e.g. book or thesis." },
            "content_excerpt": { "type": "string" },
            "rating": { "type": ["number", "null"] },
            "reviews_count": { "type": "integer" },
            "author": { "type": ["object", "null"] },
            "related": { "type": "object" },
            "similar": { "type": "array", "items": { "$ref": "#/components/schemas/Book" } }
          } }
        ]
      },
      "Author": { "type": "object", "properties": {
        "id": { "type": "integer" }, "slug": { "type": "string" }, "name": { "type": "string" },
        "books_count": { "type": "integer" }, "bio": { "type": ["string", "null"] },
        "dates": { "type": "string", "description": "Life dates, e.g. 1858-1935." },
        "photo": { "type": ["string", "null"], "format": "uri" }
      } },
      "Subject": { "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "count": { "type": "integer" } } },
      "PageMeta": { "type": "object", "properties": { "page": { "type": "integer" }, "per_page": { "type": "integer" }, "total": { "type": "integer" } } },
      "OkBookPage": { "type": "object", "properties": { "ok": { "type": "boolean" }, "data": { "allOf": [
        { "$ref": "#/components/schemas/PageMeta" },
        { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Book" } } } }
      ] } } },
      "OkSearchPage": { "type": "object", "properties": { "ok": { "type": "boolean" }, "data": { "allOf": [
        { "$ref": "#/components/schemas/PageMeta" },
        { "type": "object", "properties": {
          "query": { "type": "string" },
          "items": { "type": "array", "items": { "allOf": [
            { "$ref": "#/components/schemas/Book" },
            { "type": "object", "properties": {
              "snippet": { "type": "string", "description": "Matching passage, HTML-escaped, query words in <mark>." },
              "title_marked": { "type": "string" },
              "match": { "type": "string", "enum": ["title", "author", "description", "text"] }
            } }
          ] } }
        } }
      ] } } },
      "OkAuthorPage": { "type": "object", "properties": { "ok": { "type": "boolean" }, "data": { "allOf": [
        { "$ref": "#/components/schemas/PageMeta" },
        { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Author" } } } }
      ] } } },
      "OkBookDetail": { "type": "object", "properties": { "ok": { "type": "boolean" }, "data": { "$ref": "#/components/schemas/BookDetail" } } }
    }
  }
}
