۞i-muslim

Developer API · v1

Build with i-muslim data

A clean JSON API for the things every Islamic app needs: prayer times, Qibla direction, the Hijri calendar, mosque listings, the Quran, and the major Hadith collections — read and write. Free for community use, rate limited per key, no marketing tracking. Issue a key, drop in a fetch call, ship.

What you can do

Getting a key

Request a key through the contact form with a one-sentence description of what you're building and which endpoints you need. Keys are issued manually during v1 and typically come back within 24 hours. Each key is scoped to a subset of resources (e.g. hadith, prayer-times) and a subset of permissions (read, write, delete).

Quick start

Every request needs the X-API-Key header. Here's the simplest possible request — Qibla bearing for London:

curl

curl -H "X-API-Key: im_live_..." \ "https://i-muslim.com/api/v1/qibla?lat=51.5074&lng=-0.1278"

JavaScript (Node 18+, browsers)

const res = await fetch( "https://i-muslim.com/api/v1/qibla?lat=51.5074&lng=-0.1278", { headers: { "X-API-Key": process.env.IMUSLIM_API_KEY } }, ); const { data } = await res.json(); console.log(data.bearing); // → 118.99 degrees from north

Python (requests)

import os, requests r = requests.get( "https://i-muslim.com/api/v1/qibla", params={"lat": 51.5074, "lng": -0.1278}, headers={"X-API-Key": os.environ["IMUSLIM_API_KEY"]}, ) print(r.json()["data"]["bearing"])

Publishing a translation

With a write-scope key, you can publish or update a translation for any hadith or Quranic ayah. The endpoint is idempotent — call it again with new text and it overwrites. Arabic (text_ar) is never editable via API.

curl -X PUT \ -H "X-API-Key: im_live_..." \ -H "Content-Type: application/json" \ -d '{"text": "The deeds are only by intentions..."}' \ "https://i-muslim.com/api/v1/hadith/collections/bukhari/hadiths/1/translations/en"

Every write is recorded in our audit log with your key id, your key name, and a before/after snapshot. If you push a translation that turns out to be wrong, we can roll it back.

Endpoints

Read (GET)

Browser-callable: Access-Control-Allow-Origin: * is set on every response. Safe to call directly from frontend code if your key is read-only.

Write (PUT / PATCH / POST)

Server-side only.Write endpoints intentionally don't set CORS headers — call them from your backend so the key never lands in a browser. Requires write permission on the key.

Authentication

Send your key in the X-API-Key header on every request. Keys look like im_live_AbCd… and are shown exactly once when issued — store them in your secrets manager (Vercel env vars, AWS Secrets Manager, GitHub Actions secrets, etc.). We only keep a SHA-256 hash on our side, so we cannot recover a lost key — ask for a new one.

Rate limits

100 requests per minute, per key. Every response carries three headers so you can self-throttle:

X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1747234260

When you exceed the limit you'll get 429 Too Many Requests with error code RATE_LIMITED. Wait for the reset timestamp, or contact us if you need a higher cap for a legitimate use case.

Response shape

// Success { "data": { "bearing": 118.99, "origin": {...}, "kaaba": {...} } } // Error { "error": { "code": "INVALID_API_KEY", "message": "API key not found or revoked" } }

Error codes

Stability & versioning

v1 is the stable surface. Any breaking change ships as v2 on a new path; we'll keep v1 running for at least 12 months after v2 launches.

Attribution & ethics

Quran and Hadith are sacred — please render them faithfully, don't paraphrase, and don't silently truncate. If you publish translations you authored, please make sure you have the right to do so. If you spot a translation error in our data, let us know and we'll roll it back.

Contact

Questions, bug reports, or higher-quota requests — please use the contact form and mention “Developer API” in the subject.