> ## 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.

# ETF Purification

> Read ETF purity and per-holding compliance to guide purification.

## Overview

An ETF holds many underlying stocks, some compliant and some not. halal.sh screens each holding and rolls the results up into a single purity figure, so you can tell at a glance how much of a fund is Shariah-compliant by weight.

Two endpoints cover the workflow:

<CardGroup cols={2}>
  <Card title="GET /etfs/{symbol}" icon="percent">
    Fund-level `purity` — the headline compliant-by-weight percentage plus
    holding counts.
  </Card>

  <Card title="GET /etfs/{symbol}/holdings" icon="list">
    The per-holding breakdown, with each holding's compliance status and weight.
  </Card>
</CardGroup>

## Get fund-level purity

```bash theme={null}
curl https://api.halal.sh/v1/etfs/SPY \
  -H "X-API-Key: hsh_sandbox_your_key"
```

```json theme={null}
{
  "data": {
    "symbol": "SPY",
    "name": "SPDR S&P 500 ETF Trust",
    "purity": {
      "percentage": 66.74,
      "compliant_holdings": 289,
      "non_compliant_holdings": 156,
      "unanalyzed_holdings": 58,
      "top_10_coverage": 99.95,
      "as_of": "2026-06-02T00:00:00Z"
    }
  }
}
```

`purity.percentage` is a **percentage number, not a decimal**: `66.74` means 66.74% of the fund is compliant **by weight**. The holding counts break the fund down by status:

| Field                    | Meaning                                                                  |
| ------------------------ | ------------------------------------------------------------------------ |
| `purity.percentage`      | Share of the fund's weight that is Shariah-compliant (`66.74` = 66.74%)  |
| `compliant_holdings`     | Number of holdings screened as compliant                                 |
| `non_compliant_holdings` | Number of holdings screened as non-compliant                             |
| `unanalyzed_holdings`    | Holdings not yet analysed — excluded from the compliant weight           |
| `top_10_coverage`        | Share of fund weight held by its 10 largest positions (`99.95` = 99.95%) |

<Note>
  Purity is weighted, so the percentage won't match the raw count of compliant
  holdings. A handful of large non-compliant positions can pull `percentage`
  down even when most holdings pass, and `unanalyzed_holdings` represents weight
  that simply isn't counted as compliant yet.
</Note>

## Get the per-holding breakdown

```bash theme={null}
curl https://api.halal.sh/v1/etfs/SPY/holdings \
  -H "X-API-Key: hsh_sandbox_your_key"
```

```json theme={null}
{
  "data": {
    "symbol": "SPY",
    "holdings": [
      { "symbol": "AAPL", "name": "Apple Inc.", "weight": 7.12, "compliance_status": "compliant" },
      { "symbol": "JPM", "name": "JPMorgan Chase & Co.", "weight": 1.34, "compliance_status": "non-compliant" },
      { "symbol": "EXMPL", "name": "Example Corp.", "weight": 0.18, "compliance_status": "pending" }
    ]
  }
}
```

Each holding's `weight` is a **percentage number** (`7.12` = 7.12% of the fund), and `compliance_status` is one of `compliant`, `non-compliant`, or `pending`.

To find the positions dragging purity down, filter for non-compliant holdings and sort by weight:

```javascript theme={null}
const res = await fetch("https://api.halal.sh/v1/etfs/SPY/holdings", {
  headers: { "X-API-Key": process.env.HALALSH_API_KEY },
});
const { data } = await res.json();

const offenders = data.holdings
  .filter((h) => h.compliance_status === "non-compliant")
  .sort((a, b) => b.weight - a.weight);

console.log(offenders); // heaviest non-compliant positions first
```

## How a holder thinks about purification

A common approach for someone who already holds the ETF:

<Steps>
  <Step title="Read the purity percentage">
    `purity.percentage` tells you what share of the fund is compliant by weight.
    The remainder comes from non-compliant (and not-yet-analysed) holdings.
  </Step>

  <Step title="Estimate the non-compliant share">
    The portion to purify corresponds to the weight that isn't compliant —
    roughly `100 − purity.percentage` percent of income attributable to
    non-compliant holdings. Treat `unanalyzed_holdings` conservatively, since
    their weight isn't yet counted as compliant.
  </Step>

  <Step title="Apply it to income received">
    Multiply that non-compliant share by the dividends (or distributions) you
    received to estimate the amount to purify by giving it away.
  </Step>
</Steps>

<Warning>
  These figures are screening outputs, not financial or religious advice.
  Purification methodology varies — present the data and let users (or their
  scholars) decide how to act on it.
</Warning>

## Use cases

* **Robo-advisors** — rank funds by `purity.percentage` so users can pick the most compliant ETF.
* **Portfolio tools** — weight each ETF's purity by position size to estimate portfolio-level purity.
* **Research** — track how a fund's purity shifts over time as its holdings change.
