There is no add-in to install. The screener endpoint returns a plain CSV over HTTPS, and both spreadsheets read that URL directly: Excel's built-in Power Query turns it into a real worksheet table you can refresh with one click, and Google Sheets spills it across the cells with `IMPORTDATA`. One request brings back up to 200 companies and any of the 115 available columns, so a watchlist or a whole sector lands in a single refresh. Ask for the 200: `limit` defaults to 50 and caps at 200, so a screen without it quietly returns the first fifty matches.

The screener endpoint is not gated by plan, so this works on Free as well as on a paid plan. All your plan decides is how many refreshes a day you get. See [Rate limits](/docs/rate-limits) for the current allowances.

## Before you start

1. **An API key.** Create one on [your API keys](/dashboard/apikeys) page. It starts with `eq_` and is shown once. [Authentication](/docs/authentication) covers the details.
2. **Excel with Power Query**, built in on Excel 2016 and later for Windows and on Microsoft 365 for Mac. It lives on the **Data** tab. Google Sheets needs nothing beyond the sheet itself.

## Build the URL

Every workbook query is one URL. Start from the endpoint, add the columns you want, and add the key:

```
https://api.equibles.com/v1/screener/stocks?format=csv&cols=de,currentratio,intcov,roic,volatility,beta&api_key=eq_your_api_key
```

Three parts matter:

- **`format=csv`** switches the endpoint from JSON to a flat file. Without it you get the JSON envelope, which Power Query can read but only after several extra steps.
- **`cols`** is the comma-separated list of columns. The keys are stable identifiers such as `de`, `currentratio`, `intcov`, `roic`, `volatility` and `beta`, not display labels, so a formula pointing at a column keeps working across site copy-edits. The [full list of 115 keys](/docs/api/endpoints/capital#v1screenerstocks) is grouped by picker section.
- **Filters** decide which companies come back. `tickers=aapl,msft,ko` scores a list you already hold, while `sector`, `index`, `minMarketCap`, `maxPe` and the other min/max pairs screen the market. `sortBy` orders the result and `limit` sizes it, defaulting to 50 and capping at 200.

A list you already hold:

```bash
curl "https://api.equibles.com/v1/screener/stocks?tickers=aapl,msft,ko&cols=de,currentratio,intcov,roic,volatility,beta&format=csv" \
  -H "Authorization: Bearer eq_your_api_key"
```

```
ticker,name,price,marketcap,de,currentratio,intcov,roic,volatility,beta
AAPL,Apple Inc.,319.97,4669700046848,0.77,1.00,,100.47,25.05,0.71
MSFT,Microsoft Corp,499.70,3710545297408,0.09,1.23,50.88,30.83,32.51,0.99
KO,Coca Cola Co,88.07,378919596707,,1.36,8.81,,18.83,-0.25
```

A screen of the market:

```bash
curl "https://api.equibles.com/v1/screener/stocks?minMarketCap=10000000000&sector=Technology&cols=de,currentratio,intcov,roic,volatility,beta&sortBy=marketcap&limit=5&format=csv" \
  -H "Authorization: Bearer eq_your_api_key"
```

```
ticker,name,price,marketcap,de,currentratio,intcov,roic,volatility,beta
NVDA,Nvidia Corp,230.36,5551675822362,0.15,4.59,426.74,,38.11,1.93
AAPL,Apple Inc.,319.97,4669700046848,0.77,1.00,,100.47,25.05,0.71
MSFT,Microsoft Corp,499.70,3710545297408,0.09,1.23,50.88,30.83,32.51,0.99
TSM,Taiwan Semiconductor Manufacturing Co Ltd,428.91,2224530653184,,2.46,211.04,,40.35,2.17
AVGO,Broadcom Inc.,357.90,1702714146816,0.74,2.24,10.41,23.69,48.19,2.13
```

`ticker`, `name`, `price` and `marketcap` are pinned and always lead the file, whatever `cols` asks for. Pass `cols=none` when those four are all you want.

## Load it into Excel

On the **Data** tab open **Get Data**, then **From Other Sources**, then **From Web**. Some builds put **From Web** on the Data tab directly. Paste the URL, with `&api_key=eq_...` on the end so the sheet can refresh unattended, and choose **Load**.

To skip the dialogs, open the advanced editor and paste the query:

```
let
    Source = Csv.Document(
        Web.Contents("https://api.equibles.com/v1/screener/stocks?format=csv&cols=de,currentratio,intcov,roic,volatility,beta&tickers=aapl,msft,ko&api_key=eq_your_api_key"),
        [Delimiter=",", Encoding=65001, QuoteStyle=QuoteStyle.Csv]),
    Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
    Typed = Table.TransformColumnTypes(Promoted, {
        {"price", type number}, {"marketcap", type number}, {"de", type number},
        {"currentratio", type number}, {"intcov", type number}, {"roic", type number},
        {"volatility", type number}, {"beta", type number}})
in
    Typed
```

`Encoding=65001` is not optional. The file is UTF-8 with no byte-order mark, and without it Power Query guesses the system code page and mangles non-ASCII company names.

The `Typed` step is what makes the numbers sort and compare as numbers. Name only the columns you actually asked for: a `TransformColumnTypes` step naming a column that is not in the file breaks the query.

## Refresh it

**Data**, then **Refresh All**, reloads every query in the workbook. To refresh on a schedule, right-click the query in the **Queries & Connections** pane, choose **Properties**, and set **Refresh every N minutes** or **Refresh data when opening the file**.

Each refresh spends exactly one request from your daily allowance, however many rows come back, so the interval is what has to fit the plan and not the row count. Two queries refreshing hourly across a trading day spend about 14 requests; the same two on a five-minute timer spend over 150. Set the interval against your plan's allowance on [Rate limits](/docs/rate-limits), and remember that fundamentals move on a filing, not on a tick.

## Google Sheets

Sheets reads the same URL through `IMPORTDATA`, which fetches it on Google's servers and spills the CSV across the cells below the formula. One cell is the whole setup:

```
=IMPORTDATA("https://api.equibles.com/v1/screener/stocks?tickers=aapl,msft,ko&cols=de,currentratio,intcov,roic,volatility,beta&format=csv&api_key=eq_your_api_key")
```

Three things differ from the Excel route:

- **Anyone who can open the sheet can read your key.** `IMPORTDATA` takes a URL and nothing else, so it cannot send an `Authorization` header, which leaves `api_key=` in the query string as the only way to authenticate, and the formula is visible in the cell. Mint a key for that one sheet so you can revoke it on its own from [your API keys](/dashboard/apikeys).
- **Sheets chooses when to re-fetch, about once an hour.** That cadence is Google's, not a setting: the Recalculation options under **File**, then **Settings**, then **Calculation** govern volatile functions such as `NOW` and `RAND`, and leave `IMPORTDATA` alone. Each fetch spends one request whether or not anyone has the sheet open, so one formula costs roughly 24 requests a day and three cost about 72. Weigh that against your plan's allowance on [Rate limits](/docs/rate-limits) before filling a sheet with them.
- **Types are inferred rather than declared.** Nothing names the numeric columns; Sheets reads them itself. An empty cell still means the company reports no value on that axis, not zero.

If the formula comes back saying it could not fetch the URL, check the key first: open the same URL in a browser tab and confirm it downloads a file rather than returning a `401`. If you would rather keep a key out of a shared sheet altogether, download a CSV and use **File**, then **Import**, then **Upload**, which needs no formula.

## Score and bucket the rows yourself

Because the headers are stable keys, ordinary formulas over the loaded table survive a refresh. Scoring balance-sheet strength in a helper column looks like this:

```
=IF(AND([@de]<1, [@currentratio]>1.5, [@intcov]>5), "Strong", IF([@de]>2, "Weak", "Watch"))
```

Two column shapes are not numbers. `goingconcern` writes `Yes` or leaves the cell empty and never writes `No`, so test it with `=IF([@goingconcern]="Yes", ...)` rather than against `"No"`. `exdate`, `nextearnings` and `lastearnings` are ISO `yyyy-MM-dd` dates, and `sector` and `industry` are plain text.

## What the file does and does not carry

- **An empty cell means the company reports no value on that axis**, not zero. Apple has no interest-coverage figure above, and Coca-Cola has neither debt-to-equity nor ROIC. Filling those with `0` would rank them as though they had answered.
- **Values carry the screener's presentation rounding.** Prices, ratios, multiples, percents and day counts arrive with two decimals, while counts, scores and aggregate money round to whole units. The JSON envelope's own fixed fields carry fuller precision, so where the two overlap they will not match digit for digit. `cols` is a CSV-only parameter, so most of these columns have no JSON counterpart to compare against.
- **Percent columns are percent numbers, not fractions.** A `volatility` of `25.05` means 25.05 %.
- **Filters and columns are two different vocabularies.** You can display `de`, `roic` or `intcov` but you cannot filter on them over REST: the min/max pairs cover market cap, price, filer counts and their quarterly change, short interest, days to cover, the squeeze and insider-sentiment scores, net insider buying, P/E, dividend yield, revenue growth, gross margin, dollar volume and net income, plus the boolean `hasGoingConcernDoubt`. Pull the columns and do the rest of the bucketing in the sheet. An unsupported parameter returns a 400 listing every name the endpoint accepts, so the endpoint tells you its own vocabulary.
- **One request returns at most 200 rows.** The response headers `X-Screener-Total-Count` and `X-Screener-Total-Pages` say whether there is more; add `&page=2` for the next slice, as a second query.

## Keep the key revocable

`api_key=` in the query string is what lets Excel refresh unattended, and it also means anyone you send the file to can read the key out of the query. Mint a separate key for the workbook so you can revoke that one on its own from [your API keys](/dashboard/apikeys) if the file ever leaves your hands.

## Without an API key

The portal's own export at [equibles.com/stocks/screener](https://equibles.com/stocks/screener) downloads the same screen as a CSV with no key and no account, which is the quicker route for a one-off look. [Using the stock screener](/docs/screener) covers it. Its headers are human labels rather than stable keys, though, so a workbook pointed at it can break when copy changes. For anything you intend to refresh, use the endpoint above.

## Where to go next

- [`/v1/screener/stocks`](/docs/api/endpoints/capital#v1screenerstocks) for every parameter, every column key and the response headers.
- [Using the stock screener](/docs/screener) to build the screen in the browser first, then copy its columns across.
- [Rate limits](/docs/rate-limits) for the daily allowance a refresh spends.