curl --request POST \
--url https://api.halal.sh/v1/screen \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"symbols": [
"AAPL",
"MSFT",
"PAR:AI",
"HKG:2020",
"BRK.B"
],
"sector": "<string>",
"country": "GB",
"sort": "symbol",
"limit": 50,
"offset": 0
}
'import requests
url = "https://api.halal.sh/v1/screen"
payload = {
"symbols": ["AAPL", "MSFT", "PAR:AI", "HKG:2020", "BRK.B"],
"sector": "<string>",
"country": "GB",
"sort": "symbol",
"limit": 50,
"offset": 0
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
symbols: ['AAPL', 'MSFT', 'PAR:AI', 'HKG:2020', 'BRK.B'],
sector: '<string>',
country: 'GB',
sort: 'symbol',
limit: 50,
offset: 0
})
};
fetch('https://api.halal.sh/v1/screen', 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/screen",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'symbols' => [
'AAPL',
'MSFT',
'PAR:AI',
'HKG:2020',
'BRK.B'
],
'sector' => '<string>',
'country' => 'GB',
'sort' => 'symbol',
'limit' => 50,
'offset' => 0
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.halal.sh/v1/screen"
payload := strings.NewReader("{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.halal.sh/v1/screen")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.halal.sh/v1/screen")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"symbol": "AAPL",
"instrument_id": "LON:BA",
"country_code": "GB",
"name": "Apple Inc.",
"compliance_status": "compliant",
"health_status": "fragile",
"market_data": {
"price": 123,
"change_24h": 123,
"change_percent_24h": 123
}
}
],
"meta": {
"request_id": "req_abc123",
"as_of": "2023-11-07T05:31:56Z",
"methodology": "aaoifi-ss21@2026.1",
"total": 123,
"requested": 123,
"not_found": [
"<string>"
],
"etfs": [
"<string>"
],
"sandbox_restricted": [
"<string>"
],
"limit": 123,
"offset": 123
}
}{
"error": {
"code": "bad_request",
"message": "Maximum 50 symbols per request."
},
"meta": {
"request_id": "req_abc123"
}
}{
"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": "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"
}
}Screen Instruments
Screen stocks in one request. Provide either:
symbols: up to 50 specific stock tickers (available on every plan), or- filters (
status,sector,market_cap,health,country, ordered bysort) to discover matching stocks across the universe (requires the Plus or Developer plan).countryandsortapply to filter mode only.
This endpoint screens equities. Fund tickers don’t resolve here: they
come back in meta.not_found, and the ones we cover are named in
meta.etfs; use GET /etfs/{symbol} for those. Commodity and crypto
trusts we screen under AAOIFI directly, such as GLD, IAU, SLV, IBIT and
USO, do return a determination here.
Returns 200 with an empty array when nothing matches.
curl --request POST \
--url https://api.halal.sh/v1/screen \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"symbols": [
"AAPL",
"MSFT",
"PAR:AI",
"HKG:2020",
"BRK.B"
],
"sector": "<string>",
"country": "GB",
"sort": "symbol",
"limit": 50,
"offset": 0
}
'import requests
url = "https://api.halal.sh/v1/screen"
payload = {
"symbols": ["AAPL", "MSFT", "PAR:AI", "HKG:2020", "BRK.B"],
"sector": "<string>",
"country": "GB",
"sort": "symbol",
"limit": 50,
"offset": 0
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
symbols: ['AAPL', 'MSFT', 'PAR:AI', 'HKG:2020', 'BRK.B'],
sector: '<string>',
country: 'GB',
sort: 'symbol',
limit: 50,
offset: 0
})
};
fetch('https://api.halal.sh/v1/screen', 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/screen",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'symbols' => [
'AAPL',
'MSFT',
'PAR:AI',
'HKG:2020',
'BRK.B'
],
'sector' => '<string>',
'country' => 'GB',
'sort' => 'symbol',
'limit' => 50,
'offset' => 0
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.halal.sh/v1/screen"
payload := strings.NewReader("{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.halal.sh/v1/screen")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.halal.sh/v1/screen")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"symbols\": [\n \"AAPL\",\n \"MSFT\",\n \"PAR:AI\",\n \"HKG:2020\",\n \"BRK.B\"\n ],\n \"sector\": \"<string>\",\n \"country\": \"GB\",\n \"sort\": \"symbol\",\n \"limit\": 50,\n \"offset\": 0\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"symbol": "AAPL",
"instrument_id": "LON:BA",
"country_code": "GB",
"name": "Apple Inc.",
"compliance_status": "compliant",
"health_status": "fragile",
"market_data": {
"price": 123,
"change_24h": 123,
"change_percent_24h": 123
}
}
],
"meta": {
"request_id": "req_abc123",
"as_of": "2023-11-07T05:31:56Z",
"methodology": "aaoifi-ss21@2026.1",
"total": 123,
"requested": 123,
"not_found": [
"<string>"
],
"etfs": [
"<string>"
],
"sandbox_restricted": [
"<string>"
],
"limit": 123,
"offset": 123
}
}{
"error": {
"code": "bad_request",
"message": "Maximum 50 symbols per request."
},
"meta": {
"request_id": "req_abc123"
}
}{
"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": "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"
}
}Body
Specific identifiers to screen (max 50). Available on every plan.
Same identifiers as /instruments/{symbol}: a bare US ticker or an
exchange-prefixed listing (PAR:AI, HKG:2020). Each row echoes
the identifier you sent in upper case, and one we hold no listing for comes back
in meta.not_found. Dotted share classes (BRK.B) resolve here as
everywhere.
501 - 20[
"AAPL",
"MSFT",
"PAR:AI",
"HKG:2020",
"BRK.B"
]

