Overview
Data comes from the SEC's Form 13F data sets (public), one zip per three-month filing window. A daily collector checks the SEC listing and, when a data set is new or revised, rebuilds the affected quarter: it reads every 13F-HR in the window for that quarter end plus late filings from the next window, keeps the latest original or restatement per manager and adds NEW HOLDINGS amendments to it. Rows for the same security, put/call and manager are merged. The latest eight quarter ends are kept; requests are served from that store, never from SEC live.
Change fields compare each position with the same manager's report for the previous stored quarter, matched on CUSIP and put/call. A position missing from the previous report is `new`; one in the previous report but not this one is `soldout` (shares 0, shown only with `changeType=soldout`). When the manager filed no report for the previous quarter, or the quarter is the oldest stored, every change field is null. `value` is in US dollars as filed (13F values have been reported in dollars since 2023), and `portfolioPercent` is value over the manager's total reported value, options included.
Tickers: 13F identifies securities by CUSIP, and CUSIP tables are licensed, so none is used. A CUSIP gets a ticker from SEC fails-to-deliver files (which list CUSIP and symbol), or, for common stock with a valid CUSIP check digit, from an exact issuer-name match against SEC company_tickers.json that resolves to a single company. Otherwise `ticker` is null; a ticker can map to several CUSIPs (`otherCusips`). `turnoverPercent` estimates buys and sells from share changes priced at this quarter's value per share and divides the lesser by the average of this and last quarter's total value.
Live Test Institutional Holdings Source →
Formula
One function covers the whole catalog: the first argument names the source, the next are its inputs, and the field after them says which single value lands in the cell. Formulas covers the grammar that applies to all of them.
=VERVE("institutionalholdings", "mode")=VERVE.CALL("institutionalholdings", "mode")Inputs
Required inputs are positional, in the order below, followed by the field. Everything else is passed as a "name", value pair after that — the same shape as SUMIFS. Premium inputs are accepted on every plan but only take effect on plans that include them.
| Input | Type | Where it goes | Description |
|---|---|---|---|
cikOptional | string | "cik", value | SEC Central Index Key of the 13F filer, e.g. 1067983 for Berkshire Hathaway. Returns that manager's holdings. length 0–10 |
managerOptional | string | "manager", value | Manager name to search for instead of cik, e.g. bridgewater. The best match is returned, with other close matches in otherMatches. length 0–100 |
tickerOptional | string | "ticker", value | Ticker symbol. Alone, lists the managers holding it; with cik or manager, filters that manager's holdings to it. length 0–10 |
cusipOptional | string | "cusip", value | 9-character CUSIP. Alone, lists the managers holding it; with cik or manager, filters that manager's holdings to it. length 8–9 |
periodOptionalPremium | string | "period", value | Quarter to read, as a quarter end (2026-03-31) or quarter (2026Q1). Defaults to the latest quarter. |
changeTypeOptional | string | "changeType", value | Only positions that are new, increased, decreased, unchanged or soldout since the previous quarter. Sold-out positions appear only with soldout.newincreaseddecreasedunchangedsoldout |
putCallOptional | string | "putCall", value | Option filter: put, call, none (shares and principal only) or all. Defaults to all.putcallnoneall |
minValueOptional | number | "minValue", value | Only positions worth at least this many US dollars. range 0–∞ |
maxValueOptional | number | "maxValue", value | Only positions worth at most this many US dollars. range 0–∞ |
sortOptional | string | "sort", value | Sort by value (default), shares, change (share change), changepercent or portfolio (weight).valueshareschangechangepercentportfolio |
orderOptional | string | "order", value | Sort order: desc (default) or asc.descasc |
limitOptionalPremium | integer | "limit", value | Rows to return (1-100). Defaults to 10. range 1–100 |
offsetOptionalPremium | integer | "offset", value | Rows to skip, for paging through a large portfolio or holder list. range 0–∞ |
summaryOptionalPremium | boolean | "summary", value | Add a summary: for a manager, value change, position counts by change type, top-10 concentration and turnover; for a security, holder flows and top-10 share concentration. |
Passing an option
=VERVE("institutionalholdings", "mode", "cik", 1067983)=VERVE.CALL("institutionalholdings", "mode", "cik", 1067983)What lands in your sheet
The field — the argument after the inputs — is what makes the formula resolve to one cell. Its value is a dot-path from the table below, so swapping it is how you pull a different value — one formula per column.
Seeing everything at once
Leave the field out and the formula returns the whole response instead: two columns, field name on the left and value on the right, spilling from the cell you typed in.
=VERVE("institutionalholdings")=VERVE.CALL("institutionalholdings")The second row's table would land on top of the first's, and every cell after the first reads #REF! (#SPILL! in Excel). Keep one per sheet, or name a field, and leave the cells below and to the right empty.
Response fields
Paths are relative to data. Each one is exactly what the field argument accepts, so swapping it is how you pull a different value into a cell. On a plan without a Premium field the cell reads #PREMIUM(field) rather than a value, so a locked field never looks like a real answer.
| Use as the field | Type | Example cell value | Description |
|---|---|---|---|
mode | string | manager | manager (a manager's holdings) or holders (the managers holding a security) |
period | string | 2026-06-30 | Quarter-end date of the report (YYYY-MM-DD) |
quarter | string | 2026Q2 | Quarter of the report, e.g. 2026Q2 |
previousPeriod | string | 2026-03-31 | Quarter the change fields compare against; null when there is no earlier report |
manager | object | {…} | Manager mode: the 13F filer |
manager.cik | string | 0001067983 | SEC Central Index Key, 10 digits |
manager.name | string | Berkshire Hathaway Inc | Filing manager name |
manager.city | string | Omaha | City of the filing manager |
manager.state | string | NE | State or country code of the filing manager |
filing | object | {…} | Manager mode: the report the holdings come from |
filing.formType | string | 13F-HR | 13F-HR, or 13F-HR/A when a restatement replaced the original |
filing.accessionNumber | string | 0001193125-26-352200 | SEC accession number |
filing.filingDate | string | 2026-08-14 | Date the report was filed (YYYY-MM-DD) |
filing.amendments | number | 0 | Amendments filed for this quarter |
filing.url | string | https://www.sec.gov/Archives/edgar/data/1067983/000119312526352200/ | EDGAR folder of the filing |
totalValue | number | 299253556246 | Manager mode: total reported value in US dollars; holders mode: total value of share positions in the security |
positionCount | number | 29 | Manager mode: number of positions reported |
count | number | 5 | Rows returned |
offset | number | 0 | Rows skipped |
totalMatches | number | 29 | Rows matching the filters before paging |
holdings | array[5] | Manager mode: positions, largest first by default | |
holdings.0.issuer | string | APPLE INC | Issuer name as filed |
holdings.0.ticker | string | AAPL | Ticker matched through SEC data, or null |
holdings.0.cusip | string | 037833100 | CUSIP |
holdings.0.figi | string | BBG001S5N8V8 | FIGI when the filer supplied one, else null |
holdings.0.titleOfClass | string | COM | Class of security as filed |
holdings.0.shares | number | 227917808 | Shares, or principal amount when shareType is PRN; 0 for a sold-out position |
holdings.0.shareType | string | SH | SH (shares) or PRN (principal amount) |
holdings.0.value | number | 65950296923 | Reported value in US dollars |
holdings.0.portfolioPercent | number | 22.0383 | Value as a percent of the manager's total reported value |
holdings.0.putCall | object | null | Put or Call for option positions, null for shares |
holdings.0.investmentDiscretion | string | DFND | SOLE, DFND (shared-defined) or OTR (shared-other); MIXED when rows differed |
holdings.0.votingAuthority | object | {…} | Shares by voting authority |
holdings.0.votingAuthority.sole | number | 227917808 | Shares with sole voting authority |
holdings.0.votingAuthority.shared | number | 0 | Shares with shared voting authority |
holdings.0.votingAuthority.none | number | 0 | Shares with no voting authority |
holdings.0.previousShares | number | 227917808 | Shares in the previous quarter (0 for a new position); null without an earlier report |
holdings.0.previousValue | number | 57843260493 | Value in the previous quarter in US dollars; null without an earlier report |
holdings.0.shareChange | number | 0 | Change in shares since the previous quarter |
holdings.0.shareChangePercent | number | 0 | Change in shares in percent; null for a new position |
holdings.0.valueChange | number | 8107036430 | Change in value in US dollars |
holdings.0.changeType | string | unchanged | new, increased, decreased, unchanged or soldout |
holdings.0.isNew | boolean | false | True when the position was not held in the previous quarter |
When a cell doesn't fill
A failed lookup returns readable text starting with #ERR rather than a spreadsheet error, because Excel cannot show a custom message on a real error — you would get a bare #VALUE! with no reason. The trade-off is that IFERROR() will not catch it; test with LEFT(cell, 4) = "#ERR" instead. Error handling covers the rest.
| Cell reads | What happened |
|---|---|
#ERR Not connected | No API key saved. Open the side panel and connect your account. |
#ERR Replace <name> with a cell or value | A preview formula was copied as-is. Swap the placeholder for a cell reference. |
#ERR No "x" in institutionalholdings | An option name this source does not take. The message lists the ones it does. |
#ERR No data point "…" | The field path is not in the response. Check it against the table above. |
#PREMIUM(field) | The field exists but your plan does not include it. |
#ERR Out of credits | The cycle's credits are spent. Usage resets on your billing date. |
Before the formula works
The add-in reads the API key you saved once in the side panel — the key never goes in the formula, so a shared sheet does not leak it and a collaborator without access simply sees the last calculated values.
- Install the add-in for Google Sheets or Excel.
- Open the side panel and sign in, or paste a key from your dashboard.
- Type the formula above into any cell.
Use cases
- Fund Tracking Apps
- Investor apps follow well-known managers each quarter, showing new buys, adds, trims and exits straight from the change fields.
- Institutional Ownership Pages
- Stock research sites list the largest institutional holders of a ticker with their share changes and how many funds entered or exited.
- Investor Relations Monitoring
- IR teams watch which institutions built or cut positions in their own stock and peers' stocks after each 13F deadline.
- Quant Signals
- Researchers measure crowding and conviction from holder counts, top-10 concentration and quarter-over-quarter flows across thousands of managers.
Other ways to use Institutional Holdings
Set up Institutional Holdings on VerveSheets, or reach the same source a different way. Your VerveSheets account and credits work on all of them — one key, one balance.
Related
More in Finance: