API Documentation
The Muslim Xchange API gives you the same Shariah-compliance screening that powers the platform — verdicts under eight standards, impermissible-income figures, purification and zakat per share — as JSON you can call from any language, a spreadsheet or a data pipeline. Every response comes straight from the current dataset; there is nothing to sync.
https://muslimxchange.com/wp-json/mx-api/v1- Plans & limits
- Get your API key
- Authentication
- Quick start
- Endpoints
- Examples
- Field reference
- Dual-listed ISINs
- Errors & headers
- Rate limits & usage
- Availability
- Claude & ChatGPT
- Excel add-in
- Support
Plans & limits
Free trial
Any signed-in account
Single lookups · basic fields · 1 lookup per day
Max · Business Advisor
API access
Single, ISIN and batch lookups · market export · basic fields · Excel add-in
Corporate · Enterprise
API access, all fields
Everything a Max plan has, with every field including the per-ratio breakdowns
Every plan can use every route, including market export. The plans differ only in fields: basic fields are the identity columns, each standard’s verdict, the impermissible segment and income figures, purification, zakat per share and the business screen; all fields adds the per-ratio values and their individual test results. GET /fields tells you exactly what your plan includes.
On a plan without the API? Sign in and use the Try it box on your API keys page — members get one free lookup a day through the real API, so you can see the data before you upgrade.
Get your API key
Sign in and open your API keys page. Create a key (give it a name such as Python script or Excel), copy it immediately — it is shown only once — and keep it like a password. You can hold up to five keys, reset any of them (the old value stops working, a new one is issued under the same name) and revoke them at any time. The same page shows your usage.
Authentication
Every request uses HTTP Basic authentication: your username (or email) and your API key. Spaces in the key are optional.
curl -u "USERNAME:xxxx xxxx xxxx xxxx xxxx xxxx" \
"https://muslimxchange.com/wp-json/mx-api/v1/me"
Or set the header yourself: Authorization: Basic followed by base64("USERNAME:KEY").
{
"user": { "id": 123, "login": "USERNAME", "name": "Your Name" },
"levels": [ { "id": 12, "name": "Enterprise" } ],
"tier": "bulk",
"fields": "full",
"limits": { "requests_per_minute": 0, "batch_max": 0, "market_per_page_max": 0, "lookup_quota_per_day": 0, "used_today": 0 }
}
Quick start
Look up a listing by ticker and ask for the fields you want. Fields default to Result; names are case-insensitive.
curl -u "USERNAME:KEY" \
"https://muslimxchange.com/wp-json/mx-api/v1/ticker/AAPL?fields=Result,NoofStandards,TotalImpurePct,Purification,Zakatpershare"
{
"ticker": "AAPL",
"Market": "US",
"Name": "Apple Inc",
"Result": "Compliant",
"NoofStandards": 8,
"TotalImpurePct": 1.23,
"Purification": 0.0123,
"Zakatpershare": 0.41
}
Every row begins with the identifier, Market and Name. Numbers are numbers, empty cells are null, and a non-numeric marker in the source (such as "N/A") is returned as text.
Endpoints
| Route | Access | What it does |
|---|---|---|
GET /me |
any key | Who you are, your plan, tier, field scope and limits. |
GET /fields |
any key | Every field with its type, tier and whether your plan includes it. |
GET /ticker/{symbol} |
lookup | One listing by exchange-suffixed ticker. ?fields= optional. |
GET /isin/{isin} |
lookup | Listing(s) by ISIN. ?market= narrows to one. |
POST /batch |
lookup | Any number of tickers and/or ISINs in one call. |
GET /markets |
any plan | Market codes with listing counts. |
GET /market/{code} |
any plan | Every listing in a market in one response. The cheapest way to read a whole market. |
All routes are also available under /ticker?ticker=… and /isin?isin=… for clients that cannot put identifiers in the path.
Examples
Batch lookup
Send tickers and/or ISINs as JSON. Results come back keyed by the identifier you sent; an unknown identifier is null.
curl -u "USERNAME:KEY" -H "Content-Type: application/json" \
-d '{"tickers":["AAPL","MSFT","ASML.AS"],"isins":["US0378331005"],"fields":["Result","Purification"]}' \
"https://muslimxchange.com/wp-json/mx-api/v1/batch"
{
"fields": ["Result", "Purification"],
"results": {
"tickers": {
"AAPL": { "ticker": "AAPL", "Market": "US", "Name": "Apple Inc", "Result": "Compliant", "Purification": 0.0123 },
"MSFT": { "ticker": "MSFT", "Market": "US", "Name": "Microsoft", "Result": "Compliant", "Purification": 0.0201 },
"ASML.AS": { "ticker": "ASML.AS", "Market": "NL", "Name": "ASML Holding", "Result": "Compliant", "Purification": 0.0150 }
},
"isins": {
"US0378331005": { "ISIN": "US0378331005", "Market": "US", "Name": "Apple Inc", "Result": "Compliant", "Purification": 0.0123 }
}
}
}
GET /batch?tickers=AAPL,MSFT&fields=Result works too.
Market export
curl -u "USERNAME:KEY" "https://muslimxchange.com/wp-json/mx-api/v1/markets"
curl -u "USERNAME:KEY" "https://muslimxchange.com/wp-json/mx-api/v1/market/US?fields=Result,AAOIFI,SP,DJIM,FTSE,MSCI"
The response carries total and every row of the market under rows, ordered by ticker so an export is repeatable — one request per market. If you prefer smaller responses, add per_page and page and the response gains page, per_page and pages.
Python
import requests
API = "https://muslimxchange.com/wp-json/mx-api/v1"
AUTH = ("USERNAME", "xxxx xxxx xxxx xxxx xxxx xxxx")
# one listing
r = requests.get(f"{API}/ticker/AAPL", auth=AUTH, params={"fields": "Result,Purification,Zakatpershare"}, timeout=20)
r.raise_for_status()
print(r.json())
# many listings in one request
tickers = ["AAPL", "MSFT", "ASML.AS", "RY.TO"]
r = requests.post(f"{API}/batch", auth=AUTH, timeout=60,
json={"tickers": tickers, "fields": ["Result", "TotalImpurePct"]})
r.raise_for_status()
for symbol, row in r.json()["results"]["tickers"].items():
print(symbol, row["Result"] if row else "not found")
# a whole market
us = requests.get(f"{API}/market/US", auth=AUTH, params={"fields": "Result,Purification"}, timeout=120).json()
print(us["total"], "listings;", sum(1 for x in us["rows"] if x["Result"] == "Compliant"), "compliant")
JavaScript (Node 18+ or browser)
const API = "https://muslimxchange.com/wp-json/mx-api/v1";
const AUTH = "Basic " + btoa("USERNAME:xxxx xxxx xxxx xxxx xxxx xxxx");
const res = await fetch(`${API}/batch`, {
method: "POST",
headers: { "Authorization": AUTH, "Content-Type": "application/json" },
body: JSON.stringify({ tickers: ["AAPL", "MSFT"], fields: ["Result", "Purification"] })
});
if (!res.ok) throw new Error((await res.json()).message);
const data = await res.json();
console.log(data.results.tickers.AAPL.Result);
Google Sheets (Apps Script)
function SHARIAH(ticker, field) {
const res = UrlFetchApp.fetch("https://muslimxchange.com/wp-json/mx-api/v1/ticker/" + encodeURIComponent(ticker) + "?fields=" + (field || "Result"), {
headers: { Authorization: "Basic " + Utilities.base64Encode("USERNAME:KEY") },
muteHttpExceptions: true
});
const data = JSON.parse(res.getContentText());
if (res.getResponseCode() !== 200) return data.message;
return data[field || "Result"];
}
// =SHARIAH("AAPL", "Purification")
Field reference
Request any of these with fields=. basic fields are included in every plan; full fields need full field access — requesting one on a basic plan lists it under restricted_fields and the rest of the row is returned. Percentages are plain numbers (1.23 means 1.23 %); purification and zakat are per share in USD for every listing.
| Field | Type | Tier | Description |
|---|---|---|---|
ticker |
string | basic | Exchange-suffixed symbol (ASML, ASML.AS). Unique per listing. |
ISIN |
string | basic | International Securities Identification Number. One ISIN can have several listings. |
Market |
string | basic | Market code of the listing (e.g. US). |
Sector |
string | basic | Sector classification. |
Name |
string | basic | Company or fund name. |
Type |
string | basic | Instrument type. |
Result |
string | basic | Overall compliance verdict for the listing. |
Old_result |
string | basic | Verdict at the previous review. |
NoofStandards |
int | basic | How many of the eight screening standards the listing passes (0–8). |
AAOIFI |
string | basic | Verdict under the AAOIFI standard. |
SP |
string | basic | Verdict under the S&P Shariah standard. |
DJIM |
string | basic | Verdict under the Dow Jones Islamic Market standard. |
FTSE |
string | basic | Verdict under the FTSE Shariah standard. |
MSCI |
string | basic | Verdict under the MSCI Islamic standard. |
RAJHI |
string | basic | Verdict under the Al Rajhi standard. |
ALINMA |
string | basic | Verdict under the Alinma standard. |
BILAD |
string | basic | Verdict under the Al Bilad standard. |
ImpureSeg |
string | basic | Impermissible business segment(s) identified. |
ImpureSegPct |
float | basic | Revenue share from impermissible segments, %. |
InterestPct |
float | basic | Interest income as a share of revenue, %. |
TotalImpurePct |
float | basic | Total impermissible income as a share of revenue, %. |
Purification |
float | basic | Purification amount per share, in USD for every listing. |
Zakatpershare |
float | basic | Zakat per share, in USD for every listing. |
DJIMDEBTRESULT |
string | full | Debt-ratio test result, DJIM. |
AAOIFIDEBTRESULT |
string | full | Debt-ratio test result, AAOIFI. |
AAOIFINCARESULT |
string | full | NCA-ratio test result, AAOIFI (glossary). |
IMPURERESULT |
string | full | Impermissible-income test result. |
FMDEBTRESULT |
string | full | Debt-ratio test result, FTSE/MSCI. |
FMCASHRESULT |
string | full | Cash-ratio test result, FTSE/MSCI. |
FCASHARRESULT |
string | full | Cash & receivables test result, FTSE. |
MCASHARRESULT |
string | full | Cash & receivables test result, MSCI. |
SPDEBTRESULT |
string | full | Debt-ratio test result, S&P. |
RAJHIDEBTRESULT |
string | full | Debt-ratio test result, Al Rajhi. |
RAJHINCARESULT |
string | full | NCA-ratio test result, Al Rajhi (glossary). |
ALINMADEBTRESULT |
string | full | Debt-ratio test result, Alinma. |
ALINMANCARESULT |
string | full | NCA-ratio test result, Alinma (glossary). |
BILADDEBTRESULT |
string | full | Debt-ratio test result, Al Bilad. |
BILADNCARESULT |
string | full | NCA-ratio test result, Al Bilad (glossary). |
DJIMDEBT |
float | full | Debt ratio, DJIM basis. |
FMDEBT |
float | full | Debt ratio, FTSE/MSCI basis. |
FMCASH |
float | full | Cash ratio, FTSE/MSCI basis. |
FMCASHAR |
float | full | Cash & receivables ratio, FTSE/MSCI basis. |
AAOIFIDEBT |
float | full | Debt ratio, AAOIFI basis. |
AAOIFINCA |
float | full | NCA ratio, AAOIFI basis (glossary). |
SPDEBT |
float | full | Debt ratio, S&P basis. |
NCAA |
float | full | (glossary) |
Bscreen |
string | basic | Business screen result (glossary). |
P1 |
float | basic | (glossary) |
P2 |
float | basic | (glossary) |
P3 |
float | basic | (glossary) |
P4 |
float | basic | (glossary) |
Dual-listed ISINs
Tickers are exchange-suffixed, so a ticker always names exactly one listing. An ISIN names the security, and a security listed on two exchanges has two rows. GET /isin/NL0010273215 returns the first listing with "ambiguous": true and every listing under alternatives, each a complete row; add ?market=US to get just one.
{
"ISIN": "NL0010273215", "Market": "NL", "Name": "ASML Holding", "Result": "Compliant",
"ambiguous": true,
"alternatives": [
{ "ISIN": "NL0010273215", "ticker": "ASML.AS", "Market": "NL", "Name": "ASML Holding", "Result": "Compliant" },
{ "ISIN": "NL0010273215", "ticker": "ASML", "Market": "US", "Name": "ASML Holding", "Result": "Compliant" }
]
}
Errors & headers
Errors are JSON with a stable code, a human message and data.status.
| Status | Code | Meaning |
|---|---|---|
| 401 | mx_api_unauthorized |
Missing or wrong username/key. |
| 403 | mx_api_no_access |
Your plan has no API access. |
| 403 | mx_api_tier |
Market export is not available on the free trial. |
| 403 | mx_api_field_restricted |
Every field you asked for needs full field access. data.restricted_fields lists them. |
| 403 | mx_api_forbidden_host |
The key belongs to a different site. |
| 404 | mx_api_not_found |
No listing for that identifier (or none in that market). |
| 400 | mx_api_invalid_fields |
No valid field names in the request. |
| 400 | mx_api_batch_too_large |
Only if a batch cap is configured (batch_max in the error data). |
| 429 | mx_api_rate_limited |
Only if a per-account limit is configured — wait Retry-After seconds. |
| 429 | mx_api_quota_exceeded |
Free-trial daily lookup used; resets at midnight. |
| 429 | mx_api_too_many_attempts |
Too many failed sign-ins from your address. |
| 503 | mx_api_unavailable |
Data service temporarily down — retry after Retry-After; the data is not missing. |
| 503 | mx_api_busy |
The service as a whole is briefly saturated — retry after Retry-After (a few seconds). |
Every response carries X-API-Version, X-API-Dataset (which screening publication you are reading) and X-API-Limits; 429 and 503 add Retry-After. Responses are never cached — do not cache verdicts on your side for longer than a trading day.
Rate limits & usage
- No per-account limits on paid plans: no request cap, no batch cap, no daily allowance, no pagination. (The free trial has one lookup a day.)
- Read many listings with one
/batchcall rather than one request per ticker, and a whole market with one/marketcall — it is faster for you and lighter for everyone. - If the service as a whole is briefly saturated you get
503withRetry-After: 5— wait and retry; it is not an error in your request.
Should a limit ever be introduced it will appear in the X-API-Limits response header and in GET /me (a value of 0 means unlimited), so a client can adapt without a docs change.
Screening data is updated on the platform’s publication schedule, not intraday — poll it daily, not continuously.
Availability
We commit to 99.9% monthly uptime for the API, on SLA-backed managed infrastructure. Live status and history are on the status page linked from your API keys page, and GET /health (no authentication) answers 200 with "status": "ok" whenever the service and its data table are reachable — point your own monitor at it.
- Dataset refreshes take a few seconds, during which lookups may answer
503withRetry-After; treat that as a retry, never as missing data. Longer maintenance is announced in advance on the status page. - Requests that fail with
429or a burst503are your client being asked to slow down, not an outage — honourRetry-After. - Uptime is measured by external monitors against
/health; scheduled maintenance is excluded.
Excel add-in
The Muslim Xchange add-in brings the same data into spreadsheet formulas with no code:
=MX.TICKER("AAPL") → overall verdict
=MX.TICKER("AAPL","AAOIFI","Purification") → several fields, spilled across the row
=MX.TICKER(A2, $B$1:$E$1) → field names from a header row
=MX.ISIN("NL0010273215","ticker","Result") → one row per listing for a dual-listed ISIN
=MX.FIELDS() → every field, its type, tier and availability
Install it from the Excel add-in page, open the pane from the Home tab and sign in with your username and the same API key. Cells recalculating together are sent as a single batch, so even a large sheet is a handful of requests.
Connect Claude or ChatGPT
Every plan with API access can plug the data straight into an AI assistant through an MCP server, so you can ask in plain language — “is ASML compliant under AAOIFI, and what is the purification per share?” — or paste a list of holdings and have it screened. The assistant uses your plan’s access and counts toward your usage; it never sees your account or keys.
https://muslimxchange.com/mcp-server- Claude (web, desktop or mobile): open Muslim Xchange in the connector directory and click Add — or search “Muslim Xchange” under Customize → Connectors. ChatGPT: Settings → Connectors → create a custom connector with the URL above.
- Click Connect. A window opens on this site: sign in if you are not already, then Allow.
- In a chat, enable the connector and ask. It provides
check_ticker,check_isin,check_portfolio,market_summary,list_marketsandlist_fields, plus a Screen my portfolio prompt.
Things to ask once it is connected:
- “Is ASML.AS compliant under AAOIFI, and what is its purification per share?”
- “Screen these holdings: AAPL 100, MSFT 50, RY.TO 200 — list any that are non-compliant and show the impermissible income share.”
- “How many listings in the US market pass the DJIM screen?”
- “Which fields can my plan read?”
Connected assistants are listed on your API keys page, where you can disconnect one at any time. Field access follows your plan exactly as it does for the API. If you build your own MCP client, the server speaks the standard protocol over HTTPS with OAuth 2.1 (PKCE, dynamic client registration); discovery is at /.well-known/oauth-authorization-server.
Legacy endpoints
Integrations built on /wp-json/proxy/v1/ticker-data, isin-data and batch/market-data with username/password query parameters keep working, but that form is deprecated (responses carry Deprecation: true): it puts credentials in URLs, returns every value as text, and says "Not Found" for empty cells. Move to the routes above when convenient — same key, Basic auth, typed JSON.
Support
Questions, a field you cannot find, or a listing that looks wrong: support@muslimxchange.com. Include the request URL and the X-API-Version and X-API-Dataset headers from the response.
