Build with trusted dua content
Fortress Platform provides open, versioned Islamic content through a fast JSON API. Retrieve complete duas, search every text layer, or request the exact part your reading experience needs.
- Base URL
api.fortressofmuslim.org/v1- Format
- JSON over HTTPS
- Access
- Public reads; OAuth for managed features
Quickstart
Make a request with any HTTPS client. This example returns two lightweight dua summaries.
curl "https://api-test.fortressofmuslim.org/v1/duas?limit=2" \
-H "X-Fortress-API-Key: $FORTRESS_API_KEY"const response = await fetch(
"https://api-test.fortressofmuslim.org/v1/duas?limit=2",
{ headers: { "X-Fortress-API-Key": process.env.FORTRESS_API_KEY } }
);
const result = await response.json();import requests
result = requests.get(
"https://api-test.fortressofmuslim.org/v1/duas",
params={"limit": 2},
headers={"X-Fortress-API-Key": FORTRESS_API_KEY},
).json()Environments
| Environment | Base URL | Purpose |
|---|---|---|
| Test | https://api-test.fortressofmuslim.org/v1 | Current beta and integration testing |
| Production | https://api.fortressofmuslim.org/v1 | Stable releases after promotion from test |
Authentication
Published dataset, collection, dua, and Hadith read endpoints are public and require no account. Owner-scoped named queries, MCP, higher future limits, and management operations use X-Fortress-API-Key or an OAuth bearer token. API keys suit private server integrations; connected apps use OAuth 2.1 authorization code with PKCE or client credentials.
content:readcontent:searchdataset:readmcp:connectmcp:manageapps:writeusage:readManage integrations in the console
API keys, OAuth connected apps, device identities, MCP toolsets, and executable record queries live in a dedicated operational workspace. API keys remain persisted by the identity service; remembering the one-time value in the browser is optional and stale browser copies are removed when the server key is revoked or expires.
Open Developer ConsoleOAuth connected apps
Public browser and native clients use authorization code with PKCE. Confidential applications can use a client secret, machine integrations use client credentials, and higher-assurance clients can authenticate with private_key_jwt and a registered JWKS URL. Callback URLs are exact-match allowlists for interactive Authorization Code clients and are not required for machine-to-machine clients. Disabling an app immediately blocks new use and revokes its outstanding access and refresh tokens; re-enabling it does not restore revoked tokens.
Machine integrations (client credentials grant) exchange a client ID and secret for a bearer token directly, with no user interaction:
curl -X POST "https://auth-test.fortressofmuslim.org/api/auth/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET"const response = await fetch(
"https://auth-test.fortressofmuslim.org/api/auth/oauth2/token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.FORTRESS_CLIENT_ID,
client_secret: process.env.FORTRESS_CLIENT_SECRET,
}),
}
);
const { access_token } = await response.json();import requests
response = requests.post(
"https://auth-test.fortressofmuslim.org/api/auth/oauth2/token",
data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
},
)
access_token = response.json()["access_token"]One MCP runtime, composable tools
Fortress exposes one OAuth-protected MCP endpoint. The root endpoint includes reviewed standard tools. Use find_dua and search_duas for duas. Use list_collections, list_hadith, search_hadith, and get_hadith for the Hadith library. Use ask_fortress for semantic source retrieval with numbered citations. Use get_dua_evidence before making authenticity, attribution, or citation claims; pending evidence must be reported honestly. A custom toolset groups renamed standard tools, named-query APIs, and approved external API tools without creating another server. Disabled toolsets disappear from discovery, and disabled tools are omitted without deleting their configuration.
| Tools | Endpoint |
|---|---|
| Standard Fortress tools | https://mcp-test.fortressofmuslim.org/mcp |
| Custom toolset | https://mcp-test.fortressofmuslim.org/mcp?toolset={slug} |
Calling a tool (here, the standard search_duas tool) looks like this:
curl -X POST "https://mcp-test.fortressofmuslim.org/mcp" \
-H "Authorization: Bearer $OAUTH_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_duas","arguments":{"query":"morning"}}}'const response = await fetch("https://mcp-test.fortressofmuslim.org/mcp", {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: { name: "search_duas", arguments: { query: "morning" } },
}),
});
const result = await response.json();import requests
response = requests.post(
"https://mcp-test.fortressofmuslim.org/mcp",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {"name": "search_duas", "arguments": {"query": "morning"}},
},
)
result = response.json()Named query APIs
Named queries are declarative record queries: choose returned fields, allowlisted filters, endpoint parameters, sorting, and a maximum row count. Fortress compiles the definition into parameterized D1 statements, so callers get a stable API without receiving or submitting SQL. Disable a query to stop execution while preserving its definition and any custom MCP tool relationship.
curl "https://api-test.fortressofmuslim.org/v1/queries/QUERY_SLUG?status=verified" \
-H "X-Fortress-API-Key: $FORTRESS_API_KEY"const response = await fetch(
"https://api-test.fortressofmuslim.org/v1/queries/QUERY_SLUG?status=verified",
{ headers: { "X-Fortress-API-Key": process.env.FORTRESS_API_KEY } }
);
const result = await response.json();import requests
result = requests.get(
"https://api-test.fortressofmuslim.org/v1/queries/QUERY_SLUG",
params={"status": "verified"},
headers={"X-Fortress-API-Key": FORTRESS_API_KEY},
).json()Content model
Public read APIs expose the current immutable editorial revision, including material still under review. Consumers must inspect verificationStatus and workflowState; only records marked verified and published are trusted publication material. A dua contains ordered parts, and every part contains ordered typed segments.
arabicArabic script source texttransliterationArabic rendered in Latin scripttranslationEnglish meaningcommentContext and narration textEvery dua also carries a readingRole, because Hisn al-Muslim is not only supplications: supplication is words to recite; framed is a narration or instruction that contains words to recite; instruction says what to do, with no fixed words; virtue describes a merit, with nothing to recite. Do not present instruction or virtue readings as something to recite.
verifiedBy, verifiedAt, and publishedAt are nullable. Never present an unverified record as authenticated or reviewed.Identifiers
Fortress canonical IDs are readable and stable, such as dua.hisn.001 and hadith.bukhari.1. Public sequential routes such as /bukhari/book1/1 resolve to the same published canonical record. Existing Fortress PWA IDs such as dua-001 remain accepted for dua compatibility.
Pagination
Collection endpoints use opaque cursors. Pass the returned nextCursor into the next request and stop when it is null. Limits range from 1 to 100.
Response headers
Every API response includes operational metadata for support and deployment diagnostics. Clients may send a safe X-Request-ID value to correlate one request across their own logs.
| Header | Purpose |
|---|---|
X-Request-ID | Caller-supplied or edge-generated request correlation ID |
X-Fortress-Platform-Version | Deployed Fortress Platform release |
Server-Timing | Worker application processing duration in milliseconds |
X-Fortress-Dataset-Version | Active dataset identifier on versioned content routes |
Errors
Errors use a predictable envelope with a machine-readable code and request ID.
{
"error": {
"code": "not_found",
"message": "Dua was not found.",
"requestId": "cf-ray-or-generated-id"
}
}Read endpoints
All routes below are available under the v1 base URL.
/duasList duas
Returns ordered, lightweight summaries without loading complete text.
limitinteger1-100, defaults to 20cursorstringOpaque cursor from the previous response/duas/searchSearch duas
Searches titles, Arabic, transliteration, translations, and commentary. Wildcards are treated as literal text.
qstring required2-200 characterslimitinteger1-100, defaults to 20cursorstringOpaque pagination cursor/duas/randomRandom dua
Returns one complete random record. Responses are marked Cache-Control: no-store.
/duas/{id}Get a dua
Returns full ordered parts and all segment text for a canonical or legacy ID.
Try this endpoint/duas/{id}/evidenceInspect evidence
Returns dataset provenance, collection placement, source references, taxonomy, verification history, and correction history. Missing or unreviewed evidence is reported explicitly and never inferred.
Try this endpoint/duas/{id}/partsList parts
Returns swipe-sized part resources with explicit positions and segment counts.
Try this endpoint/duas/{id}/parts/{position}Get one part
Returns only the requested 1-based part position.
Try this endpoint/collectionsList collections
Returns current dua and Hadith collections with record, book, chapter, and aggregate verification status. Filter with type=dua or type=hadith.
/hadithList Hadith
Returns lightweight, paginated summaries. Use collection to restrict results to bukhari, muslim, or tirmidhi.
/hadith/searchSearch Hadith
Searches current Arabic, English, narrator, title, and display-number fields. Results include their editorial state and may be restricted by collection.
Try this endpoint/hadith/{id}Get Hadith
Returns the complete current revision, editorial state, hierarchy, narrator, grading, and canonical references using a Fortress ID.
Try this endpoint/hadith/resolveResolve canonical Hadith path
Resolves a Fortress sequential path from exact collection, book, and record number components.
Try this endpoint/askAsk Fortress
Uses query-aware hybrid retrieval across exact published text and the active canonical vector namespace. Results materially weaker than the strongest evidence are omitted. Lexical retrieval remains available while Vectorize is unavailable or a newly published dataset is still indexing. Generated answers are rejected when their numbered citations are missing or invalid. A question that is essentially just a reference (for example "Bukhari 52") resolves directly against the matching record instead of running retrieval. An optional filters object narrows retrieval to a specific contentType (dua or hadith) and/or collection slug.
curl -X POST https://api-test.fortressofmuslim.org/v1/ask \
-H "Content-Type: application/json" \
-d '{"question":"What do the sources say about intentions?","filters":{"contentType":"hadith"}}'/ask/statusAsk readiness
Reports the active dataset, separate verified Dua and Hadith counts, expected vectors, indexed vectors, and retrieval state. New verified books are indexed incrementally; lexical retrieval remains available during indexing. An empty dataset does not consume an Ask allowance or invoke AI.
Try this endpoint/datasets/currentCurrent dataset
Returns source provenance, content hash, record count, publication status, and verification state.
Try this endpointAPI Explorer
Send an authenticated request using the same URL, headers, and response contract documented above.
Select an endpoint and send a request.