Institutional holdings
Paid plansSee which institutional managers held a security at each quarter end, from SEC Form 13F, with shares, value and voting authority.
GET /v1/holdings/{ticker} returns the positions institutional managers report on SEC Form 13F: one row per manager, security and quarter end, largest position first within each quarter. Pass one or more tickers in the path, comma-separated, or pass entity_id instead: GET /v1/holdings?entity_id=10003635.
Rows are keyed to the security. entity_id on every row is one share class and meta.entity_id_is reads security, so BRK-A and BRK-B return different holders. issuer_entity_id names the company above the security. Tickers and entities explains how entity_id scope differs by endpoint.
Units:
sharesis the number of shares the manager reported, summed across its lines for the security and quarter. It is not adjusted for later splits. A line reported as a principal amount carries that amount in USD.value_usdis in US dollars, not thousands.sole_voting,shared_votingandno_votingare share counts.
Values are in US dollars in both eras
Form 13F filings made before 2023-01-03 reported values in thousands of dollars. Those values are multiplied by 1,000, so value_usd is in US dollars, not thousands, on every row.
Institutional holdings are available on Pro and higher plans. A Free key receives 402.
Two eras
Quarters come from two eras. source on every row names the era, and meta.archive_edge gives the boundary, currently 2025-12-31:
historical: Form 13F positions for quarter ends from 1978-12-31 tometa.archive_edge.value_usdisshares× the quarter-end share price, so it can carry cents.filing: Form 13F filings read directly, for quarters aftermeta.archive_edge.value_usdis the value the filer reported.
By default each quarter is answered by one era: on or before the edge by historical, after it by filing. Pass source=filing or source=historical to read one era for every quarter in your window. The filing era holds filings made from 2013 onward, and a late or amended filing can state an earlier quarter.
The two eras state a quarter in their own terms. For Apple at 2025-12-31, Vanguard Group reads 1363416528 shares in the historical era and 1426283914 shares with source=filing. Do not add rows from the two eras together.
The eras fill some fields differently:
manager_idis the filer's SEC CIK onfilingrows and 900,000,000 plus the historical dataset's manager number onhistoricalrows.manager_id_spacereadscikorarchive. A firm that appears in both eras has one id in each: Berkshire Hathaway is1067983in the filing era and900008350in the historical era.manager_typeis a digit from1to5onhistoricalrows and null onfilingrows.filing_date,title_of_class,filer_cik,accession_numberandunit_scale_suspectappear onfilingrows.manager_numberandvintage_dateappear onhistoricalrows, wherefiling_dateis null.put_callis null andis_amendmentis false on everyhistoricalrow.
A historical-era row:
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/AAPL?quarter=2025-12-31&limit=2"{
"tickers": ["AAPL"],
"data": [
{
"entity_id": 10003635,
"ticker": "AAPL",
"entity_name": "APPLE INC",
"report_date": "2025-12-31",
"manager_id": 900090457,
"manager_name": "VANGUARD GROUP, INC.",
"manager_type": "5",
"shares": 1363416528,
"filing_date": null,
"value_usd": 370658417302.08,
"sole_voting": 93437,
"shared_voting": 84271157,
"no_voting": 1279051934,
...
"put_call": null,
"source": "historical",
"is_amendment": false,
"manager_id_space": "archive",
"issuer_entity_id": 1,
"link_method": "windowed",
"issuer_name_as_filed": "APPLE INC",
"lines": 1,
"manager_number": 90457,
"vintage_date": "2025-12-31",
"is_current": true
},
...
],
"data_through": "2025-12-31",
"count": 2,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaUxWTlZPSEY2TVVJeVdYSnNSV1ZTTUhOV1VHdGxRU0lzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbE13ZUUxcE1IcE5XSGQ0VFZSSmQwMTZSWGhOYW1ONVprUnJkMDFFUVhkUFZFMDBUbGg0ZWsxVVFYZE5SRTB5VFhwV09HWkViM2hQYlVsM1dXMUZlVTVVVG1sTmJVa3lXWHBWTWsxRVdUTk5SMDVwVGxSck1VNUVXVE5aYWs1b1dYcG5lU0o5fFlQUVhYVTVJVGwtNmw0enhvWXVXa3c=",
"meta": {
"entity_id_is": "security",
"entity_id_grain": "security",
"archive_edge": "2025-12-31",
"amendment_view": "current",
"era_fallback": false,
"knowledge_time": "2026-07-25T19:46:39Z",
"as_of": "2025-12-31",
"freshness": [
{"dataset": "institutional_holdings_historical", "through": "2025-12-31", "promoted_at": "2026-09-24T19:51:07Z"}
],
"has_more": true,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaUxWTlZPSEY2TVVJeVdYSnNSV1ZTTUhOV1VHdGxRU0lzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbE13ZUUxcE1IcE5XSGQ0VFZSSmQwMTZSWGhOYW1ONVprUnJkMDFFUVhkUFZFMDBUbGg0ZWsxVVFYZE5SRTB5VFhwV09HWkViM2hQYlVsM1dXMUZlVTVVVG1sTmJVa3lXWHBWTWsxRVdUTk5SMDVwVGxSck1VNUVXVE5aYWs1b1dYcG5lU0o5fFlQUVhYVTVJVGwtNmw0enhvWXVXa3c="
}
}value_usd here is 1363416528 shares × 271.86 USD, Apple's close on 2025-12-31 from Prices.
Amendment versions
include_amendments selects which versions of an amended Form 13F you receive. It applies to the filing era; historical rows have no amendments.
- Omitted: the position in force, and
meta.amendment_viewreadscurrent. An amendment marked as a restatement replaces the report it amends. An amendment marked as adding new holdings entries adds them to the report, so a position stated in both is their sum. Such an amendment replaces the positions it states instead when it repeats an entry already in force with the same quantity, has more than a quarter as many lines as the holdings in force, states more than a quarter of the positions in force, or states more than a tenth of the positions it shares with them within 5% of the quantity already held. Any other amendment replaces the positions it states. true, in any letter case: every filed version as its own row. Superseded rows carryis_current: false.meta.amendment_viewreadsall.false, in any letter case: figures from original filings only.meta.amendment_viewreadsoriginals.- Any other non-empty value returns
400.
Vanguard Capital Management filed its 2026-Q1 report on 2026-05-08 and a restatement on 2026-05-15. Both state 953847648 Apple shares; the restatement changes the value.
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/AAPL?quarter=2026-03-31&manager=vanguard%20capital&include_amendments=true"{
"tickers": ["AAPL"],
"data": [
{"manager_id": 2100119, "manager_name": "VANGUARD CAPITAL MANAGEMENT LLC", "shares": 953847648, "filing_date": "2026-05-15", "value_usd": 242076924860, "is_amendment": true, "accession_number": "0002100119-26-001311", "is_current": true, ...},
{"manager_id": 2100119, "manager_name": "VANGUARD CAPITAL MANAGEMENT LLC", "shares": 953847648, "filing_date": "2026-05-08", "value_usd": 241720924860, "is_amendment": false, "accession_number": "0002100119-26-001306", "is_current": false, ...},
{"manager_id": 1730578, "manager_name": "Vanguard Capital Wealth Advisors", "shares": 55855, "filing_date": "2026-04-21", "value_usd": 14175411, "is_amendment": false, "accession_number": "0001730578-26-000002", "is_current": true, ...}
],
"count": 3,
...
"meta": {"amendment_view": "all", ...}
}The same request in each view:
- Omitted: 2 rows. Vanguard Capital Management reads the restated
242076924860USD. include_amendments=true: 3 rows, both Vanguard Capital Management versions.include_amendments=false: 2 rows. Vanguard Capital Management reads the original241720924860USD.
Invesco filed its 2026-Q1 report on 2026-05-12 and an amendment adding new holdings entries on 2026-07-15. The report states 142760706 NVIDIA shares and the amendment 184736390 more.
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/NVDA?quarter=2026-03-31&manager_id=914208&include_amendments=true"{
"tickers": ["NVDA"],
"data": [
{"manager_id": 914208, "manager_name": "Invesco Ltd.", "shares": 184736390, "filing_date": "2026-07-15", "value_usd": 32218026416, "is_amendment": true, "lines": 1, "accession_number": "0000914208-26-000216", "is_current": true, ...},
{"manager_id": 914208, "manager_name": "Invesco Ltd.", "shares": 142760706, "filing_date": "2026-05-12", "value_usd": 24897467149, "is_amendment": false, "lines": 29, "accession_number": "0000914208-26-000193", "is_current": true, ...}
],
"count": 2,
...
"meta": {"amendment_view": "all", ...}
}The same request in each view:
- Omitted: 1 row, the sum of the two filings:
327497096shares and57115493565USD overlines30, with the laterfiling_dateandis_amendment: true. include_amendments=true: 2 rows, both withis_current: true.include_amendments=false: 1 row, the report's142760706shares.
A position stated only in an amendment has no original, so include_amendments=false leaves it out. Manager holdings shows an example.
Parameters
tickerstr (path)Required unless entity_id is setOne or more tickers, comma-separated: /v1/holdings/AAPL,MSFT. Each resolves to one share class. Up to 100 per request on Pro, 500 on Max, 5,000 on Redistribution.
entity_idint | strDefault: noneOne id, or several comma-separated, in place of ticker. A share-class id returns that security. An issuer id returns every security of the issuer. Cannot be combined with a ticker in the path. Counts toward the same per-request cap.
startstrDefault: noneEarliest report_date, YYYY-MM-DD, inclusive. The Python client's holdings() sends a start 365 days before end, or before today, when you omit both start and quarter.
endstrDefault: noneLatest report_date, YYYY-MM-DD, inclusive.
quarterstrDefault: noneOne exact report_date, YYYY-MM-DD. Pass a calendar quarter end, such as 2026-03-31; any other date returns 400.
min_valuenumberDefault: noneMinimum value_usd for the position, in USD, 0 or more.
managerstrDefault: noneCase-insensitive substring of manager_name, for example vanguard capital. % and _ match those characters.
manager_idintDefault: noneOne exact manager_id, a positive integer. Find ids with Manager search.
sourcestrDefault: by quarterhistorical or filing, in any letter case. Omitted: quarters on or before meta.archive_edge come from the historical era, later quarters from the filing era. Set: every quarter in the window comes from that era.
include_amendmentsstrDefault: omittedOmitted: the position in force. true: every filed version. false: original filings only. Both are read in any letter case; any other non-empty value returns 400. The Python client's holdings() sends true unless you pass include_amendments=None.
fieldsstrDefault: every selectable field except value_scale_correctedComma-separated. Selectable: filing_date, value_usd, sole_voting, shared_voting, no_voting, security_class, put_call, source, is_amendment, and the opt-in value_scale_corrected. entity_id, ticker, entity_name, report_date, shares, manager_id, manager_name, manager_type and the era fields are always returned; naming them is accepted and adds nothing. An unknown name is ignored with a warning; a list with no known name returns 400.
limitintDefault: 1000Rows per page, up to 5,000. A larger whole number, up to nine digits, returns 5,000 rows; 0, a negative or a non-numeric value returns 400.
security_classstrDefault: noneNot a filter. The request is served without it, with the warning security_class is not a filter on this data; each row carries title_of_class as filed.
cursorstrDefault: noneThe next_cursor value from the previous page, passed back unchanged.
Response
The response is not the {data, meta} shape of the prices and fundamentals endpoints. data, data_through, count, next_cursor and warnings sit at the top level, with meta beside them:
{
"tickers": ["AAPL"],
"data": [ ... ],
"data_through": "2026-03-31",
"count": 3,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaWR6SnRNVFZYYlZKcVZFaEJlWGszWTFsaGJGZFVaeUlzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbWt3ZDAxNU1IcE5XSGN5VFVSSmVrNUVSVEJOUkd3NFQxUk5NMDVVUmpoamVrVjNUVVJCZWs1cVRURm1TSGMyVFZFOVBTSjl8bjl6U09iTTdhbHlOMkpVODVJLU9nZw==",
"meta": { ... }
}Top-level fields
| field | type | unit | nullable | description |
|---|---|---|---|---|
tickers | list[str] | no | The tickers in the path, upper-cased. An empty list on an entity_id request. | |
entity_ids | list[int] | no | The ids you passed. Present on entity_id requests only. | |
entity_ids_unresolved | list[int] | no | Ids that matched nothing. Present on entity_id requests only. | |
tickers_unresolved | list[str] | no | Tickers that matched nothing, when others resolved. Present only when non-empty. | |
historical_resolution | object | no | Present when a ticker resolved to a security other than its current holder's. Keyed by ticker: entity_id, current_entity_id (or null), as_of and via. | |
historical_resolution_note | str | no | A fixed explanation, present with historical_resolution. | |
data | list[object] | no | The rows. See the row fields below. | |
data_through | str | date | yes | The latest report_date on this page. Null when data is empty. |
count | int | rows | no | Rows on this page. |
next_cursor | str | yes | Pass as cursor for the next page. Null on the last page. meta.next_cursor holds the same value. | |
warnings | list[str] | no | Present only when there is something to report, such as Ignored unknown fields: foo or BRK named more than one share class on that date; served at the company level. | |
meta | object | no | See the meta fields below. |
Row fields
| field | type | unit | nullable | description |
|---|---|---|---|---|
entity_id | int | yes | The security (share class). Null on a filed line not linked to a security. | |
ticker | str | yes | On a ticker request, the ticker you requested. When a ticker is served at company level or an issuer entity_id is requested, each class's ticker on report_date; on a share-class entity_id request, that class's ticker. Null on unlinked lines. | |
entity_name | str | yes | The company's name. Null on unlinked lines. | |
report_date | str | date | no | The quarter end the position is reported for. |
manager_id | int | no | Filing era: the filer's SEC CIK. Historical era: 900,000,000 plus the historical dataset's manager number. | |
manager_name | str | yes | The manager's name as filed. | |
manager_type | str | yes | Historical era: the historical dataset's manager type code, a digit from 1 to 5. Null on filing-era rows. | |
shares | number | shares | no | Shares reported, summed across the manager's lines for the position. Not adjusted for splits. On a line reported as a principal amount, the principal in USD. |
filing_date | str | date | yes | Filing era: the latest filing date among the position's lines. Null on historical rows. Default field. |
value_usd | number | USD | yes | US dollars, not thousands. Filing era: the reported value. Historical era: shares × the quarter-end price. Default field. |
sole_voting | number | shares | yes | Shares over which the manager has sole voting authority. Default field. |
shared_voting | number | shares | yes | Shares with shared voting authority. Default field. |
no_voting | number | shares | yes | Shares with no voting authority. Default field. |
security_class | str | yes | null on every row. Default field. | |
put_call | str | yes | put or call for an option position. Null otherwise, and on every historical row. Default field. | |
source | str | no | historical or filing. Default field. | |
is_amendment | bool | no | True when the figures come from an amended filing. Always false on historical rows. Default field. | |
value_scale_corrected | bool | no | True when a filing made before 2023-01-03 already stated whole dollars, so its values are served as filed rather than multiplied by 1,000. Always false on historical rows. Opt-in through fields. | |
manager_id_space | str | no | cik on filing-era rows, archive on historical rows. | |
issuer_entity_id | int | yes | The company above the security. | |
link_method | str | yes | How the security identifier on the line was matched to a security. windowed: the identifier's recorded date range covers report_date. censored: no recorded range covers it, and exactly one security has ever carried the identifier, with a record that runs to the end of the recorded history. unique: exactly one security has ever carried the identifier, with a record that starts after report_date. Null on an unlinked line. | |
issuer_name_as_filed | str | yes | The issuer's name as stated for the line, for example FACEBOOK INC on a 2020 Meta row. | |
title_of_class | str | yes | Filing rows only: the filer's description of the class, for example COM or CL B NEW. | |
lines | int | lines | no | Number of filed lines summed into the row. |
filer_cik | int | no | Filing rows only: the filer's SEC CIK. | |
accession_number | str | no | Filing rows only: the SEC accession number of the filing the figures come from. | |
unit_scale_suspect | bool | no | Filing rows only: true when the filing states the scale of its values inconsistently. Values on such rows are served as filed. | |
manager_number | int | no | Historical rows only: the historical dataset's manager number, manager_id minus 900,000,000. | |
vintage_date | str | date | no | Historical rows only: the date of the historical dataset edition the row comes from. |
is_current | bool | no | True when the row is the version in force. |
Meta fields
| field | type | unit | nullable | description |
|---|---|---|---|---|
entity_id_is | str | no | Always security. | |
entity_id_grain | str | no | security when every request item named a share class, issuer when every item was served at company level, mixed otherwise. | |
archive_edge | str | date | no | The last quarter end the historical era answers by default. |
amendment_view | str | no | current, all or originals, from include_amendments. | |
era_fallback | bool | no | True when the filing era answered a security and quarter on or before archive_edge that the historical era does not hold. | |
knowledge_time | str | UTC timestamp | yes | When the newest data in the response became known. See Response metadata. |
as_of | str | date | no | end if you passed it, else quarter, else start. Absent when you passed none. |
freshness | list[object] | no | One entry per era your window falls in: institutional_holdings_historical for quarters on or before archive_edge, institutional_holdings for later quarters or with source=filing. Each has dataset, through and promoted_at. | |
has_more | bool | no | true when another page follows. | |
next_cursor | str | yes | Pass as cursor for the next page. The same value as the top-level next_cursor. Null on the last page. |
Pagination
A page holds up to limit rows: 1,000 by default, 5,000 at most. Rows are ordered by report_date descending, then shares descending, then manager_id descending, then by the position's own keys, so a page can end between any two rows without skipping or repeating one. A window that spans meta.archive_edge returns filing-era quarters first and continues into historical quarters on later pages.
When more rows match, meta.has_more is true and next_cursor, at the top level of the body and in meta, carries a token. Pass it back as cursor with the same path and parameters. On the last page meta.has_more is false and next_cursor is null. Pagination covers cursors in general.
One query can run to 50 pages on Pro, 100 on Max and 200 on Redistribution. A cursor for a page beyond the cap returns 400:
{"error":"Pagination limit reached","code":"pagination_limit_reached","status":400,"detail":"Pro tier supports up to 50 pages per query.","message":"Pro tier supports up to 50 pages per query."}With source=filing and a window on or before meta.archive_edge, read the window in one page. Raise limit, or narrow with quarter, manager, manager_id or min_value.
The Python client's holdings() returns one page per call, up to 5,000 rows. Page with cursor over REST to read further.
Errors
| status | error code | when it happens | how to fix |
|---|---|---|---|
400 | bad_request | start, end or quarter is not a real YYYY-MM-DD date, quarter is not a calendar quarter end, or end is before start. | Pass a valid calendar date; for quarter, a quarter end. |
400 | bad_request | include_amendments is a non-empty value other than true or false, or limit is not a whole number from 1 to 999,999,999. | Pass true or false, and a limit of 1 or more. |
400 | bad_request | min_shares or min_value is negative or not a number. | Pass a number of 0 or more. |
400 | bad_request | manager_id is not a positive integer. | Pass an id from Manager search. |
400 | bad_request | source is not historical or filing. | Pass one of the two. |
400 | bad_request | No fields name is valid. | Use the selectable field names. |
400 | bad_request | Both a path ticker and entity_id, or an entity_id that is not a positive integer. | Pass one or the other. |
400 | bad_request | More tickers than your plan allows. | Split the request. |
400 | bad_request | cursor was not issued for this request: it is not a next_cursor value, it has been altered, or it came from another path, a changed parameter or another endpoint. | Pass next_cursor unchanged with the same path and parameters, or repeat the request without cursor. |
400 | pagination_limit_reached | The cursor asks for a page beyond your plan's cap. error reads Pagination limit reached. | Narrow the query. |
401 | unauthorized | The key is missing or invalid. | Send X-API-Key. See Authentication. |
402 | upgrade_required | The key is on the Free plan. | Upgrade to Pro. |
404 | not_found | No ticker or id matched. | Check the symbol with Search, or pass entity_id. |
404 | not_found | The ticker names a company with no listed security on the dates tried. | Pass an entity_id. |
409 | ambiguous_ticker | The ticker named more than one company on the resolved date, and nothing else resolved, for example SFN on 2009-06-30. hint reads pass entity_id=. | Pass one of the candidates as entity_id. |
429 | see Rate limits | A quota is exhausted. | Wait for the window to reset. |
503 | coverage_unavailable | The holdings coverage boundary is unavailable. | Retry the request. |
Real bodies:
{"error":"bad_request","code":"bad_request","status":400,"detail":"Invalid quarter date format (YYYY-MM-DD)"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"Invalid start date format (YYYY-MM-DD)"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"min_shares must be a non-negative number"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"min_value must be a non-negative number"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"manager_id must be a positive integer"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"source must be 'historical' or 'filing'"}
{"error":"bad_request","code":"bad_request","status":400,"detail":"No valid fields requested. Unknown: foo, _bar. Selectable via fields=: filing_date, value_usd, ... Always included: entity_id, ticker, entity_name, report_date, shares, manager_id, manager_name, manager_type."}
{"error":"bad_request","code":"bad_request","status":400,"detail":"Provide either a ticker in the path or an entity_id parameter, not both."}
{"error":"bad_request","code":"bad_request","status":400,"detail":"Maximum 100 tickers per request"}
{"error":"Pagination limit reached","code":"pagination_limit_reached","status":400,"detail":"Pro tier supports up to 50 pages per query.","message":"Pro tier supports up to 50 pages per query."}{"error":"upgrade_required","code":"upgrade_required","status":402,"detail":"Institutional holdings are available on Pro. https://xfinlink.com/pricing"}{"error":"not_found","code":"not_found","status":404,"detail":"No matching entities for: ZZZZQ"}SFN named two different companies on 2009-06-30. /v1/holdings/SFN?quarter=2009-06-30 returns 409, and candidates lists the share-class ids that carried the ticker on that date:
{"error":"ambiguous_ticker","code":"ambiguous_ticker","status":409,"detail":"SFN names more than one company. Request by entity_id to choose one.","candidates":{"SFN":[10022947,10034604]},"hint":"pass entity_id="}The 404 for a company with no listed security reads {"error":"not_found","code":"not_found","status":404,"detail":"No listed security for: <ticker>"}. The 503 body reads {"error":"coverage_unavailable","code":"coverage_unavailable","status":503,"detail":"Holdings coverage is not available"}.
When one ticker in a list fails and another resolves, you get 200 and the failed ticker is listed in tickers_unresolved or reported in warnings.
Plan differences
- Free:
402. A date,quarter,limit,include_amendments,manager_idorcursorvalue that is refused returns its400first. - Pro: full history, up to 100 tickers per request, 50 pages per query.
- Max: full history, up to 500 tickers per request, 100 pages per query.
- Redistribution: full history, up to 5,000 tickers per request, 200 pages per query.
Each ticker or entity_id counts as one unit against your daily quota. A Free key's 402 does not count. See Plans and limits.
A request with 101 tickers returns 400 on Pro and 200 on Redistribution:
{"error":"bad_request","code":"bad_request","status":400,"detail":"Maximum 100 tickers per request"}A cursor for page 51 returns the Pro page-cap 400 shown under Pagination, and 200 on Redistribution. On Redistribution the cap applies from page 201:
{"error":"Pagination limit reached","code":"pagination_limit_reached","status":400,"detail":"Redistribution tier supports up to 200 pages per query.","message":"Redistribution tier supports up to 200 pages per query."}A Free key receives the 402 body, unless a refused parameter value returns its 400 first.
Edge cases
Share classes
A ticker names one share class, so BRK-A and BRK-B return different holders under one issuer_entity_id, 942. Values are per class: a BRK-A share is worth about 1,500 BRK-B shares.
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/BRK-A?quarter=2026-03-31&min_value=1000000000&fields=value_usd&limit=2"{
"tickers": ["BRK-A"],
"data": [
{"entity_id": 10006133, "ticker": "BRK-A", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "report_date": "2026-03-31", "manager_id": 315066, "manager_name": "FMR LLC", "manager_type": null, "shares": 17000, "value_usd": 12208380000, "issuer_entity_id": 942, "title_of_class": "CL A", "lines": 4, ...},
{"entity_id": 10006133, "ticker": "BRK-A", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "report_date": "2026-03-31", "manager_id": 728083, "manager_name": "FIRST MANHATTAN CO. LLC.", "manager_type": null, "shares": 13969, "value_usd": 10031697660, "issuer_entity_id": 942, "title_of_class": "CL A", "lines": 1, ...}
],
...
}curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/BRK-B?quarter=2026-03-31&min_value=1000000000&fields=value_usd&limit=2"{
"tickers": ["BRK-B"],
"data": [
{"entity_id": 10025221, "ticker": "BRK-B", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "report_date": "2026-03-31", "manager_id": 2012383, "manager_name": "BlackRock, Inc.", "manager_type": null, "shares": 121207647, "value_usd": 58082703896, "issuer_entity_id": 942, "title_of_class": "CL B NEW", "lines": 23, ...},
{"entity_id": 10025221, "ticker": "BRK-B", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "report_date": "2026-03-31", "manager_id": 2100119, "manager_name": "VANGUARD CAPITAL MANAGEMENT LLC", "manager_type": null, "shares": 117415535, "value_usd": 56265524372, "issuer_entity_id": 942, "title_of_class": "CL B NEW", "lines": 1, ...}
],
...
}Pass the issuer id to get every class in one request: ?entity_id=942 returns both classes, each row with its class's own ticker, and meta.entity_id_grain reads issuer. A symbol that names several classes of one company on the date, such as BRK, is served the same way, with a warning and each row's class ticker:
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/BRK?quarter=2026-03-31&min_value=10000000000&fields=value_usd"{
"tickers": ["BRK"],
...
"data": [
{"entity_id": 10025221, "ticker": "BRK-B", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "manager_name": "BlackRock, Inc.", "shares": 121207647, "value_usd": 58082703896, ...},
...
{"entity_id": 10006133, "ticker": "BRK-A", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "manager_name": "FMR LLC", "shares": 17000, "value_usd": 12208380000, ...},
{"entity_id": 10006133, "ticker": "BRK-A", "entity_name": "BERKSHIRE HATHAWAY INC DEL", "manager_name": "FIRST MANHATTAN CO. LLC.", "shares": 13969, "value_usd": 10031697660, ...}
],
"count": 8,
"warnings": ["BRK named more than one share class on that date; served at the company level"],
"meta": {"entity_id_is": "security", "entity_id_grain": "issuer", ...}
}One manager across the seam
A window that spans meta.archive_edge returns both eras. Berkshire Hathaway's Apple position appears under its historical id up to 2025-12-31 and under its filing id after:
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/AAPL?start=2025-06-30&end=2026-06-30&manager=berkshire%20hathaway%20inc&fields=value_usd,filing_date,source"{
"tickers": ["AAPL"],
"data": [
{"report_date": "2026-06-30", "manager_id": 1067983, "manager_name": "Berkshire Hathaway Inc", "manager_type": null, "shares": 227917808, "value_usd": 65950296923, "filing_date": "2026-08-14", "source": "filing", "manager_id_space": "cik", ...},
{"report_date": "2026-03-31", "manager_id": 1067983, "manager_name": "Berkshire Hathaway Inc", "manager_type": null, "shares": 227917808, "value_usd": 57843260493, "filing_date": "2026-05-15", "source": "filing", "manager_id_space": "cik", ...},
{"report_date": "2025-12-31", "manager_id": 900008350, "manager_name": "BERKSHIRE HATHAWAY INC.", "manager_type": "5", "shares": 227917808, "value_usd": 61961735282.880005, "filing_date": null, "source": "historical", "manager_id_space": "archive", "manager_number": 8350, ...},
{"report_date": "2025-09-30", "manager_id": 900008350, "manager_name": "BERKSHIRE HATHAWAY INC.", "manager_type": "5", "shares": 238212764, "value_usd": 60656116097.32, "filing_date": null, "source": "historical", "manager_id_space": "archive", "manager_number": 8350, ...},
{"report_date": "2025-06-30", "manager_id": 900008350, "manager_name": "BERKSHIRE HATHAWAY INC.", "manager_type": "5", "shares": 280000000, "value_usd": 57447600000, "filing_date": null, "source": "historical", "manager_id_space": "archive", "manager_number": 8350, ...}
],
"data_through": "2026-06-30",
"count": 5,
"next_cursor": null,
"meta": {
...
"freshness": [
{"dataset": "institutional_holdings_historical", "through": "2025-12-31", "promoted_at": "2026-09-24T19:51:07Z"},
{"dataset": "institutional_holdings", "through": "2026-06-30", "promoted_at": "2026-09-25T15:35:44Z"}
]
}
}Filing-era fallback
When the historical era holds nothing for a security in a quarter it covers, and Form 13F filings do, the filing era answers that security and quarter and meta.era_fallback reads true. Texas Pacific Land Trust at 2020-12-31:
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/TPL?quarter=2020-12-31&limit=2&fields=value_usd,filing_date,source"{
"tickers": ["TPL"],
"historical_resolution": {
"TPL": {"entity_id": 10003778, "current_entity_id": 10008244, "as_of": "2020-12-31", "via": "requested_date"}
},
"historical_resolution_note": "Resolved to a previous holder of the ticker: the requested date window ends before the ticker's current holder acquired it. Pass entity_id to pin an entity explicitly.",
"data": [
{"entity_id": 10003778, "ticker": "TPL", "entity_name": "TEXAS PACIFIC LAND TRUST", "report_date": "2020-12-31", "manager_id": 1056823, "manager_name": "HORIZON KINETICS ASSET MANAGEMENT LLC", "shares": 1606293, "value_usd": 1167775000, "filing_date": "2021-02-16", "source": "filing", ...},
...
],
...
"meta": {"archive_edge": "2025-12-31", "era_fallback": true, ...}
}The same response shows a reorganised ticker: TPL in 2020 names Texas Pacific Land Trust (10003778), while today's TPL is a different security (10008244).
Recycled tickers
A ticker resolves on the dates of your window. GM at 2005-12-31 resolves to the General Motors Corp share class (10001629), not today's General Motors:
curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/GM?quarter=2005-12-31&limit=2&fields=value_usd"{
"tickers": ["GM"],
"historical_resolution": {
"GM": {"entity_id": 10001629, "current_entity_id": 10001879, "as_of": "2005-12-31", "via": "requested_date"}
},
...
"data": [
{"entity_id": 10001629, "ticker": "GM", "entity_name": "GENERAL MOTORS CORP", "report_date": "2005-12-31", "manager_id": 900081540, "manager_name": "STATE STR CORPORATION", "manager_type": "1", "shares": 93371689, "value_usd": 1813278200.38, "issuer_entity_id": 4, ...},
...
],
...
}Value scale
value_usd is in US dollars, not thousands, in both eras. Each value below divides by shares to the security's closing price from Prices:
- BlackRock's 2026-Q1 Apple position:
290512251859USD ÷1144695425shares =253.79USD, Apple's close on 2026-03-31. - Horizon Kinetics' 2020-Q4 Texas Pacific Land Trust position, filed in thousands:
1167775000USD ÷1606293shares =727.00USD, the close on 2020-12-31.
Two fields describe the scale of a filing's values:
unit_scale_suspect: truemarks a filing that states the scale of its values inconsistently. Values on the row are served as filed.value_scale_corrected: true, returned only when you name it infields, marks a filing made before 2023-01-03 that already stated whole dollars. Values on the row are served as filed rather than multiplied by 1,000.
Names on historical rows
On a ticker request, ticker is the ticker you requested and entity_name is the company's current name. The name as stated for the quarter is in issuer_name_as_filed. META at 2020-12-31 returns rows with "ticker": "META", "entity_name": "META PLATFORMS INC" and "issuer_name_as_filed": "FACEBOOK INC". Join on entity_id, not on names.
Coverage boundaries
The first quarter end is 1978-12-31, and manager coverage is broad from 1980. end=1978-09-30 returns 200 with an empty data array. Form 13F is due within 45 days of a quarter end, so the newest quarter fills in over the following weeks; data_through gives the latest quarter on your page.
Unlinked lines
A filed line that names no security on record carries entity_id, ticker, entity_name and link_method null. A ticker or entity_id request cannot reach it; Manager holdings returns it under its manager.
Request examples
The three largest Apple holders at the end of 2026-Q1:
import xfinlink as xfl
xfl.set_api_key("YOUR_API_KEY")
df = xfl.holdings(
"AAPL",
quarter="2026-03-31",
fields=["filing_date", "value_usd", "source", "is_amendment"],
include_amendments=None,
limit=3,
)
print(df[["ticker", "report_date", "manager_id", "manager_name",
"shares", "value_usd", "is_amendment"]].to_string(index=False))curl -s -H "X-API-Key: YOUR_API_KEY" \
"https://api.xfinlink.com/v1/holdings/AAPL?quarter=2026-03-31&fields=filing_date,value_usd,source,is_amendment&limit=3"Which three institutions held the most Apple shares at the end of the first quarter of 2026, and what were the positions worth?ticker report_date manager_id manager_name shares value_usd is_amendment
AAPL 2026-03-31 2012383 BlackRock, Inc. 1144695425 290512251859 False
AAPL 2026-03-31 2100119 VANGUARD CAPITAL MANAGEMENT LLC 953847648 242076924860 True
AAPL 2026-03-31 93751 STATE STREET CORP 602341409 152868226190 False{
"tickers": ["AAPL"],
"data": [
{
"entity_id": 10003635,
"ticker": "AAPL",
"entity_name": "APPLE INC",
"report_date": "2026-03-31",
"manager_id": 2012383,
"manager_name": "BlackRock, Inc.",
"manager_type": null,
"shares": 1144695425,
"filing_date": "2026-05-13",
"value_usd": 290512251859,
"source": "filing",
"is_amendment": false,
"manager_id_space": "cik",
"issuer_entity_id": 1,
"link_method": "censored",
"issuer_name_as_filed": "APPLE INC",
"title_of_class": "COM",
"lines": 25,
"filer_cik": 2012383,
"accession_number": "0002012383-26-001841",
"unit_scale_suspect": false,
"is_current": true
},
{
"entity_id": 10003635,
"ticker": "AAPL",
"entity_name": "APPLE INC",
"report_date": "2026-03-31",
"manager_id": 2100119,
"manager_name": "VANGUARD CAPITAL MANAGEMENT LLC",
"manager_type": null,
"shares": 953847648,
"filing_date": "2026-05-15",
"value_usd": 242076924860,
"source": "filing",
"is_amendment": true,
"manager_id_space": "cik",
"issuer_entity_id": 1,
"link_method": "censored",
"issuer_name_as_filed": "APPLE INC",
"title_of_class": "COM",
"lines": 1,
"filer_cik": 2100119,
"accession_number": "0002100119-26-001311",
"unit_scale_suspect": false,
"is_current": true
},
{
"entity_id": 10003635,
"ticker": "AAPL",
"entity_name": "APPLE INC",
"report_date": "2026-03-31",
"manager_id": 93751,
"manager_name": "STATE STREET CORP",
"manager_type": null,
"shares": 602341409,
"filing_date": "2026-05-15",
"value_usd": 152868226190,
"source": "filing",
"is_amendment": false,
"manager_id_space": "cik",
"issuer_entity_id": 1,
"link_method": "censored",
"issuer_name_as_filed": "APPLE INC",
"title_of_class": "COM",
"lines": 1,
"filer_cik": 93751,
"accession_number": "0000093751-26-000315",
"unit_scale_suspect": false,
"is_current": true
}
],
"data_through": "2026-03-31",
"count": 3,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaWR6SnRNVFZYYlZKcVZFaEJlWGszWTFsaGJGZFVaeUlzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbWt3ZDAxNU1IcE5XSGN5VFVSSmVrNUVSVEJOUkd3NFQxUk5NMDVVUmpoamVrVjNUVVJCZWs1cVRURm1TSGMyVFZFOVBTSjl8bjl6U09iTTdhbHlOMkpVODVJLU9nZw==",
"meta": {
"entity_id_is": "security",
"entity_id_grain": "security",
"archive_edge": "2025-12-31",
"amendment_view": "current",
"era_fallback": false,
"knowledge_time": "2026-09-26T18:53:54Z",
"as_of": "2026-03-31",
"freshness": [
{"dataset": "institutional_holdings", "through": "2026-06-30", "promoted_at": "2026-09-25T15:35:44Z"}
],
"has_more": true,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaWR6SnRNVFZYYlZKcVZFaEJlWGszWTFsaGJGZFVaeUlzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbWt3ZDAxNU1IcE5XSGN5VFVSSmVrNUVSVEJOUkd3NFQxUk5NMDVVUmpoamVrVjNUVVJCZWs1cVRURm1TSGMyVFZFOVBTSjl8bjl6U09iTTdhbHlOMkpVODVJLU9nZw=="
}
}{"tool": "get_holdings", "arguments": {"ticker": "AAPL", "quarter": "2026-03-31", "fields": "filing_date,value_usd,source,is_amendment", "limit": 3}}
{
"tickers": ["AAPL"],
"data": [
{
"entity_id": 10003635,
"ticker": "AAPL",
"entity_name": "APPLE INC",
"report_date": "2026-03-31",
"manager_id": 2012383,
"manager_name": "BlackRock, Inc.",
"manager_type": null,
"shares": 1144695425,
"filing_date": "2026-05-13",
"value_usd": 290512251859,
"source": "filing",
"is_amendment": false,
"manager_id_space": "cik",
"issuer_entity_id": 1,
"link_method": "censored",
"issuer_name_as_filed": "APPLE INC",
"title_of_class": "COM",
"lines": 25,
"filer_cik": 2012383,
"accession_number": "0002012383-26-001841",
"unit_scale_suspect": false,
"is_current": true
},
...
],
"data_through": "2026-03-31",
"count": 3,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaWR6SnRNVFZYYlZKcVZFaEJlWGszWTFsaGJGZFVaeUlzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbWt3ZDAxNU1IcE5XSGN5VFVSSmVrNUVSVEJOUkd3NFQxUk5NMDVVUmpoamVrVjNUVVJCZWs1cVRURm1TSGMyVFZFOVBTSjl8bjl6U09iTTdhbHlOMkpVODVJLU9nZw==",
"meta": {
"entity_id_is": "security",
"entity_id_grain": "security",
"archive_edge": "2025-12-31",
"amendment_view": "current",
"era_fallback": false,
"knowledge_time": "2026-09-26T18:53:54Z",
"as_of": "2026-03-31",
"freshness": [
{"dataset": "institutional_holdings", "through": "2026-06-30", "promoted_at": "2026-09-25T15:35:44Z"}
],
"has_more": true,
"next_cursor": "djJ8ZXlKeUlqb2lhRzlzWkdsdVozTWlMQ0p4SWpvaWR6SnRNVFZYYlZKcVZFaEJlWGszWTFsaGJGZFVaeUlzSW5BaU9qSXNJbXNpT2lKTmFrRjVUbWt3ZDAxNU1IcE5XSGN5VFVSSmVrNUVSVEJOUkd3NFQxUk5NMDVVUmpoamVrVjNUVVJCZWs1cVRURm1TSGMyVFZFOVBTSjl8bjl6U09iTTdhbHlOMkpVODVJLU9nZw=="
}
}The tool result's text is the same JSON body as the curl response.
Was this page helpful?
Thank you for helping improve xfinlink documentation.
- Need help? Get in touch.
- Building with an LLM? Read llms.txt.
- Using Claude or ChatGPT? Connect the MCP server.