{
  "openapi": "3.0.0",
  "paths": {
    "/search/categories": {
      "get": {
        "operationId": "SearchController_categories",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List card categories (key, name, parent, cards count)",
        "tags": [
          "Search"
        ]
      }
    },
    "/search/suggestions": {
      "get": {
        "operationId": "SearchController_suggest",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "encId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get search suggestions (autocomplete) from titles and content",
        "tags": [
          "Search"
        ]
      }
    },
    "/search": {
      "get": {
        "operationId": "SearchController_search",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "description": "Search query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by content type. Multiple types can be comma-separated (e.g., surah,book).",
            "schema": {
              "enum": [
                "surah",
                "book",
                "aya",
                "phrase",
                "encyclopedia"
              ],
              "type": "string"
            }
          },
          {
            "name": "encId",
            "required": false,
            "in": "query",
            "description": "Filter by specific Encyclopedia ID (e.g., fadel, maysar)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "description": "Card category key(s), \"<table>:<item>\", comma-separated (see /search/categories). Restricts results to cards in any of them.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "facets",
            "required": false,
            "in": "query",
            "description": "\"categories\" adds categoryCounts: matching cards per category key, ignoring the category filter. \"props\" adds propCounts: matching cards per property value, ignoring the prop filters.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "surah",
            "required": false,
            "in": "query",
            "description": "Surah number (1-114): only the ayas of that surah, Arabic and translations.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prop",
            "required": false,
            "in": "query",
            "description": "A card property filter \"<id>=<value>\" (see /enc/:encId/properties), repeatable. Restricts results to cards with every one.",
            "schema": {}
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Search across all content",
        "tags": [
          "Search"
        ]
      }
    },
    "/quran/search": {
      "get": {
        "operationId": "QuranController_search",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "1-50, default 10",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "description": "Language iso code of the translation returned with each aya (default en)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Quran search by words and meaning (the ayas of GET /hybrid-search)",
        "tags": [
          "quran"
        ]
      }
    },
    "/quran/surahs": {
      "get": {
        "operationId": "QuranController_getSurahs",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all surahs",
        "tags": [
          "quran"
        ]
      }
    },
    "/quran/surah-names": {
      "get": {
        "operationId": "QuranController_getSurahNames",
        "parameters": [
          {
            "name": "language",
            "required": false,
            "in": "query",
            "description": "Language iso code (e.g. en, fr, ar). 404 if unknown.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "surah_no",
            "required": false,
            "in": "query",
            "description": "Surah number (1-114). 404 if unknown.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Case-insensitive substring of surah_name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List surah names in all languages (synced from icadb)",
        "tags": [
          "quran"
        ]
      }
    },
    "/quran/surahs/{surahNo}": {
      "get": {
        "operationId": "QuranController_getSurahAyas",
        "parameters": [
          {
            "name": "surahNo",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "langKey",
            "required": false,
            "in": "query",
            "description": "ISO code for translation (e.g. en)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "description": "Language iso code to filter aya translations (e.g. en)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get surah details with ayas",
        "tags": [
          "quran"
        ]
      }
    },
    "/quran/translation-keys": {
      "get": {
        "operationId": "QuranController_getTranslationKeys",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all available translation languages",
        "tags": [
          "quran"
        ]
      }
    },
    "/hybrid-search": {
      "get": {
        "operationId": "HybridSearchController_query",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "aya, book, card - comma-separated. Without it: all three, interleaved, at most 2 hits per book or card",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "description": "The reader's language: searched with Arabic, and the language of each aya's translation (default ar)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "langs",
            "required": false,
            "in": "query",
            "description": "Languages to search instead, comma-separated, or \"all\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "surah",
            "required": false,
            "in": "query",
            "description": "Surah numbers: ayas from these only",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "book",
            "required": false,
            "in": "query",
            "description": "Book project ids: passages from these only",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "enc",
            "required": false,
            "in": "query",
            "description": "Encyclopedia ids: cards from these only",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ratio",
            "required": false,
            "in": "query",
            "description": "Weight of meaning against words, 0-1 (default 0.75)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "1-50, default 10",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "Default 0; offset + limit <= 1000",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exact",
            "required": false,
            "in": "query",
            "description": "true: the words as typed, together and in order, no meaning side. A query in quotes is exact too",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "required": false,
            "in": "query",
            "description": "\"hits\": results shaped like GET /search (hits, _formatted, metadata) for the search page",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "description": "Card category keys (\"<table>:<item>\"), comma-separated: cards in any of them, and only cards",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "facets",
            "required": false,
            "in": "query",
            "description": "\"categories\": adds categoryCounts, matching cards per category; \"props\": adds propCounts, matching cards per property value",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "intent",
            "required": false,
            "in": "query",
            "description": "\"off\": do not narrow the types by what the question asks for (\"كتاب عن ...\")",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prop",
            "required": false,
            "in": "query",
            "description": "A card property filter \"<id>=<value>\" (see /enc/:encId/properties), repeatable: cards with every one, and only cards",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Search ayas, book passages and encyclopedia cards by words and meaning, with filters",
        "tags": [
          "Search"
        ]
      }
    },
    "/books": {
      "get": {
        "operationId": "BooksController_getBooks",
        "parameters": [
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "description": "Adds translated_title and translated_description for books translated into this language",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all books",
        "tags": [
          "books"
        ]
      }
    },
    "/books/pdfs": {
      "get": {
        "description": "One row per book, language and Arabic version, with the public object URL, size and the title the file is named after in that language. Written by `npm run books:pdf`; read by the sitemap and the download proxy.",
        "operationId": "BooksController_getBookPdfs",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Every PDF copy of every book",
        "tags": [
          "books"
        ]
      }
    },
    "/books/{projectId}": {
      "get": {
        "operationId": "BooksController_getBookDetails",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get book details and versions",
        "tags": [
          "books"
        ]
      }
    },
    "/books/{projectId}/versions/{versionName}": {
      "get": {
        "operationId": "BooksController_getBookVersionContent",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "versionName",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get content of a specific book version",
        "tags": [
          "books"
        ]
      }
    },
    "/books/{projectId}/languages": {
      "get": {
        "operationId": "BooksController_getBookLanguages",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List available translation languages for a book",
        "tags": [
          "books"
        ]
      }
    },
    "/books/{projectId}/translations/{isoCode}": {
      "get": {
        "operationId": "BooksController_getBookTranslation",
        "parameters": [
          {
            "name": "projectId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "isoCode",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get translated content",
        "tags": [
          "books"
        ]
      }
    },
    "/enc": {
      "get": {
        "operationId": "EncController_getEncyclopedias",
        "parameters": [
          {
            "name": "lang",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all encyclopedias; with ?lang=, cards_count counts that language only",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc/{encId}/cards": {
      "get": {
        "operationId": "EncController_getEncyclopediaCards",
        "parameters": [
          {
            "name": "encId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "With page: paginate, at most 100.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "description": "This language plus the Arabic it falls back to; Arabic only when absent.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "translated",
            "required": false,
            "in": "query",
            "description": "1: only cards that exist in lang.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "required": false,
            "in": "query",
            "description": "Comma-separated sentence field names (e.g. عنوان الحديث,متن الحديث). Only those sentences are returned; cards without them still appear. Cuts the full set to a third for listings.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "description": "Category key \"<table>:<item>\": only cards in it or under it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prop",
            "required": false,
            "in": "query",
            "description": "A property filter \"<id>=<value>\" (see /enc/:encId/properties), repeatable: only cards with every one.",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get cards for a specific encyclopedia",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc/{encId}/properties": {
      "get": {
        "operationId": "EncController_getEncyclopediaProperties",
        "parameters": [
          {
            "name": "encId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "translated",
            "required": false,
            "in": "query",
            "description": "1: count only cards that exist in lang.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The property filters an encyclopedia's listing offers, with values and card counts",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc/{encId}/categories": {
      "get": {
        "operationId": "EncController_getEncyclopediaCategories",
        "parameters": [
          {
            "name": "encId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "translated",
            "required": false,
            "in": "query",
            "description": "1: count only cards that exist in lang.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The categories of an encyclopedia's cards, with card counts",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc/{encId}/card-languages": {
      "get": {
        "operationId": "EncController_getCardLanguages",
        "parameters": [
          {
            "name": "encId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The languages each card of an encyclopedia exists in, by card id",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc/cards/{cardId}": {
      "get": {
        "operationId": "EncController_getCard",
        "parameters": [
          {
            "name": "cardId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get a specific card with its versions and sentences",
        "tags": [
          "enc"
        ]
      }
    },
    "/enc-meta": {
      "get": {
        "operationId": "EncMetaController_index",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The metadata projects and what is stored for each",
        "tags": [
          "enc-meta"
        ]
      }
    },
    "/enc-meta/{projectKey}": {
      "get": {
        "operationId": "EncMetaController_labels",
        "parameters": [
          {
            "name": "projectKey",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Metadata phrases by key, in one language",
        "tags": [
          "enc-meta"
        ]
      }
    },
    "/enc-meta/{projectKey}/values": {
      "get": {
        "operationId": "EncMetaController_values",
        "parameters": [
          {
            "name": "projectKey",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "The same phrases keyed by their Arabic original",
        "tags": [
          "enc-meta"
        ]
      }
    },
    "/languages": {
      "get": {
        "operationId": "LanguagesController_getLanguages",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Get all stored languages",
        "tags": [
          "languages"
        ]
      }
    }
  },
  "info": {
    "title": "Islamenc API",
    "version": "1.0",
    "description": "The public, read-only endpoints. Base URL: https://islamenc.com/api. No authentication; 10 requests per second per IP address."
  },
  "tags": [
    {
      "name": "Search"
    },
    {
      "name": "books"
    },
    {
      "name": "enc"
    },
    {
      "name": "enc-meta"
    },
    {
      "name": "languages"
    },
    {
      "name": "quran"
    }
  ],
  "servers": [
    {
      "url": "https://islamenc.com/api",
      "description": "Production"
    }
  ]
}
