> ## Documentation Index
> Fetch the complete documentation index at: https://docs.halal.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Screen a Portfolio

> Check Shariah compliance for a list of stocks in a single API call.

## Overview

`POST /v1/screen` checks compliance for up to **50 symbols** in one request. It's the fastest way to screen a portfolio, validate a watchlist, or power a compliance dashboard without making one call per stock.

Each result carries a `compliance_status` you can read directly. Need the underlying ratios? Enrich any symbol with a follow-up call to `/compliance` (see [Enrich with per-stock screens](#enrich-with-per-stock-screens) below).

## Screen a list of symbols

Pass a `symbols` array. The sandbox key works against the 12 pre-analysed sandbox instruments.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.halal.sh/v1/screen \
    -H "X-API-Key: hsh_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "symbols": ["AAPL", "MSFT", "NVDA", "JPM", "TSLA"]
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.halal.sh/v1/screen", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.HALALSH_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      symbols: ["AAPL", "MSFT", "NVDA", "JPM", "TSLA"],
    }),
  });

  const { data } = await response.json();
  ```
</CodeGroup>

## Response

`data` is a flat array — every entry includes a `compliance_status` of `compliant`, `non-compliant`, or `pending`.

```json theme={null}
{
  "data": [
    { "symbol": "AAPL", "name": "Apple Inc.", "compliance_status": "compliant", "health_status": "antifragile", "market_data": { "price": 315.02, "change_24h": 8.71, "change_percent_24h": 2.84 } },
    { "symbol": "MSFT", "name": "Microsoft Corporation", "compliance_status": "compliant", "health_status": "antifragile", "market_data": { "price": 441.45, "change_24h": -19.10, "change_percent_24h": -4.15 } },
    { "symbol": "JPM", "name": "JPMorgan Chase & Co.", "compliance_status": "non-compliant", "health_status": "fragile", "market_data": { "price": 301.00, "change_24h": 4.42, "change_percent_24h": 1.49 } }
  ],
  "meta": { "total": 3, "requested": 3, "not_found": [] }
}
```

`/screen` screens **stocks**. Unknown tickers — and ETF tickers, which belong to [`GET /etfs/{symbol}`](/api-reference/etfs/get-etf) — are returned in `meta.not_found` rather than as fabricated rows. On a **sandbox key**, any requested symbol outside the sandbox universe is returned in `meta.sandbox_restricted` (present only when non-empty) instead of being silently dropped.

Read the status straight off each result:

```javascript theme={null}
const { data } = await response.json();

const compliant = data.filter(
  (r) => r.compliance_status === "compliant"
);

console.log(`${compliant.length} of ${data.length} symbols are compliant`);
```

<Note>
  A `compliance_status` of `pending` means the instrument hasn't been analysed
  yet — its screens aren't available. See
  [Handle Pending Analysis](/guides/handle-pending-analysis) for how to treat
  these gracefully.
</Note>

## Enrich with per-stock screens

`POST /screen` gives you the verdict per symbol. To show *why* a stock passed or failed, fetch the three financial screens from `GET /instruments/{symbol}/compliance` for the symbols you want to drill into.

```javascript theme={null}
async function enrich(symbol) {
  const res = await fetch(`https://api.halal.sh/v1/instruments/${symbol}/compliance`, {
    headers: { "X-API-Key": process.env.HALALSH_API_KEY },
  });
  const { data } = await res.json();
  const { screens } = data;

  return {
    symbol,
    status: data.determination.status,
    debtOk: screens.debt_to_market_cap.result === "pass",
    cashOk: screens.cash_to_market_cap.result === "pass",
    revenueOk: screens.prohibited_revenue.result === "pass",
  };
}
```

Each financial screen exposes a `result` of `"pass"` or `"fail"` — there is no boolean `passes` field. Check `screens.debt_to_market_cap.result === "pass"`, not `screens.debt_to_market_cap.passes`.

The three financial screen keys are always:

| Key                  | What it measures                                              |
| -------------------- | ------------------------------------------------------------- |
| `debt_to_market_cap` | Interest-bearing debt as a share of market cap                |
| `cash_to_market_cap` | Cash and interest-bearing securities as a share of market cap |
| `prohibited_revenue` | Revenue from non-permissible activities                       |

`value` and `threshold` are decimals (`0.30` = 30%) and `buffer` is in percentage points.

## Limits

<Warning>
  A single `/screen` request accepts at most **50 symbols**. Split larger
  portfolios into batches of 50.
</Warning>

**Filter mode is a Plus capability.** On Plus you can screen the analysed universe by attributes (status, sector, and similar) instead of listing symbols. On the sandbox and free tiers, always pass an explicit `symbols` array.
