Get an ETF
curl --request GET \
--url https://api.halal.sh/v1/etfs/{symbol} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.halal.sh/v1/etfs/{symbol}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.halal.sh/v1/etfs/{symbol}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.halal.sh/v1/etfs/{symbol}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.halal.sh/v1/etfs/{symbol}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.halal.sh/v1/etfs/{symbol}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.halal.sh/v1/etfs/{symbol}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"symbol": "SPY",
"name": "SPDR S&P 500 ETF",
"exchange": "NYSE",
"fund_family": "SPDR",
"category": "Equity",
"geographic_focus": "US",
"status": "active",
"purity": {
"percentage": 66.74,
"compliant_holdings": 247,
"non_compliant_holdings": 253,
"unanalyzed_holdings": 3,
"top_10_coverage": 99.95,
"as_of": "2023-11-07T05:31:56Z",
"holdings_as_of": "2026-08-31"
}
},
"meta": {
"request_id": "req_abc123",
"as_of": "2023-11-07T05:31:56Z",
"methodology": "aaoifi-ss21@2026.1"
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "sandbox_restricted",
"message": "Symbol 'COST' is not available in the sandbox. The sandbox includes AAPL, MSFT, NVDA, GOOGL, JPM, GS, META, TSLA, JNJ and AMZN, and the ETFs SPY and HLAL. Full access needs a live key, which the Plus plan includes for $7 a month: https://halal.sh/plans?source=api_refusal. To show results in your own product, you need the Developer plan, at $99 a month: https://halal.sh/developers.",
"upgrade": {
"plan": "plus",
"price_usd_monthly": 7,
"url": "https://halal.sh/plans?source=api_refusal",
"commercial_plan": "developer",
"commercial_price_usd_monthly": 99,
"commercial_url": "https://halal.sh/developers"
}
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "not_found",
"message": "Stock with identifier 'XYZ' not found"
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Daily limit of 100 requests reached. It resets at midnight UTC. The Plus plan includes up to 2,000 requests a day on every stock and ETF we cover, for $7 a month: https://halal.sh/plans?source=api_refusal. To show results in your own product, you need the Developer plan, at $99 a month: https://halal.sh/developers.",
"retry_after": 3600,
"upgrade": {
"plan": "plus",
"price_usd_monthly": 7,
"url": "https://halal.sh/plans?source=api_refusal",
"commercial_plan": "developer",
"commercial_price_usd_monthly": 99,
"commercial_url": "https://halal.sh/developers"
}
},
"meta": {
"request_id": "req_abc123"
}
}ETFs
Get ETF
Returns fund identity and the current Shariah purity: the percentage of holdings (by weight) that are compliant, with a breakdown of compliant, non-compliant, and not-yet-analyzed holdings.
GET
/
etfs
/
{symbol}
Get an ETF
curl --request GET \
--url https://api.halal.sh/v1/etfs/{symbol} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.halal.sh/v1/etfs/{symbol}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.halal.sh/v1/etfs/{symbol}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.halal.sh/v1/etfs/{symbol}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.halal.sh/v1/etfs/{symbol}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.halal.sh/v1/etfs/{symbol}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.halal.sh/v1/etfs/{symbol}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"symbol": "SPY",
"name": "SPDR S&P 500 ETF",
"exchange": "NYSE",
"fund_family": "SPDR",
"category": "Equity",
"geographic_focus": "US",
"status": "active",
"purity": {
"percentage": 66.74,
"compliant_holdings": 247,
"non_compliant_holdings": 253,
"unanalyzed_holdings": 3,
"top_10_coverage": 99.95,
"as_of": "2023-11-07T05:31:56Z",
"holdings_as_of": "2026-08-31"
}
},
"meta": {
"request_id": "req_abc123",
"as_of": "2023-11-07T05:31:56Z",
"methodology": "aaoifi-ss21@2026.1"
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "sandbox_restricted",
"message": "Symbol 'COST' is not available in the sandbox. The sandbox includes AAPL, MSFT, NVDA, GOOGL, JPM, GS, META, TSLA, JNJ and AMZN, and the ETFs SPY and HLAL. Full access needs a live key, which the Plus plan includes for $7 a month: https://halal.sh/plans?source=api_refusal. To show results in your own product, you need the Developer plan, at $99 a month: https://halal.sh/developers.",
"upgrade": {
"plan": "plus",
"price_usd_monthly": 7,
"url": "https://halal.sh/plans?source=api_refusal",
"commercial_plan": "developer",
"commercial_price_usd_monthly": 99,
"commercial_url": "https://halal.sh/developers"
}
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "not_found",
"message": "Stock with identifier 'XYZ' not found"
},
"meta": {
"request_id": "req_abc123"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Daily limit of 100 requests reached. It resets at midnight UTC. The Plus plan includes up to 2,000 requests a day on every stock and ETF we cover, for $7 a month: https://halal.sh/plans?source=api_refusal. To show results in your own product, you need the Developer plan, at $99 a month: https://halal.sh/developers.",
"retry_after": 3600,
"upgrade": {
"plan": "plus",
"price_usd_monthly": 7,
"url": "https://halal.sh/plans?source=api_refusal",
"commercial_plan": "developer",
"commercial_price_usd_monthly": 99,
"commercial_url": "https://halal.sh/developers"
}
},
"meta": {
"request_id": "req_abc123"
}
}
