Using the Quran API with Python
This post shows you how to fetch Quran data from UmmahAPI using Python. You will cover basic GET requests, query parameters, saving data to JSON files, and building a small CLI tool that lets you read any surah from your terminal.
What You Need
You only need Python 3.7 or newer and the requests library. If you do not have it yet, install it now:
pip install requests
That is it. UmmahAPI does not require authentication for basic use. You get 5,000 requests per 15 minutes for free without any key. If you need more, grab a free API key and add it as a header.
Your First Request: API Overview
Before fetching surahs, it is good to check the API status and see what stats it returns. The /api/quran endpoint gives you a quick overview.
import requests
BASE_URL = "https://ummahapi.com"
def get_overview():
response = requests.get(f"{BASE_URL}/api/quran")
response.raise_for_status()
data = response.json()
print(data)
get_overview()
raise_for_status() will throw an exception if the server returns a 4xx or 5xx status code. This is a simple way to catch errors early without writing a lot of extra code.
Fetching the List of Surahs
The /api/quran/surahs endpoint returns all 114 surahs with their names, number of ayahs, and revelation type. This is useful if you want to build a surah picker or display a table of contents.
import requests
BASE_URL = "https://ummahapi.com"
def list_surahs():
response = requests.get(f"{BASE_URL}/api/quran/surahs")
response.raise_for_status()
surahs = response.json()
for surah in surahs:
print(f"{surah['number']:>3}. {surah['englishName']:<25} ({surah['numberOfAyahs']} ayahs)")
list_surahs()
The output will look like a numbered list of all surahs. You can adjust the format string to show Arabic names too. The response includes both the English transliteration and the Arabic script for each surah name.
Fetching a Full Surah with Translations
To get all ayahs in a surah, call /api/quran/surah/:number. You can attach the translations query parameter to get English, Urdu, or French alongside the Arabic text.
import requests
BASE_URL = "https://ummahapi.com"
def get_surah(surah_number, translations="en"):
url = f"{BASE_URL}/api/quran/surah/{surah_number}"
params = {"translations": translations}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()
surah = get_surah(1, translations="en,ur")
for ayah in surah["ayahs"]:
print(f"[{ayah['number']}] {ayah['text']}")
print(f" EN: {ayah['translations']['en']}")
print()
Passing params as a dictionary to requests.get() is cleaner than building the URL string by hand. The library handles URL encoding for you.
Tip. You can also request a specific Uthmani or IndoPak script by adding ?script=uthmani or ?script=indopak to your request. This changes the Arabic text rendering in the response.
Fetching a Single Ayah
Sometimes you just need one ayah. The endpoint /api/quran/surah/:s/ayah/:a is the fastest way to get it. Here is how to fetch Ayat al-Kursi, which is surah 2 ayah 255:
import requests
BASE_URL = "https://ummahapi.com"
def get_ayah(surah, ayah, translations="en"):
url = f"{BASE_URL}/api/quran/surah/{surah}/ayah/{ayah}"
response = requests.get(url, params={"translations": translations})
response.raise_for_status()
return response.json()
result = get_ayah(2, 255, translations="en")
print(result["text"])
print(result["translations"]["en"])
Searching the Quran
The search endpoint lets you find ayahs by keyword across all translations. Pass your term as the q parameter to /api/quran/search.
import requests
BASE_URL = "https://ummahapi.com"
def search_quran(query):
url = f"{BASE_URL}/api/quran/search"
response = requests.get(url, params={"q": query})
response.raise_for_status()
results = response.json()
print(f"Found {len(results)} result(s) for '{query}':\n")
for item in results[:5]: # show first 5
ref = f"Surah {item['surah']}:{item['ayah']}"
print(f"{ref} - {item['translation']}")
search_quran("mercy")
Slicing with [:5] keeps the output short during testing. Remove the slice when you need all results.
Saving Quran Data to a JSON File
Saving responses to disk means you can work with the data offline without hitting the API every time. Python's built-in json module handles this easily.
import requests
import json
import os
BASE_URL = "https://ummahapi.com"
def save_surah(surah_number, output_dir="quran_data"):
os.makedirs(output_dir, exist_ok=True)
filepath = f"{output_dir}/surah_{surah_number}.json"
# skip download if file already exists
if os.path.exists(filepath):
print(f"Already saved: {filepath}")
return
url = f"{BASE_URL}/api/quran/surah/{surah_number}"
response = requests.get(url, params={"translations": "en"})
response.raise_for_status()
with open(filepath, "w", encoding="utf-8") as f:
json.dump(response.json(), f, ensure_ascii=False, indent=2)
print(f"Saved: {filepath}")
# save all 114 surahs
for n in range(1, 115):
save_surah(n)
Setting ensure_ascii=False is important here. Without it, Python will escape Arabic characters as Unicode sequences, which makes the file hard to read and larger than it needs to be.
Tip. If you are downloading all 114 surahs in a loop, add a small delay with time.sleep(0.1) between requests. This keeps you well under the rate limit and is good practice for any bulk download script.
Building a CLI Quran Reader
Now let's put everything together. This script accepts a surah number as a command-line argument and prints each ayah to the terminal with its English translation. It also loads from a local cache if the file already exists.
#!/usr/bin/env python3
# quran_reader.py - usage: python quran_reader.py 36
import sys
import json
import os
import requests
BASE_URL = "https://ummahapi.com"
CACHE_DIR = "quran_cache"
def load_surah(surah_number):
os.makedirs(CACHE_DIR, exist_ok=True)
cache_file = f"{CACHE_DIR}/surah_{surah_number}.json"
if os.path.exists(cache_file):
with open(cache_file, encoding="utf-8") as f:
return json.load(f)
url = f"{BASE_URL}/api/quran/surah/{surah_number}"
response = requests.get(url, params={"translations": "en"})
response.raise_for_status()
data = response.json()
with open(cache_file, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return data
def print_surah(data):
name = data.get("englishName", "Unknown")
total = len(data.get("ayahs", []))
print(f"\n{'='*50}")
print(f" {name} ({total} ayahs)")
print(f"{'='*50}\n")
for ayah in data["ayahs"]:
num = ayah["number"]
arabic = ayah["text"]
english = ayah.get("translations", {}).get("en", "")
print(f"[{num}] {arabic}")
if english:
print(f" {english}")
print()
def main():
if len(sys.argv) < 2:
print("Usage: python quran_reader.py <surah_number>")
print("Example: python quran_reader.py 1")
sys.exit(1)
try:
surah_number = int(sys.argv[1])
if not (1 <= surah_number <= 114):
raise ValueError
except ValueError:
print("Please enter a number between 1 and 114.")
sys.exit(1)
try:
data = load_surah(surah_number)
print_surah(data)
except requests.HTTPError as e:
print(f"API error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Run it with python quran_reader.py 36 to read Surah Ya-Sin. The first run downloads and caches the data. Every run after that loads from the local JSON file, so it works offline too.
You can extend this further. For example, add a --search flag that calls /api/quran/search, or a --random flag that hits /api/quran/random. The argparse module from the standard library is a clean way to handle multiple flags without adding extra dependencies.
Using an API Key
When you are ready to move beyond the free tier, register at ummahapi.com/register. Once you have a key, pass it as a header on every request.
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://ummahapi.com"
session = requests.Session()
session.headers.update({"X-API-Key": API_KEY})
response = session.get(f"{BASE_URL}/api/quran/surah/2")
response.raise_for_status()
print(response.json())
Using a requests.Session() object is better than passing headers on every single call. You set the key once and all requests from that session include it automatically. This also reuses the underlying TCP connection, which makes multiple requests slightly faster.
What Else Can You Build
Once you have the basics working, there are a few directions you can take this:
- Use
/api/quran/juz/:juzto build a juz-by-juz study tool. There are 30 juz in total. - Use
/api/quran/words/:surah/:ayahto get word-by-word breakdowns. This is useful for vocabulary apps or learning tools. - Combine the Quran API with the Tafsir API. Call
/api/tafsir/ibn_kathir/surah/1/ayah/1to pull commentary for any ayah. - Add audio by requesting a reciter with
?reciter=alafasy. Other reciters includesudais,husary, andabdul_basit. - Pipe the output into a text file or PDF generator to create printable study sheets.
The full list of endpoints is on the API docs page. Everything shown above also works with the Hadith API and Duas API using the same pattern.
FAQ
Do I need an API key to use the Quran API with Python?
No. UmmahAPI allows up to 5,000 requests per 15 minutes without a key. If you need unlimited requests, you can register for a free key at ummahapi.com/register.
Which Python library should I use to call UmmahAPI?
The requests library is the easiest option. Install it with pip install requests and use requests.get() to call any endpoint. For async use cases, httpx is a good alternative that supports both sync and async.
Can I get Quran translations through the Python API?
Yes. Add ?translations=en,ur,fr to any surah or ayah endpoint. UmmahAPI returns multiple translations in the same JSON response, so you only need one request to get all the languages you want.
How do I search the Quran with Python?
Call GET /api/quran/search?q=your+keyword. Pass your search term as the q parameter. The API searches across translations and returns matching ayahs with their surah and ayah numbers. See the docs for the full response shape.
Start building with UmmahAPI
UmmahAPI is a free Islamic API with Quran, Hadith, Prayer Times, Duas, Qibla, and more, all from one base URL.
Read the docs