
# How to Use Advanced Growth Filters in the Screener API {#intro}


Canonical HTML page: [/docs/api/v1/examples/advanced-growth-filters/](/docs/api/v1/examples/advanced-growth-filters/)

LLM-friendly Markdown page: [/docs/api/v1/examples/advanced-growth-filters.md](/docs/api/v1/examples/advanced-growth-filters.md)




Some screener filters are simple: send a minimum market cap, a country, or a sector. Growth filters are different. They let you ask a more specific question: which metric should grow, over what horizon, measured how, and by how much?

Once you understand the pattern, you can build surprisingly precise screens with just a few lines of JSON. This article focuses on `incomeStatementGrowth` because it is the clearest way to learn the structure. Once that clicks, the same logic carries over to share count, balance sheet, and cash flow growth filters.

For the endpoint contract, request envelope, and generated Postman collection, see the [API v1 screener reference](/docs/api/v1/#screener). If you want simpler request examples before this article, start with the [starter-screen screener examples](/docs/api/v1/examples/screener-starter-screens/).

## 1.0 The growth filter family {#growth-family}

The advanced screener supports four growth-rule filters. Each one takes a `rules` array, and each rule specifies a metric, a time horizon, a value type, a currency basis, and a threshold.

| Filter | API field | Max rules | What it screens |
| --- | --- | --- | --- |
| Income Statement Growth | incomeStatementGrowth | 5 | Revenue, gross profit, EBITDA, EBIT, operating income, net income, EPS, and other income-statement metrics. |
| Share Count Growth | shareCountGrowth | 5 | Basic or diluted share count, useful for finding companies that have reduced, held flat, or grown their share count over time. |
| Balance Sheet Growth | balanceSheetGrowth | 5 | Assets, debt, equity, book value per share, and other balance-sheet measures. |
| Cash Flow Growth | cashFlowGrowth | 5 | Operating cash flow, free cash flow, CapEx, dividends, and per-share cash-flow measures. |

## 2.0 How Income Statement Growth rules work {#income-statement-growth}

Each rule inside `incomeStatementGrowth` combines into a single logical statement, such as: revenue grew at least 10% per year over the past five years, measured in reported currency. Here is what each field controls.

| Field | Example value | What it controls |
| --- | --- | --- |
| metric | revenue | The income-statement metric you want to evaluate. |
| horizon_years | 1, 2, 3, 5, 7, 8, 10 | How far back to look. Use `/api/v1/screener/options/` to confirm the current allowed values. |
| value_type | cagr, multiple | CAGR gives you annualized growth rate. Multiple gives you total growth over the horizon, so 2.0 means doubled. |
| currency_basis | reported, usd | Use reported to evaluate each company in its own currency. Use USD to normalize across currencies when comparing companies from different countries. |
| min / max | 0.10, 2.0 | The threshold. For CAGR, 0.10 means 10% annualized. For a multiple, 2.0 means the metric has at least doubled. |

You can include up to 5 rules in a single filter. Companies that do not have enough history for the chosen horizon are excluded automatically.

## 3.0 Find companies with sustained revenue growth {#sustained-revenue-growth}

### The goal

A clean first pass for companies that have been genuinely expanding, not just companies that had one great year.

### Why this filter works

Revenue CAGR over five years is one of the most reliable ways to find real demand growth. The five-year window smooths out a lucky quarter and forces you to look at a fuller business cycle.

### Where to take it next

This is a starting filter, not a final answer. Once you have results, layer in profitability or balance-sheet screens to separate businesses that are growing healthily from ones growing at any cost.

### Rule breakdown

| Metric | API metric | Payload setting | What it does |
| --- | --- | --- | --- |
| Revenue | revenue | revenue, 5-year CAGR, reported currency, min: 0.1 | Keeps companies where Revenue CAGR over 5 years, measured in reported currency, is at least 0.1. |

### Request body

This request keeps companies where reported revenue CAGR is at least 10% over five years. Send this body to `/api/v1/screener/advanced/`.


```json
{
  "filters": {
    "incomeStatementGrowth": {
      "rules": [
        {
          "metric": "revenue",
          "horizon_years": 5,
          "value_type": "cagr",
          "currency_basis": "reported",
          "min": 0.1
        }
      ]
    }
  },
  "sort": {},
  "page": {
    "limit": 100,
    "offset": 0
  },
  "fields": [
    "full_ticker",
    "companyName",
    "marketCap_usd"
  ],
  "result_format": "rows"
}
```


### Code


### curl

```bash
curl -X POST "https://www.dfin.pro/api/v1/screener/advanced/" \
  -H "Authorization: Bearer ${DFIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"incomeStatementGrowth":{"rules":[{"metric":"revenue","horizon_years":5,"value_type":"cagr","currency_basis":"reported","min":0.1}]}},"sort":{},"page":{"limit":100,"offset":0},"fields":["full_ticker","companyName","marketCap_usd"],"result_format":"rows"}'
```

### Python

```python
import os, requests

url = "https://www.dfin.pro/api/v1/screener/advanced/"
headers = {"Authorization": f"Bearer {os.environ['DFIN_API_KEY']}"}
payload = {'filters': {'incomeStatementGrowth': {'rules': [{'metric': 'revenue',
                                                  'horizon_years': 5,
                                                  'value_type': 'cagr',
                                                  'currency_basis': 'reported',
                                                  'min': 0.1}]}},
 'sort': {},
 'page': {'limit': 100, 'offset': 0},
 'fields': ['full_ticker', 'companyName', 'marketCap_usd'],
 'result_format': 'rows'}

response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.json())
```



## 4.0 Find companies where EBITDA has doubled {#ebitda-doubled}

### The goal

Surface businesses where earnings power has expanded dramatically over a shorter window.

### Why this filter works

Sometimes you care less about the annualized rate and more about the total change. That is where `multiple` is more useful than `cagr`: a multiple of 2.0 simply means the metric is at least twice what it was at the start of the horizon. Concrete, easy to reason about.

This example also uses `currency_basis: usd`, which normalizes EBITDA into USD before applying the threshold. That is useful when your screen includes companies that report in different currencies and you want a like-for-like comparison.

### Where to take it next

Companies that pass this screen have grown fast, but they are not necessarily profitable or well-capitalized. Add a net income or leverage filter to narrow toward companies where the growth looks durable.

### Rule breakdown

| Metric | API metric | Payload setting | What it does |
| --- | --- | --- | --- |
| EBITDA | ebitda | ebitda, 3-year growth multiple, USD, min: 2.0 | Keeps companies where EBITDA growth multiple over 3 years, measured in USD, is at least 2.0. |

### Request body

This request keeps companies where USD EBITDA growth multiple is at least 2.0 over three years. Send this body to `/api/v1/screener/advanced/`.


```json
{
  "filters": {
    "incomeStatementGrowth": {
      "rules": [
        {
          "metric": "ebitda",
          "horizon_years": 3,
          "value_type": "multiple",
          "currency_basis": "usd",
          "min": 2.0
        }
      ]
    }
  },
  "sort": {},
  "page": {
    "limit": 100,
    "offset": 0
  },
  "fields": [
    "full_ticker",
    "companyName",
    "marketCap_usd"
  ],
  "result_format": "rows"
}
```


### Code


### curl

```bash
curl -X POST "https://www.dfin.pro/api/v1/screener/advanced/" \
  -H "Authorization: Bearer ${DFIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"incomeStatementGrowth":{"rules":[{"metric":"ebitda","horizon_years":3,"value_type":"multiple","currency_basis":"usd","min":2.0}]}},"sort":{},"page":{"limit":100,"offset":0},"fields":["full_ticker","companyName","marketCap_usd"],"result_format":"rows"}'
```

### Python

```python
import os, requests

url = "https://www.dfin.pro/api/v1/screener/advanced/"
headers = {"Authorization": f"Bearer {os.environ['DFIN_API_KEY']}"}
payload = {'filters': {'incomeStatementGrowth': {'rules': [{'metric': 'ebitda',
                                                  'horizon_years': 3,
                                                  'value_type': 'multiple',
                                                  'currency_basis': 'usd',
                                                  'min': 2.0}]}},
 'sort': {},
 'page': {'limit': 100, 'offset': 0},
 'fields': ['full_ticker', 'companyName', 'marketCap_usd'],
 'result_format': 'rows'}

response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.json())
```



## 5.0 Find steadier growers, not extreme outliers {#steadier-growers}

### The goal

A growth screen that filters out the most explosive names as well as the slow ones, useful when you want a research list you can actually underwrite.

### Why this filter works

This is where the `max` threshold earns its place. A minimum of 8% revenue CAGR keeps the slow growers out; a maximum of 40% keeps out the hypergrowth names that are harder to analyze and often harder to value. The second rule, requiring at least 5% net income CAGR, asks whether some of that top-line growth is actually reaching the bottom line.

### Where to take it next

This kind of bounded universe is a useful foundation for valuation work. Add sector and size filters if you want to compare companies within a tighter peer group.

### Rule breakdown

| Metric | API metric | Payload setting | What it does |
| --- | --- | --- | --- |
| Revenue | revenue | revenue, 5-year CAGR, reported currency, min: 0.08, max: 0.4 | Keeps companies where Revenue CAGR over 5 years, measured in reported currency, is between 0.08 and 0.4. |
| Net Income | netIncome | netIncome, 5-year CAGR, reported currency, min: 0.05 | Keeps companies where Net Income CAGR over 5 years, measured in reported currency, is at least 0.05. |

### Request body

This request combines two Income Statement Growth rules: revenue CAGR must be between 8% and 40%, and net income CAGR must be at least 5%. Send this body to `/api/v1/screener/advanced/`.


```json
{
  "filters": {
    "incomeStatementGrowth": {
      "rules": [
        {
          "metric": "revenue",
          "horizon_years": 5,
          "value_type": "cagr",
          "currency_basis": "reported",
          "min": 0.08,
          "max": 0.4
        },
        {
          "metric": "netIncome",
          "horizon_years": 5,
          "value_type": "cagr",
          "currency_basis": "reported",
          "min": 0.05
        }
      ]
    }
  },
  "sort": {},
  "page": {
    "limit": 100,
    "offset": 0
  },
  "fields": [
    "full_ticker",
    "companyName",
    "marketCap_usd"
  ],
  "result_format": "rows"
}
```


### Code


### curl

```bash
curl -X POST "https://www.dfin.pro/api/v1/screener/advanced/" \
  -H "Authorization: Bearer ${DFIN_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"incomeStatementGrowth":{"rules":[{"metric":"revenue","horizon_years":5,"value_type":"cagr","currency_basis":"reported","min":0.08,"max":0.4},{"metric":"netIncome","horizon_years":5,"value_type":"cagr","currency_basis":"reported","min":0.05}]}},"sort":{},"page":{"limit":100,"offset":0},"fields":["full_ticker","companyName","marketCap_usd"],"result_format":"rows"}'
```

### Python

```python
import os, requests

url = "https://www.dfin.pro/api/v1/screener/advanced/"
headers = {"Authorization": f"Bearer {os.environ['DFIN_API_KEY']}"}
payload = {'filters': {'incomeStatementGrowth': {'rules': [{'metric': 'revenue',
                                                  'horizon_years': 5,
                                                  'value_type': 'cagr',
                                                  'currency_basis': 'reported',
                                                  'min': 0.08,
                                                  'max': 0.4},
                                                 {'metric': 'netIncome',
                                                  'horizon_years': 5,
                                                  'value_type': 'cagr',
                                                  'currency_basis': 'reported',
                                                  'min': 0.05}]}},
 'sort': {},
 'page': {'limit': 100, 'offset': 0},
 'fields': ['full_ticker', 'companyName', 'marketCap_usd'],
 'result_format': 'rows'}

response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.json())
```



## 6.0 How to modify these examples {#modify}

The best approach is to copy one example, run it as-is, then change one rule field at a time and watch how the result set shifts. Small changes, fast feedback.

### Change the metric

Replace `metric` with any other value from `/api/v1/screener/options/`, such as `operatingIncome`, `netIncome`, or `epsDiluted`. Keep the rest of the rule the same at first, then adjust the horizon or threshold once you see what changes.

### Return only tickers

Set `result_format` to `tickers` when you just need the symbols. It keeps the response compact and works well when the output feeds into another step.

### Request more columns

When using `result_format: rows`, add to the `fields` array: sector, market cap, valuation ratios, recent returns. More context in the output means less looking things up afterward.

### Narrow the universe

Combine a growth filter with ordinary filters like `country`, `gics_sector`, or `marketCap_usd`. This is almost always the right move when you want a practical research list rather than a global screen.

### Check the current contract

Before building a new rule from scratch, call `/api/v1/screener/options/` and look at the growth filter metadata. It is the authoritative source for current metrics, allowed horizons, value types, and currency options, and it is much faster than guessing and debugging.
