This is the full developer documentation for Islamenc API
# Islamenc API
> The Quran with 70 translation editions, more than 300 books in up to 64 languages, and twelve encyclopedias of hadith, terms, names and places, over one public JSON API. No key, no sign-up.
```plaintext
https://islamenc.com/api
```
[Quran](/reference/quran/)114 surahs, every aya in Uthmani and standard spelling, translations by edition, surah names in 78 languages.
[Books](/reference/books/)The catalogue, each book's chapters and paragraphs, its translations phrase by phrase, and PDF and Word copies.
[Encyclopedias](/reference/encyclopedias/)Cards with their fields in each language, categories, filterable properties, and the vocabulary of the hadith collection.
[Search](/reference/search/)Hybrid search by words and meaning across everything, keyword search, suggestions and category facets.
## In short
[Section titled “In short”](#in-short)
| | |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Base URL | `https://islamenc.com/api` |
| Format | JSON, UTF-8. Arabic text is returned as is (Uthmani script where the source has it). |
| Authentication | None. Every endpoint documented here is public and read-only. |
| Rate limit | 10 requests per second per IP address, with bursts of up to 40. Past that the API answers `429 Too Many Requests`. |
| CORS | Enabled for every origin: the API can be called from a browser. |
| Caching | Most answers carry `Cache-Control: public, max-age=600`. Content changes a few times a week, so cache freely. |
| For assistants | [/llms.txt](/llms.txt) and [/llms-full.txt](/llms-full.txt) hold these docs as Markdown; [/openapi.json](/openapi.json) is the machine-readable contract. |
| Terms | Free to use with attribution. See [Terms of use](/terms/). |
## Your first request
[Section titled “Your first request”](#your-first-request)
* curl
```bash
curl "https://islamenc.com/api/quran/surahs/112?lang=en"
```
* JavaScript
```js
const res = await fetch("https://islamenc.com/api/quran/surahs/112?lang=en");
const { surah, ayahs } = await res.json();
console.log(surah.surah_name, ayahs.length); // الإخلَاص 4
```
* Python
```python
import requests
r = requests.get("https://islamenc.com/api/quran/surahs/112", params={"lang": "en"})
data = r.json()
print(data["surah"]["surah_name"], len(data["ayahs"]))
```
```json
{
"surah": { "surah_no": 112, "surah_name": "الإخلَاص", "ar_uthmani_name": "ﰝ", "ayas_count": 4 },
"ayahs": [
{
"id": 12458,
"aya_no": 1,
"aya_no_uthmani": "١",
"aya_uthmani": "قُلۡ هُوَ ٱللَّهُ أَحَدٌ",
"aya_imlaei": "قُلْ هُوَ اللَّهُ أَحَدٌ",
"translations": [
{
"id": 872051,
"translationKey": { "key": "english_hilali_khan", "title": "الترجمة الإنجليزية - تقي الدين الهلالي ومحسن خان", "language": { "isoCode": "en", "englishName": "English", "direction": "ltr" } },
"content": "1. Say (O Muhammad صلى الله عليه وسلم): \"He is Allâh, (the) One.",
"footnotes": null
}
]
}
]
}
```
Next: getting started
Languages, identifiers, pagination, errors and the rate limit, in five minutes. [Read it](/getting-started/).
Try it in the browser
Every public endpoint with a built-in client on the [OpenAPI page](/reference/openapi/).
# Getting started
> Every endpoint lives under https://islamenc.com/api and answers JSON. There is no API key and nothing to sign; a plain GET is enough. Responses are UTF-8, and Arabic comes back exactly as the source h
## Base URL and format
[Section titled “Base URL and format”](#base-url-and-format)
Every endpoint lives under `https://islamenc.com/api` and answers JSON. There is no API key and nothing to sign; a plain `GET` is enough. Responses are UTF-8, and Arabic comes back exactly as the source has it: Quranic text in Uthmani script with its marks, and in standard (imla’i) spelling beside it where the endpoint offers both.
```bash
curl -s "https://islamenc.com/api/languages" | head -c 300
```
```json
[{"isoCode":"aa","arabicName":"عفري","englishName":"Afar","nativeName":"Qafár af","direction":"ltr"}, ...
```
## Languages
[Section titled “Languages”](#languages)
Languages are named by ISO code (`en`, `fr`, `bn`, `prs`…). `GET /languages` lists the 147 the platform knows, each with its names and writing direction. Not every book, card or surah exists in every language: ask a book for `/languages`, an encyclopedia for `/card-languages`, and the Quran for `/translation-keys` before you request a language.
Most endpoints take `lang`:
* On listings it adds the translated title or description where one exists (`/books?lang=fr`), or restricts the count to that language (`/enc?lang=en`).
* On content it selects the translation (`/quran/surahs/2?lang=fr`, `/enc/cards/7913?lang=en`). The Arabic original always comes along.
Arabic is the source language of everything, so `lang=ar`, or no `lang` at all, is always complete.
## Identifiers
[Section titled “Identifiers”](#identifiers)
| Thing | Identifier | Example |
| -------------- | ------------------------------------------------- | ------------------------------------------------------ |
| Surah | `surah_no`, 1 to 114 | `2` |
| Aya | `surah_no` and `aya_no` | surah `2`, aya `255` |
| Book | `project_id` | `36` |
| Book version | `version_name` | `2.0` |
| Encyclopedia | `external_id` | `101` is the hadith encyclopedia |
| Card | `external_id` | `7913` |
| Category | `":- "` | `11:2` is “الحديث وعلومه” in the sharia classification |
| Property value | `"
:- "` under a property id `t
` | `t40` = `40:1` is a short card |
All of them are stable: a card keeps its `external_id` across versions, and a book its `project_id` across editions.
## Pagination
[Section titled “Pagination”](#pagination)
Two styles, depending on the endpoint:
* **Page and limit** on the card listing: `GET /enc/101/cards?page=2&limit=20` answers `{ "cards": [...], "total": 839 }`. `limit` is at most 100. Without `page` the whole set comes back in one answer, which is what the site itself uses, and is a few megabytes for the hadith encyclopedia.
* **Offset and limit** on the search endpoints: `GET /hybrid-search?q=...&offset=10&limit=10`. `limit` is at most 50 and `offset + limit` at most 1000. `hasMore` (with `format=hits`) says whether another page exists.
The Quran, the catalogue and the languages have no pages: a surah, the book list or the language list comes whole.
## Errors
[Section titled “Errors”](#errors)
The API uses HTTP status codes and a small JSON body:
```json
{ "statusCode": 404, "message": "Book 999 not found" }
```
| Status | When |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `400` | A parameter is missing or malformed (`q` absent, `type` unknown, a limit out of range). The `message` says which. |
| `404` | The surah, book, version, card or language does not exist, or the book has been withdrawn. |
| `429` | More than 10 requests a second from one address. Slow down and retry after a moment. |
| `500` / `502` / `503` | Something failed on our side or the API is restarting. Retry with backoff. |
A missing book detail (`GET /books/{projectId}`) currently answers `200` with an empty body rather than `404`; check for an empty response.
## Rate limit and caching
[Section titled “Rate limit and caching”](#rate-limit-and-caching)
Ten requests a second per IP address, with room for short bursts of up to forty. That is plenty for a page that loads a surah and a few cards, and for a crawler that walks the catalogue politely. If you need sustained higher volume, [tell us](/terms/#contact) what you are building.
Every answer that can be cached says so: `Cache-Control: public, max-age=600, stale-while-revalidate=3600`. Content is synchronised from the source platform a few times a week, so caching answers for an hour on your side costs nothing in freshness. The two heaviest answers, a whole encyclopedia’s cards and the book catalogue, are cached by the API itself and come back in milliseconds once warm.
## Calling from a browser
[Section titled “Calling from a browser”](#calling-from-a-browser)
CORS is open, so the API can be called straight from client-side code:
```js
const q = encodeURIComponent("فضل الصدقة");
const res = await fetch(`https://islamenc.com/api/hybrid-search?q=${q}&limit=5&lang=en`);
const { results } = await res.json();
```
Remember to `encodeURIComponent` Arabic query strings and field names (`fields=متن الحديث` on the card listing) before putting them in a URL.
## What the API does not do
[Section titled “What the API does not do”](#what-the-api-does-not-do)
* No writing: nothing here creates, edits or deletes content. Content comes from the source platform (ICADB and QuranEnc) and is synchronised a few times a week.
* No accounts, favourites or user state.
* No audio: the Quran is text and translations only.
# Books
> The library: more than 300 books, each with one or more Arabic editions, translations into up to 64 languages, and PDF and Word copies.
The library: more than 300 books, each with one or more Arabic editions, translations into up to 64 languages, and PDF and Word copies.
## The catalogue
[Section titled “The catalogue”](#the-catalogue)
GET/books
| Parameter | | |
| --------- | -------- | --------------------------------------------------------------------------------------------- |
| `lang` | optional | Adds `translated_title` and `translated_description` for books translated into this language. |
Every book that is published, with its versions and the languages of each. About 800 KB; cache it.
```bash
curl "https://islamenc.com/api/books?lang=en"
```
```json
[
{
"project_id": 36,
"title": "الأصول الثلاثة وأدلتها",
"name": "الأصول الثلاثة وأدلتها",
"description": "...",
"is_hidden": false,
"versions": [
{
"id": 3702,
"version_number": "2.00",
"version_name": "2.0",
"is_latest": true,
"translations": [
{ "id": 17308, "language": { "isoCode": "fr", "englishName": "French", "nativeName": "Français", "direction": "ltr" }, "version_number": 1, "source": "molhem" }
]
}
],
"available_languages": ["ar", "en", "fr", "..."],
"language_count": 64,
"translated_title": "The Three Fundamental Principles",
"translated_description": "..."
}
]
```
`available_languages` and `language_count` cover the latest version. `source` names where a translation came from (`molhem`, `islamhouse`…).
## One book
[Section titled “One book”](#one-book)
GET/books/{projectId}
The book’s record with its versions and translations (as above) plus every printable copy:
```json
{
"project_id": 36,
"title": "الأصول الثلاثة وأدلتها",
"versions": [ ... ],
"pdfs": [
{ "id": 383, "project_id": 36, "lang": "af", "version_name": "2.0", "source": "molhem", "url": "https://islamenc-files.hel1.your-objectstorage.com/pdf/36/af-2.0.pdf", "bytes": 412433, "updated_at": "2026-10-02T09:11:40.000Z" }
],
"docxs": [
{ "id": 120, "project_id": 36, "lang": "af", "version_name": "2.0", "url": "https://islamenc-files.hel1.your-objectstorage.com/docx/36/af-2.0.docx", "bytes": 98311, "updated_at": "2026-10-12T02:30:11.000Z" }
]
}
```
The `url`s are public and direct; link to them or download them. A withdrawn book answers with an empty body.
## A version’s text
[Section titled “A version’s text”](#a-versions-text)
GET/books/{projectId}/versions/{versionName}
The Arabic text of one edition, as chapters of phrases, in reading order. `versionName` is the `version_name` from the catalogue (`2.0`).
```bash
curl "https://islamenc.com/api/books/36/versions/2.0"
```
```json
[
{
"id": 7283,
"serial": 1,
"name": "الأصول الثلاثة وأدلتها",
"phrases": [
{
"phrase_id": "21fd289f-c28c-458b-bae3-d8f5741da543",
"group_id": 360,
"group_order": 10,
"arabic_text": "(اعلم) رحمك الله أنه يجب على كل مسلم ومسلمة تعلم هذه الثلاث مسائل والعمل بهن.",
"text_type": "p",
"content_type_id": 4,
"tag": "p",
"hadith_card_id": null,
"hadith_match_score": null,
"hadith_link_source": null,
"links": []
}
]
}
]
```
| Field | |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `group_id`, `group_order` | A group is a paragraph; `group_order` orders the sentences in it. Join a group’s phrases to rebuild the paragraph. |
| `tag` | The HTML-like role of the phrase: `p`, `h1`…`h4`, `li`, `blockquote`. `text_type` is the same in the source’s own vocabulary. |
| `content_type_id` | The kind of text: `1` title, `4` body, and the footnote and heading kinds. |
| `hadith_card_id` | When the phrase quotes a hadith that the hadith encyclopedia has, the card’s `external_id`, with the match score and how it was found. |
| `links` | Cross-references the site found in this phrase, for its own pages; empty for most phrases. |
## A translation
[Section titled “A translation”](#a-translation)
GET/books/{projectId}/translations/{isoCode}
The book in one language, phrase by phrase, each paired with its Arabic source. `isoCode` is a language from `GET /books/{projectId}/languages`.
```bash
curl "https://islamenc.com/api/books/36/translations/fr"
```
```json
[
{
"id": 17308,
"arabicVersion": { "id": 3702, "version_number": "2.00", "version_name": "2.0", "is_latest": true },
"language": { "isoCode": "fr", "englishName": "French", "nativeName": "Français", "direction": "ltr" },
"version_number": 1,
"source": "molhem",
"phrases": [
{
"id": 7033944,
"phrase": {
"phrase_id": "fee0fb72-8ccb-4aac-80bb-cc7e872d9ea1",
"chapter": { "id": 7285, "serial": 2, "name": "ثلاثة الأصول وأدلتها" },
"group_id": 55,
"group_order": 3,
"arabic_text": "[آل عمران: 18]"
},
"translated_text": "[Âl ‘Imrân : 18]"
}
]
}
]
```
One element per translated Arabic version (usually the latest). Group the phrases by `phrase.chapter` and `phrase.group_id` to render chapters and paragraphs, exactly as for the Arabic.
## Languages of a book
[Section titled “Languages of a book”](#languages-of-a-book)
GET/books/{projectId}/languages
```json
["aa", "af", "ak", "am", "as", "en", "fr", "..."]
```
## Every PDF
[Section titled “Every PDF”](#every-pdf)
GET/books/pdfs
One row per book, language and version, for the whole library (about 2,900 rows, 800 KB): what the sitemap and a download mirror need.
```json
[
{ "project_id": 36, "lang": "fr", "version_name": "2.0", "source": "molhem", "bytes": 466120, "url": "https://islamenc-files.hel1.your-objectstorage.com/pdf/36/fr-2.0.pdf", "updated_at": "2026-10-02T09:11:40.000Z", "title": "Les trois fondements" }
]
```
`title` is the book’s title in that language, the name the file is meant to be saved under.
# Encyclopedias
> Twelve collections of cards: hadith, questions and answers, Islamic terms, the names of Allah, places, and introductions to Islam. Each card is a set of named fields in one or more languages, with cat
Twelve collections of cards: hadith, questions and answers, Islamic terms, the names of Allah, places, and introductions to Islam. Each card is a set of named fields in one or more languages, with categories and properties to filter by.
## The encyclopedias
[Section titled “The encyclopedias”](#the-encyclopedias)
GET/enc
| Parameter | | |
| --------- | -------- | ------------------------------------------------------------------------- |
| `lang` | optional | Count only the cards that exist in this language. Without it, every card. |
```bash
curl "https://islamenc.com/api/enc?lang=en"
```
```json
[
{ "external_id": "101", "name": "موسوعة الأحاديث", "description": null, "cards_count": 839 },
{ "external_id": "102", "name": "موسوعة الأسئلة والأجوبة للمسلمين", "description": null, "cards_count": 0 },
{ "external_id": "105", "name": "موسوعة المصطلحات", "description": null, "cards_count": 0 }
]
```
With `lang`, a count of `0` means the encyclopedia has no cards in that language; ask without `lang` for the Arabic total.
| id | Encyclopedia |
| --------------------------------- | ------------------------------------------------------------------------------- |
| `101` | Hadith (موسوعة الأحاديث): the most translated, 839 cards in up to 67 languages. |
| `102` | Questions and answers for Muslims. |
| `103` | Places. |
| `104` | The names of Allah. |
| `105`, `109` | Islamic terms. |
| `108` | Prophets and messengers. |
| `110`, `113`, `114`, `115`, `116` | Introducing Islam: pillars, beliefs, FAQs, messages and more. |
## The cards of an encyclopedia
[Section titled “The cards of an encyclopedia”](#the-cards-of-an-encyclopedia)
GET/enc/{encId}/cards
| Parameter | | |
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `page`, `limit` | optional | Paginate: `limit` at most 100. Without `page` the whole set comes back in one answer. |
| `lang` | optional | This language plus the Arabic it falls back to. Arabic only when absent. |
| `translated` | optional | `1`: only cards that exist in `lang`. |
| `fields` | optional | Comma-separated field names (`عنوان الحديث,متن الحديث`): only those sentences are returned. Cards without them still appear. Cuts the full set to a third. |
| `category` | optional | A category key `":- "`: only cards in it or under it. |
| `prop` | optional | A property filter `"="` (`t40=40:1`), repeatable: only cards with every one. |
With `page`:
```bash
curl "https://islamenc.com/api/enc/101/cards?page=1&limit=2&lang=en"
```
```json
{
"cards": [
{
"external_id": "14294",
"title": "لو أنكم كنتم توكلون على الله حق توكله لرزقكم كما يرزق الطير تغدو خماصا وتروح بطانا",
"is_hidden": false,
"categories": ["11:280", "11:3002", "11:5"],
"properties": { "t46": ["46:5", "46:6", "46:8", "46:9", "46:19"] },
"versions": [
{
"id": 2529,
"version_string": "2",
"sentences": [
{ "id": 35227, "field_name": "متن الحديث", "content": "«لَوْ أَنَّكُمْ كُنْتُمْ تَوَكَّلُونَ عَلَى اللهِ حَقَّ تَوَكُّلِهِ ...»", "language": "ar", "sentence_id": "7ad332b8-..." },
{ "id": 35228, "field_name": "Hadith text", "content": "If you were to rely on Allah as He should be relied on ...", "language": "en", "sentence_id": "7ad332b8-..." }
]
}
],
"displayed_properties": [
{ "id": "t11", "label": "التصنيف الشرعي", "values": [ { "key": "11:5", "name": "..." } ] }
]
}
],
"total": 839
}
```
Without `page` the answer is a plain array of the same cards. For the hadith encyclopedia that is \~2.6 MB with `fields` and \~7.5 MB without; it is served from a cache and is the right call for a client that wants everything once.
| Field | |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `versions[].sentences` | The card’s content. Each sentence is one field in one language: pair the Arabic and the translation by `sentence_id`. The hadith encyclopedia’s fields are `عنوان الحديث` (title), `بادئة الحديث` (narrator line), `متن الحديث` (text), `درجة الحديث` (grade), `التخريج` (source), `الشرح` (explanation), `الفوائد` (benefits) and a few more; translated sentences carry the field name in that language. |
| `categories` | Keys `"
:- "` including ancestors; names from [categories](#categories). |
| `properties` | Flat attributes, keyed by property id: item keys for a lookup property (`t46`), text for a free one (`book`, `chapter`). |
| `displayed_properties` | The properties the site shows for this card, resolved to labels and names, in display order. |
## One card
[Section titled “One card”](#one-card)
GET/enc/cards/{cardId}
| Parameter | | |
| --------- | -------- | ----------------------------------------- |
| `lang` | required | The language to return beside the Arabic. |
```bash
curl "https://islamenc.com/api/enc/cards/7913?lang=en"
```
The same shape as a listed card, plus:
```json
{
"external_id": "7913",
"encyclopedia": { "external_id": "101", "name": "موسوعة الأحاديث", "description": null },
"available_languages": ["ar", "am", "as", "bs", "en", "..."],
"versions": [ { "sentences": [ { "field_name": "...", "content": "...", "language": "en", "links": [] } ] } ],
"displayed_properties": [ ... ]
}
```
`sentences[].links` are cross-references the site found in that sentence, for its own pages; empty for most.
## Categories
[Section titled “Categories”](#categories)
GET/enc/{encId}/categories
| Parameter | | |
| ------------ | -------- | ------------------------------------------- |
| `lang` | optional | Language of the names where translated. |
| `translated` | optional | `1`: count only cards that exist in `lang`. |
The category trees of an encyclopedia’s cards, flat, with each node’s parent and how many cards sit in it or under it.
```json
[
{ "key": "11:1", "name": "القرآن الكريم وعلومه", "parent": null, "count": 37 },
{ "key": "11:2", "name": "الحديث وعلومه", "parent": null, "count": 9 },
{ "key": "11:4", "name": "العقيدة", "parent": null, "count": 148 }
]
```
The table before the colon says which tree: `11` the sharia classification, `43` topics, `18` the themes of introducing Islam. Pass a key as `category` to the card listing or to the search.
## Properties
[Section titled “Properties”](#properties)
GET/enc/{encId}/properties
| Parameter | | |
| ------------ | -------- | ------------------------------------------- |
| `lang` | optional | Language of the listing the counts are for. |
| `translated` | optional | `1`: count only cards that exist in `lang`. |
What an encyclopedia’s listing can be filtered by, with every value and its card count. A tree property (`tree: true`) has its values in the categories endpoint; the rest list theirs here.
```json
[
{ "id": "t11", "label": "التصنيف الشرعي", "table": 11, "tree": true },
{ "id": "t30", "label": "الفئة المستهدفة", "values": [ { "key": "30:33", "name": "المسلم", "count": 109 }, { "key": "30:34", "name": "غير مسلم", "count": 1 } ] },
{ "id": "t40", "label": "حجم المحتوى", "values": [ { "key": "40:1", "name": "مختصر", "count": 58 }, { "key": "40:2", "name": "متوسط", "count": 33 } ] }
]
```
Filter with `prop==`: `GET /enc/101/cards?page=1&limit=20&prop=t40=40:1` lists the short cards. Repeat `prop` to require several.
## Which languages each card has
[Section titled “Which languages each card has”](#which-languages-each-card-has)
GET/enc/{encId}/card-languages
A map from card id to its languages, for the whole encyclopedia (\~200 KB for the hadith one).
```json
{ "7913": ["ar", "am", "as", "bs", "en", "..."], "7914": ["ar", "en", "fr", "..."] }
```
## Vocabulary of the hadith encyclopedia
[Section titled “Vocabulary of the hadith encyclopedia”](#vocabulary-of-the-hadith-encyclopedia)
GET/enc-meta
GET/enc-meta/{projectKey}
GET/enc-meta/{projectKey}/values
The labels and value names used by the hadith encyclopedia, translated into 100+ languages: field names, grade names, the names of the collections a hadith is narrated in. Two projects: `hadeethenc` (interface labels) and `hadeethenc_meta` (attribute values). `GET /enc-meta` lists them with how many languages and phrases each has.
| Parameter | | |
| --------- | -------- | --------------------------------------------------------------------------------------------------- |
| `lang` | required | The language wanted; falls back along `chain` (to English, then Arabic) for phrases not translated. |
```bash
curl "https://islamenc.com/api/enc-meta/hadeethenc_meta/values?lang=en"
```
```json
{
"project_key": "hadeethenc_meta",
"language": "en",
"chain": ["en"],
"resolved_from": { "en": 120 },
"labels": { "attrib_7": "Narrated by Ibn Hibbaan", "attrib_11": "Narrated by Ibn Maajah" },
"values": [ { "key": "attrib_7", "ar": "رواه ابن حبان", "text": "Narrated by Ibn Hibbaan" } ]
}
```
`/values` keys the same phrases by their Arabic original (`ar`), which is how a card’s Arabic grade or source text can be shown in the reader’s language.
# Languages
> The 147 languages the platform knows, with their names and writing direction. Use isoCode wherever an endpoint takes lang.
GET/languages
The 147 languages the platform knows, with their names and writing direction. Use `isoCode` wherever an endpoint takes `lang`.
```bash
curl "https://islamenc.com/api/languages"
```
```json
[
{ "isoCode": "aa", "arabicName": "عفري", "englishName": "Afar", "nativeName": "Qafár af", "direction": "ltr" },
{ "isoCode": "ar", "arabicName": "عربي", "englishName": "Arabic", "nativeName": "العربية", "direction": "rtl" },
{ "isoCode": "bn", "arabicName": "بنغالي", "englishName": "Bengali", "nativeName": "বাংলা", "direction": "ltr" },
{ "isoCode": "prs", "arabicName": "دري", "englishName": "Dari", "nativeName": "دری", "direction": "rtl" }
]
```
Not every language has content of every kind. To know what exists:
| Content | Ask |
| ----------------------------------- | ---------------------------------------------------------------- |
| A book’s translations | `GET /books/{projectId}/languages` |
| Which cards exist in which language | `GET /enc/{encId}/card-languages` |
| Quran translations | `GET /quran/translation-keys` (editions, each with its language) |
| Surah names | `GET /quran/surah-names?language=xx` |
`direction` is `rtl` for Arabic, Persian, Dari, Pashto, Urdu, Uyghur, Kurdish (Sorani) and the other right-to-left scripts; use it to set `dir` on what you render.
# OpenAPI
> The public endpoints as an OpenAPI 3 document, rendered with a built-in client to try requests from the browser.
The public endpoints as an OpenAPI 3 document, rendered below with a client to try every request from this page. The same file is available for code generators and API clients:
* [/openapi.json](/openapi.json): the public endpoints only, regenerated with each build of these docs.
* `https://islamenc.com/api/api-docs-json`: the live document the API serves (it also lists administrative routes that need a key and are not part of the public contract).
Open an endpoint, fill its parameters and **Send**; the request goes straight to `https://islamenc.com/api`.
# Quran
> The 114 surahs, their ayas in Uthmani and standard spelling, translations by edition, surah names in every language, and a search over the ayas by words and meaning.
The 114 surahs, their ayas in Uthmani and standard spelling, translations by edition, surah names in every language, and a search over the ayas by words and meaning.
## List surahs
[Section titled “List surahs”](#list-surahs)
GET/quran/surahs
| Parameter | | |
| --------- | -------- | -------------------------------------------- |
| `lang` | optional | Language of `surah_name`. Arabic without it. |
```bash
curl "https://islamenc.com/api/quran/surahs?lang=en"
```
```json
[
{ "surah_no": 1, "surah_name": "Al-Faatiha", "ar_uthmani_name": "ﰀ", "ayas_count": 7 },
{ "surah_no": 2, "surah_name": "Al-Baqara", "ar_uthmani_name": "ﰁ", "ayas_count": 286 }
]
```
`ar_uthmani_name` is a glyph from the Uthmanic surah-names font; render it with that font or ignore it.
## One surah with its ayas
[Section titled “One surah with its ayas”](#one-surah-with-its-ayas)
GET/quran/surahs/{surahNo}
| Parameter | | |
| --------- | -------- | --------------------------------------------------------------------------------------------------- |
| `surahNo` | path | 1 to 114. |
| `lang` | optional | Return the translations in this language (every edition the language has). Without it, Arabic only. |
| `langKey` | optional | Return one edition by its key, such as `english_hilali_khan` (see translation keys below). |
```bash
curl "https://islamenc.com/api/quran/surahs/112?lang=en"
```
```json
{
"surah": { "surah_no": 112, "surah_name": "الإخلَاص", "ar_uthmani_name": "ﰝ", "ayas_count": 4 },
"ayahs": [
{
"id": 12458,
"aya_no": 1,
"aya_no_uthmani": "١",
"aya_uthmani": "قُلۡ هُوَ ٱللَّهُ أَحَدٌ",
"aya_imlaei": "قُلْ هُوَ اللَّهُ أَحَدٌ",
"translations": [
{
"id": 872051,
"translationKey": {
"key": "english_hilali_khan",
"title": "الترجمة الإنجليزية - تقي الدين الهلالي ومحسن خان",
"language": { "isoCode": "en", "arabicName": "إنجليزي", "englishName": "English", "nativeName": "English", "direction": "ltr" }
},
"content": "1. Say (O Muhammad صلى الله عليه وسلم): \"He is Allâh, (the) One.",
"footnotes": null
}
]
}
]
}
```
| Field | |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `aya_uthmani` | The Uthmani text with its pause marks and small letters, as in the Madinah mushaf. Needs a Quranic font (KFGQPC Uthmanic, Amiri Quran) to render well. |
| `aya_imlaei` | The same aya in standard modern spelling: searchable, and readable in any Arabic font. |
| `aya_no_uthmani` | The aya number in Arabic-Indic digits. |
| `translations[].content` | The translated text; some editions keep the aya number inside it. `footnotes` holds the edition’s notes when it has them. |
`404` when the surah number is outside 1 to 114.
## Translation editions
[Section titled “Translation editions”](#translation-editions)
GET/quran/translation-keys
The editions available, 70 of them, each tied to a language.
```json
[
{ "key": "afar_hamza", "title": "الترجمة العفرية - محمود عبدالقادر حمزة", "language": { "isoCode": "aa", "englishName": "Afar", "direction": "ltr" }, "last_version": "1.0" },
{ "key": "english_hilali_khan", "title": "الترجمة الإنجليزية - تقي الدين الهلالي ومحسن خان", "language": { "isoCode": "en", "englishName": "English", "direction": "ltr" }, "last_version": "1.0" }
]
```
Use `key` as `langKey` on the surah endpoint to get exactly that edition.
## Surah names in every language
[Section titled “Surah names in every language”](#surah-names-in-every-language)
GET/quran/surah-names
| Parameter | | |
| ---------- | -------- | --------------------------------------- |
| `language` | optional | ISO code; `404` if unknown. |
| `surah_no` | optional | 1 to 114; `404` if unknown. |
| `q` | optional | Case-insensitive substring of the name. |
Without parameters, all 114 names in all 78 languages (8,892 rows, \~540 KB). Filter by `language` for one list.
```bash
curl "https://islamenc.com/api/quran/surah-names?language=fr"
```
```json
[ { "surah_no": 1, "language": "fr", "surah_name": "Al-Fatiha" }, ... ]
```
## Search the ayas
[Section titled “Search the ayas”](#search-the-ayas)
GET/quran/search
The ayas of the [hybrid search](/reference/search/): by words and by meaning, Arabic and translations together.
| Parameter | | |
| --------- | -------- | -------------------------------------------------------------------- |
| `q` | required | The question or words. |
| `limit` | optional | 1 to 50, default 10. |
| `lang` | optional | Language of the `translation` returned with each aya (default `en`). |
```bash
curl "https://islamenc.com/api/quran/search?q=الصبر&limit=2&lang=en"
```
```json
{
"query": "الصبر",
"semantic": true,
"results": [
{
"type": "aya",
"score": 0.7873,
"surah_no": 70,
"aya_no": 5,
"surah_name": "المَعَارج",
"aya_uthmani": "فَٱصۡبِرۡ صَبۡرٗا جَمِيلًا",
"translation": "5. So be patient (O Muhammad صلى الله عليه وسلم), with a good patience.",
"matched_lang": "ar"
}
],
"timings": { "embed": 212, "meili": 120, "rerank": 0, "db": 7, "total": 339 }
}
```
`semantic` is `false` when the answer was found by words alone (the question’s embedding was not ready in time); the same question a moment later is searched by meaning. `matched_lang` says which text matched: the Arabic or a translation.
For filters by surah, more result types and paging, call `/hybrid-search?type=aya` directly.
# Search
> Two engines. Hybrid search matches by words and by meaning across the Quran, the books and the encyclopedias: a question finds what answers it even without sharing a word. Keyword search matches the w
Two engines. **Hybrid search** matches by words and by meaning across the Quran, the books and the encyclopedias: a question finds what answers it even without sharing a word. **Keyword search** matches the words themselves, with highlighting, for autocomplete and exact lookups.
## Hybrid search
[Section titled “Hybrid search”](#hybrid-search)
GET/hybrid-search
| Parameter | | |
| ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `q` | required | The question or words. Arabic or any language that has been embedded. A query in quotes is searched exactly. |
| `type` | optional | `aya`, `book`, `card`, comma-separated. Without it: all three, ranked together by relevance, at most 2 hits per book or card. |
| `lang` | optional | The reader’s language: searched with Arabic, and the language of each aya’s `translation` (default `ar`). |
| `langs` | optional | Languages to search instead, comma-separated, or `all`. |
| `surah` | optional | Surah numbers, comma-separated: ayas from these only. |
| `book` | optional | Book project ids: passages from these only. |
| `enc` | optional | Encyclopedia ids: cards from these only. |
| `category` | optional | Category keys `"
:- "`, comma-separated: cards in any of them, and only cards. |
| `prop` | optional | A card property filter `"="`, repeatable: cards with every one, and only cards. |
| `ratio` | optional | Weight of meaning against words, 0 to 1 (default 0.75). `0` is words only, `1` meaning only. |
| `exact` | optional | `true`: the words as typed, together and in order, no meaning side. |
| `limit` | optional | 1 to 50, default 10. |
| `offset` | optional | Default 0; `offset + limit` at most 1000. |
| `facets` | optional | `categories` adds `categoryCounts`; `props` adds `propCounts`: matching cards per category or property value. |
| `format` | optional | `hits`: results shaped like `GET /search` (`hits`, `_formatted`, `metadata`). |
| `intent` | optional | `off`: do not narrow the types by what the question asks for (“كتاب عن…” otherwise returns books only). |
```bash
curl "https://islamenc.com/api/hybrid-search?q=فضل الصدقة&limit=6&lang=en"
```
```json
{
"query": "فضل الصدقة",
"filters": { "type": null, "langs": null, "surah": null, "book": null, "enc": null, "category": null, "prop": null, "ratio": 0.75, "exact": false, "intent": null },
"semantic": true,
"semanticHits": 18,
"reranked": false,
"mixed": true,
"timings": { "embed": 0, "meili": 152, "rerank": 0, "db": 7, "total": 165 },
"results": [
{
"type": "aya",
"score": 0.7588,
"surah_no": 2,
"aya_no": 271,
"surah_name": "البَقَرَة",
"aya_uthmani": "إِن تُبۡدُواْ ٱلصَّدَقَٰتِ فَنِعِمَّا هِيَۖ ...",
"translation": "271. If you disclose your Sadaqât (alms-giving), it is well; ...",
"matched_lang": "ar"
},
{
"type": "book",
"score": 0.8133,
"lang": "ar",
"phrase_id": "17f637d4-3a97-4747-9382-4e15d7727f44",
"book_title": "المنتقى من المتجر الرابح في ثواب العمل الصالح",
"chapter_id": 6585,
"project_id": 226,
"chapter_name": "المنتقى من المتجر الرابح في ثواب العمل الصالح",
"text": "ثواب الصدقة\nعن أبي هريرة رضي الله عنه أن رسول الله ..."
},
{
"type": "card",
"score": 0.802,
"lang": "ar",
"title": "الصدقة",
"card_id": "22413",
"enc_id": "114",
"categories": ["11:136", "11:4", "11:511"],
"props": { "t40": ["40:4"] },
"text": "الصدقة\nإن من محاسن الدين الإسلامي الحث على الصدقة؛ ..."
}
]
}
```
### Result types
[Section titled “Result types”](#result-types)
| `type` | Fields | Link to |
| ------ | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
| `aya` | `surah_no`, `aya_no`, `surah_name`, `aya_uthmani`, `translation` (in `lang`), `matched_lang` | `https://islamenc.com/{lang}/quran/{surah_no}/{aya_no}` |
| `book` | `project_id`, `book_title`, `chapter_id`, `chapter_name`, `phrase_id`, `lang`, `text` (the matching passage) | `https://islamenc.com/{lang}/books/{project_id}` |
| `card` | `card_id`, `enc_id`, `title`, `lang`, `text`, `categories`, `props` | `https://islamenc.com/{lang}/enc/{enc_id}/card/{card_id}` |
`score` is the search engine’s match score (0 to 1), comparable within a type, not across types. The order of `results` is the ranking to show: by relevance to the question, judged by a reranker that grades every type on one scale, with no fixed turn between types.
### Flags
[Section titled “Flags”](#flags)
| Field | |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `semantic` | `true` when the meaning side took part. `false` means the question’s vector was not ready within the time the API waits (about 1.5 s on a slow day) and the answer is by words alone; the vector is cached as soon as it lands, so the same question a moment later is semantic. |
| `semanticHits` | How many of the candidates came from the meaning side. |
| `mixed` | `true` for a search over several types. |
| `timings` | Milliseconds spent embedding the question, in the search engine, reranking, and reading the database. |
### Paging and facets
[Section titled “Paging and facets”](#paging-and-facets)
`format=hits` gives the shape the site’s own search page uses, with highlighting and `hasMore`:
```bash
curl "https://islamenc.com/api/hybrid-search?q=فضل الصدقة&limit=9&offset=9&format=hits&facets=categories"
```
```json
{
"hits": [
{ "id": "aya_2_271", "type": "aya", "title": "البَقَرَة - 271", "text": "...", "_formatted": { "text": "..." }, "metadata": { "surah_no": 2, "aya_no": 271, "surah_name": "البَقَرَة" } }
],
"categoryCounts": { "11:4": 12, "11:136": 9 },
"hasMore": true,
"processingTimeMs": 165
}
```
Highlighting (`` in `_formatted`) is only present for an exact search; a semantic match has no words to mark.
### Intent
[Section titled “Intent”](#intent)
A question that names what it wants is narrowed to it: “كتاب عن الصيام” or “a book about fasting” returns books only, “آيات عن الصبر” ayas only, “حديث عن النية” hadith cards only. Pass `intent=off` to search everything regardless.
## Keyword search
[Section titled “Keyword search”](#keyword-search)
GET/search
The words themselves, with typo tolerance and highlighting. Faster than the hybrid search and the right tool for an exact phrase or an autocomplete box.
| Parameter | | |
| ------------------ | -------- | ---------------------------------------------------------------------------- |
| `q` | required | The words. |
| `type` | optional | `aya`, `book`, `card`, comma-separated. |
| `encId` | optional | One encyclopedia’s cards only. |
| `lang` | optional | Language of the content searched (default Arabic with the site’s languages). |
| `surah` | optional | Surah number: only the ayas of that surah. |
| `category`, `prop` | optional | As in the hybrid search. |
| `facets` | optional | `categories`: adds `categoryCounts`. |
| `limit`, `offset` | optional | Paging. |
```json
{
"hits": [
{
"id": "aya_6546",
"type": "aya",
"lang": ["ar", "en"],
"title": "آل عِمران - 17",
"text": "ٱلصَّٰبِرِينَ وَٱلصَّٰدِقِينَ ...",
"metadata": { "surah_no": 3, "aya_no": 17, "surah_name": "آل عِمران" },
"_formatted": { "title": "آل عِمران - 17", "text": "ٱلصَّٰبِرِينَ ..." }
}
],
"query": "الصبر",
"processingTimeMs": 12,
"limit": 2,
"offset": 0,
"estimatedTotalHits": 1480,
"totalHits": 1000,
"capped": true
}
```
`metadata` carries what a hit needs to be linked: `surah_no` and `aya_no` for an aya, `project_id` and `chapter_id` for a book passage, `enc_id` and `card_id` for a card. `capped` says the total was cut at 1000.
## Suggestions
[Section titled “Suggestions”](#suggestions)
GET/search/suggestions
| Parameter | | |
| --------- | -------- | --------------------------- |
| `q` | required | What has been typed so far. |
| `type` | optional | `aya`, `book`, `card`. |
| `encId` | optional | One encyclopedia only. |
| `lang` | optional | |
Up to a handful of titles and passages that start with or contain the text, for an autocomplete menu:
```json
[
{
"text": "الصبر وانتظار الفرج من أعظم العبادات - فضيلة الشيخ محمد بن عثيمين",
"type": "phrase",
"title": "مشروع هدايات - المجموعة الخامسة - الصبر وانتظار الفرج من أعظم العبادات",
"metadata": { "phrase_id": "...", "project_id": 231, "chapter_id": 6029 },
"snippets": [ { "id": "phrase_...", "text": "...", "_formatted": { "text": "..." } } ]
}
]
```
## Categories
[Section titled “Categories”](#categories)
GET/search/categories
Every card category across the encyclopedias, with the number of cards in each: the same shape as `GET /enc/{id}/categories`, for building a category filter over a search.
# Changelog
> Changes to the public API since these docs went live, newest first. Breaking changes are marked and announced here ahead of time.
Changes to the public API since these docs went live, newest first. Breaking changes are marked and announced here ahead of time.
## 2026-10-30
[Section titled “2026-10-30”](#2026-10-30)
These docs went live at docs.islamenc.com. They describe the API as it is on this date:
* The Quran with translations by edition, the book library with phrase-aligned translations and PDF and Word copies, and the encyclopedias with categories, properties and the hadith vocabulary in 100+ languages.
* Hybrid search by words and meaning (`GET /hybrid-search`, `GET /quran/search`), keyword search, suggestions and category facets. A question’s embedding is prefetched while it is typed on the site and cached across restarts; the API waits at most 1.5 s for it before answering by words (`semantic: false`). Typical answer: 250 to 500 ms.
* A rate limit of 10 requests per second per address, with bursts of 40.
* The public contract as an OpenAPI document at [/openapi.json](/openapi.json), and these pages as Markdown at [/llms.txt](/llms.txt) for assistants.
# Concepts
> The data model behind the endpoints, so the field names make sense before you read the reference.
The data model behind the endpoints, so the field names make sense before you read the reference.
## The Quran
[Section titled “The Quran”](#the-quran)
* **Surah** (`surah_no` 1 to 114) with its Arabic name, its Uthmani calligraphic name and `ayas_count`.
* **Aya** with `aya_no`, the text in two spellings, `aya_uthmani` (the Uthmani script with its marks, as printed in the Madinah mushaf) and `aya_imlaei` (standard modern spelling, the one to search or display in a plain font), and its **translations**.
* **Translation key**: one edition of a translation, such as `english_hilali_khan`. A language can have several editions; `GET /quran/translation-keys` lists them with the language each belongs to. When you ask a surah for `lang=en` you get the editions in English; `langKey` picks one edition by its key.
* **Tafsir**: an Arabic explanation per aya is stored for the site’s own use and is not exposed by these endpoints yet.
## Books
[Section titled “Books”](#books)
* **Book** (`project_id`) with a title, a description and one or more **Arabic versions** (`version_name` such as `1.0`, `2.0`; `is_latest` marks the current one). Versions are editions of the Arabic text; a new edition can change paragraphs, so translations attach to a version.
* **Chapter** (`id`, `serial`, `name`): the sections of a version in reading order.
* **Phrase**: the unit of text. A chapter is a list of phrases, each with a `phrase_id` (stable UUID), a `group_id` and `group_order` that place it in a paragraph (a *group* is a paragraph; its phrases are sentences in order), `arabic_text`, a `tag` (`p`, `h2`, `li`…) and `content_type_id` (a title, a body paragraph, a footnote…). Phrases that quote a hadith may carry `hadith_card_id`, the card in the hadith encyclopedia.
* **Translation**: a version’s text in one language, phrase by phrase: each item pairs the Arabic `phrase` with its `translated_text`, so a bilingual view lines up exactly.
* **Copies**: every book has PDF and Word files per language and version, listed with the book (`pdfs`, `docxs`) and all together at `GET /books/pdfs`.
## Encyclopedias and cards
[Section titled “Encyclopedias and cards”](#encyclopedias-and-cards)
* **Encyclopedia** (`external_id`): a collection of cards of one kind. `101` is the hadith encyclopedia; others hold questions and answers, Islamic terms, the names of Allah, places, and introductions to Islam. `GET /enc` lists them with a card count.
* **Card** (`external_id`): one entry. Its content is a set of **sentences**, each with a `field_name` (for a hadith: `عنوان الحديث` the title, `متن الحديث` the text, `درجة الحديث` the grade, `التخريج` the source, `الشرح` the explanation…), a `language` and `content`. A card has **versions** (`version_string`); the sentences of the latest are what you want.
* **Categories**: every card carries `categories`, keys of the form `"
:- "` where the table is a classification tree: `11` the sharia classification, `43` topics, `18` the themes of introducing Islam. The keys include the ancestors, so a card under “الحديث وعلومه > مصطلح الحديث” carries both. `GET /enc/{id}/categories` gives names, parents and counts.
* **Properties**: flat attributes under `properties`, keyed `t
` with item keys as values (`"t40": ["40:1"]` means the card is short) or plain text (`book`, `chapter`). `GET /enc/{id}/properties` says which properties an encyclopedia offers for filtering, with labels and value names; `displayed_properties` on a card gives the same, resolved to names, ready to show.
* **Vocabulary**: the hadith encyclopedia’s field labels and value names exist in 100+ languages through `GET /enc-meta/...`, so a client can label a card in the reader’s language.
## Search
[Section titled “Search”](#search)
Two engines:
* **Hybrid search** (`/hybrid-search`, `/quran/search`): by words *and* meaning. The question is embedded with the same model as the content and matched against ayas, book passages and cards, so “ثواب من يتصدق على أقاربه” finds the hadith about charity to relatives even without sharing a word with it. `ratio` sets the weight of meaning against words.
* **Keyword search** (`/search`, `/search/suggestions`): the words themselves, with highlighting, for autocomplete and exact lookups.
Both accept filters by type, language, surah, book, encyclopedia, category and property, and can return facet counts.
# Terms of use
> The Islamenc API is offered free of charge so that the Quran, its translations, the books and the encyclopedias reach more readers through more applications.
The Islamenc API is offered free of charge so that the Quran, its translations, the books and the encyclopedias reach more readers through more applications.
## You may
[Section titled “You may”](#you-may)
* Read any public endpoint from any application, website or script, commercial or not, without registering.
* Cache and store the content, translate your interface around it, and display it in any form.
* Link to the content on [islamenc.com](https://islamenc.com) or to the PDF and Word copies directly.
## You must
[Section titled “You must”](#you-must)
* **Attribute.** Name *موسوعة المحتوى الإسلامي (islamenc.com)* as the source of the content where it is displayed, and keep the names of the translation editions and the books’ authors where the API gives them. The content is the work of its authors and translators and of the ICADB and QuranEnc projects it is synchronised from.
* **Keep the text intact.** Do not alter the Quranic text, the hadith text or the translations. Shorten with an ellipsis if you must, never rewrite.
* **Respect the rate limit:** 10 requests a second per address. Cache answers (they say how long they are good for) rather than re-asking. A crawler should identify itself with a `User-Agent` that says who it is.
## You may not
[Section titled “You may not”](#you-may-not)
* Present the content as your own, or remove the attribution the data carries.
* Sell access to the API or resell the raw data as a dataset. Building a product on it is welcome; charging for the data itself is not.
* Use the content in material that insults Islam or any faith, or alongside advertising that a Muslim reader would find offensive.
## No warranty
[Section titled “No warranty”](#no-warranty)
The API is provided as is. The content is synchronised from its sources a few times a week and corrected as the sources correct it; endpoints may change, and will be announced in the [changelog](/changelog/) with notice where the change breaks a client. There is no uptime guarantee, though the service is monitored and restarts itself within seconds if it fails.
## Contact
[Section titled “Contact”](#contact)
For higher limits, bulk access, a new encyclopedia or a correction to the content, write to ****.