Recipes
Paid plansRun complete Python scripts for recycled tickers, point-in-time statements, past index rosters, backtests, bulk downloads, succession links, ownership joins and incremental refresh.
Each recipe is one complete script. Install the client with pip install -U xfinlink, replace YOUR_API_KEY with your key, and run the file. The output under each script is the output it printed on 2026-09-27, or on 2026-10-02 for Backtest on past index members and Pull many tickers within your limits.
The recipes use Pro. The last one, Refresh only what changed, also runs on Free. The others need Pro or higher because they send more than one ticker or entity_id per request, ask for dates more than one year back, or call insider and holdings endpoints, which return 402 on Free. See Plans and limits.
Two kinds of entity_id
On prices, resolve, search, index and holdings an entity_id names one share class. On fundamentals, metrics and insiders it names the issuer. See Tickers and entities.
Follow a recycled ticker
1. Import the client and set your key
Lines 1–32. Resolve
FBon each date
Lines 5–6date_asksresolvefor the security that carried the ticker on that date. In 2020 that is Meta Platforms' Class A common stock. In September 2025 it is a ProShares exchange-traded fund.3. Print the holder
Line 7instrument_typetells the two apart:commonfor the stock,etffor the fund.4. Pull prices for each holder
Passing the holder's
Lines 8–9entity_idpins the series to that share class, whatever the ticker names today.closeis in USD per share, as traded. The rowtickeris the symbol in force on each date.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")for start, end in [("2020-01-02", "2020-01-08"), ("2025-09-02", "2025-09-08")]: holder = xfl.resolve("FB", date_=start)["data"]["FB"]["entities"][0] print(start, holder["entity_id"], holder["name"], holder["instrument_type"]) px = xfl.prices(entity_id=holder["entity_id"], start=start, end=end, fields=["close"]) print(px[["entity_id", "ticker", "date", "close"]].to_string(index=False))2020-01-02 10002684 META PLATFORMS INC common
entity_id ticker date close
10002684 FB 2020-01-02 209.78000
10002684 FB 2020-01-03 208.67000
10002684 FB 2020-01-06 212.60001
10002684 FB 2020-01-07 213.06000
10002684 FB 2020-01-08 215.22000
2025-09-02 10039593 PROSHARES TRUST etf
entity_id ticker date close
10039593 FB 2025-09-02 40.9411
10039593 FB 2025-09-03 40.9500
10039593 FB 2025-09-04 41.0600
10039593 FB 2025-09-05 41.1500
10039593 FB 2025-09-08 41.2000Follow a predecessor link
1. Import the client and set your key
Lines 1–32. Read the succession link
Lines 5–7include=["events"]addssuccessionto each entity. RTX lists Raytheon Co as a predecessor through amergerdated 2020-04-02. The link'sentity_idis an issuer id.3. Prices for the predecessor
Prices accepts the issuer id and serves that issuer's listed share class, so the rows carry the share-class id
Lines 9–1010012171and the tickerRTN.closeis in USD per share, as traded. The series ends on the merger date.4. Statements for the predecessor
Fundamentals are keyed by issuer, so the link's
Lines 12–13entity_idworks as it is.revenueandnet_incomeare in millions of USD.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")rtx = xfl.resolve("RTX", include=["events"])["data"]["RTX"]["entities"][0]link = rtx["succession"]["predecessors"][0]print(rtx["entity_id"], rtx["name"], "<-", link)px = xfl.prices(entity_id=link["entity_id"], start="2020-03-27", end="2020-04-10", fields=["close"])print(px[["entity_id", "ticker", "date", "close"]].to_string(index=False))fin = xfl.fundamentals(entity_id=link["entity_id"], period_type="annual", start="2017-01-01", fields=["revenue", "net_income"])print(fin[["entity_id", "entity_name", "period_end", "revenue", "net_income"]].to_string(index=False))10006181 R T X CORP <- {'entity_id': 6172, 'name': 'RAYTHEON CO', 'event_type': 'merger', 'event_date': '2020-04-02'}
entity_id ticker date close
10012171 RTN 2020-03-27 142.02000
10012171 RTN 2020-03-30 141.21001
10012171 RTN 2020-03-31 131.14999
10012171 RTN 2020-04-01 122.43000
10012171 RTN 2020-04-02 116.96000
entity_id entity_name period_end revenue net_income
6172 RAYTHEON CO 2017-12-31 25348 2024
6172 RAYTHEON CO 2018-12-31 27058 2909
6172 RAYTHEON CO 2019-12-31 29176 3343Compare two share classes
1. Import the client and set your key
Lines 1–32. Prices for both classes
Lines 5–7GOOGLandGOOGare separate securities, each with its ownentity_idand its ownclose, in USD per share. One request carries both tickers, which needs Pro.3. Statements for their issuer
Both tickers resolve to the same issuer,
Lines 9–11entity_id31223, and return the same rows. Thetickercolumn repeats the ticker you asked for.revenueandnet_incomeare in millions of USD.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")px = xfl.prices(["GOOGL", "GOOG"], start="2026-09-21", end="2026-09-25", fields=["close"])print(px.pivot(index="date", columns="ticker", values="close"))print(px.groupby("ticker")["entity_id"].first().to_dict())for ticker in ["GOOGL", "GOOG"]: fin = xfl.fundamentals(ticker, period_type="annual", start="2024-01-01", fields=["revenue", "net_income"]) print(fin[["entity_id", "ticker", "entity_name", "period_end", "revenue", "net_income"]].to_string(index=False))ticker GOOG GOOGL
date
2026-09-21 350.87 354.97
2026-09-22 347.41 351.16
2026-09-23 334.98 337.83
2026-09-24 339.01 342.36
2026-09-25 341.08 343.92
{'GOOG': 10003590, 'GOOGL': 10030636}
entity_id ticker entity_name period_end revenue net_income
31223 GOOGL ALPHABET INC 2024-12-31 350018 100118
31223 GOOGL ALPHABET INC 2025-12-31 402836 132170
entity_id ticker entity_name period_end revenue net_income
31223 GOOG ALPHABET INC 2024-12-31 350018 100118
31223 GOOG ALPHABET INC 2025-12-31 402836 132170Rebuild a past S&P 500 roster
1. Import pandas and the client, set your key
Lines 1–42. Roster on 2008-09-12
Lines 6–7as_ofreturns the members on that date, including companies that later left the index or stopped trading. Eachentity_idnames a share class.3. Prices for every member
Pro accepts up to 100
Lines 8–11entity_idvalues per request, so the ids go in chunks of 100. Withinterval="1y"each member gets one row for the window, and itsreturn_dailyis the total return compounded from the close on 2008-09-12 to the member's last close on or before 2008-10-10. Returns are decimal fractions:-0.3137is a loss of 31.37%.4. Join prices to the roster
Both tables carry the same share-class
Line 12entity_id.5. Compare all members with the stayers
Lines 14–18removed_dateis empty for members that have never left the index. Keeping only those members moves the equal-weighted return from -0.3137 to -0.2897, a ratio, not a percentage. The worst performer, Lehman Brothers, left the index on 2008-09-16, so a list built from today's members would not contain it.
import pandas as pdimport xfinlink as xflxfl.set_api_key("YOUR_API_KEY")roster = xfl.index("sp500", as_of="2008-09-12")ids = roster["entity_id"].tolist()moves = pd.concat([ xfl.prices(entity_id=ids[i:i + 100], start="2008-09-15", end="2008-10-10", interval="1y", fields=["return_daily"]) for i in range(0, len(ids), 100)])df = roster.merge(moves[["entity_id", "return_daily"]], on="entity_id", how="left")stayed = df["removed_date"].isna()print(len(df), "members on 2008-09-12;", stayed.sum(), "have never left the index since")print("equal-weighted return, all members: ", round(df["return_daily"].mean(), 4))print("equal-weighted return, stayers only: ", round(df.loc[stayed, "return_daily"].mean(), 4))print(df.nsmallest(5, "return_daily")[["entity_id", "ticker", "entity_name", "removed_date", "return_daily"]].to_string(index=False))498 members on 2008-09-12; 248 have never left the index since
equal-weighted return, all members: -0.3137
equal-weighted return, stayers only: -0.2897
entity_id ticker entity_name removed_date return_daily
10023380 LEH LEHMAN BROTHERS HOLDINGS INC 2008-09-16 -0.964384
10024136 WM MR COOPER GROUP INC 2008-09-29 -0.941246
10022022 GGP BROOKFIELD PROPERTY REIT INC 2008-11-12 -0.825045
10018030 AIG AMERICAN INTERNATIONAL GROUP INC NaN -0.808073
10030487 GNW GENWORTH FINANCIAL INC 2015-11-17 -0.763438Backtest on past index members
This recipe takes the S&P 500 members on each rebalance date and holds them for the following month, identifying each member by entity_id.
1. Import pandas and the client, set your key
Lines 1–42. Choose the rebalance dates
Each tuple is a rebalance date followed by the first and last day of the month held after it.
Lines 6–73. Members on the rebalance date
Lines 10–11as_ofreturns the members on that date, including companies that later left the index or stopped trading. Eachentity_idnames one share class, so a recycled ticker cannot pull in another company:WMis Waste Management's ticker today, and on 2008-08-29 it was Washington Mutual's, whose security carries its later name,MR COOPER GROUP INC.4. One monthly return per member
Pro accepts up to 100
Lines 12–16entity_idvalues per request, so the ids go in chunks of 100. Withinterval="1mo"each member gets one row for the month, and itsreturn_dailyis the total return compounded from the last close before the month to the member's last close in the month. Returns are decimal ratios:-0.1091is a loss of 10.91%.5. Score the portfolio
Members join their returns on
Lines 17–19entity_id. Every member held in September 2008 has a return, including Lehman Brothers, which stopped trading on 2008-09-17.6. Members that left
Lehman Brothers and Washington Mutual left the index in September 2008, so the October portfolio holds neither. Their September returns run to their last close.
Lines 20–21meta.delistingon the REST prices response gives the return from that close to the exit,-0.6for Lehman Brothers; see Data coverage and boundaries.
import pandas as pdimport xfinlink as xflxfl.set_api_key("YOUR_API_KEY")months = [("2008-08-29", "2008-09-01", "2008-09-30"), ("2008-09-30", "2008-10-01", "2008-10-31")]for as_of, start, end in months: members = xfl.index("sp500", as_of=as_of) ids = members["entity_id"].tolist() px = pd.concat([ xfl.prices(entity_id=ids[i:i + 100], start=start, end=end, interval="1mo", fields=["return_daily"]) for i in range(0, len(ids), 100) ]) held = members.merge(px[["entity_id", "return_daily"]], on="entity_id", how="left") print(f"held from {as_of}: {len(held)} members, {held['return_daily'].notna().sum()} with a return, " f"equal-weighted {held['return_daily'].mean():.4f}") print(held[held["ticker"].isin(["LEH", "WM", "WB"])] [["entity_id", "ticker", "entity_name", "removed_date", "return_daily"]].to_string(index=False))held from 2008-08-29: 500 members, 500 with a return, equal-weighted -0.1091
entity_id ticker entity_name removed_date return_daily
10023380 LEH LEHMAN BROTHERS HOLDINGS INC 2008-09-16 -0.991920
10024136 WM MR COOPER GROUP INC 2008-09-29 -0.960395
10014467 WB WACHOVIA CORP 2ND NEW 2008-12-31 -0.779735
held from 2008-09-30: 499 members, 499 with a return, equal-weighted -0.2091
entity_id ticker entity_name removed_date return_daily
10014467 WB WACHOVIA CORP 2ND NEW 2008-12-31 0.831425Read statements as of a date
1. Import the client and set your key
Lines 1–32. Same query at two knowledge dates
Lines 5–7as_ofreturns each period as the filings made on or before that date reported it. Withoutas_ofyou get the latest view.startandendboundperiod_endto the fiscal year ending 2020-12-31. See Point-in-time and as-of.3. Print both versions
On 2021-04-01 the only filing for fiscal 2020 was the original annual report of 2021-03-01, with
Lines 9–13net_incomeof -273.035. The amendment filed on 2021-05-10 reports -644.887. Values are in millions of USD, sorevenueof 0.238 is USD 238,000.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")query = dict(period_type="annual", start="2020-12-31", end="2020-12-31", fields=["revenue", "net_income"])known = xfl.fundamentals("SPCE", as_of="2021-04-01", **query)latest = xfl.fundamentals("SPCE", **query)cols = ["entity_id", "period_end", "filing_date", "version", "revenue", "net_income"]print("Known on 2021-04-01:")print(known[cols].to_string(index=False))print("Latest:")print(latest[cols].to_string(index=False))Known on 2021-04-01:
entity_id period_end filing_date version revenue net_income
18383 2020-12-31 2021-03-01 original 0.238 -273.035
Latest:
entity_id period_end filing_date version revenue net_income
18383 2020-12-31 2021-05-10 amendment 0.238 -644.887List every filed version
1. Import the client and set your key
Lines 1–32. Ask for every vintage of one period
Lines 5–12view="as_reported"returns one row per filing that reported the period.startandendboundperiod_endto Microsoft's fiscal year ending 2017-06-30.3. Print the vintages
The filing of 2017-08-02 reported
Line 13revenueof 89,950. The filings of 2018-08-03 and 2019-08-01 report the same year at 96,571, markedrestated. Values are in millions of USD.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")df = xfl.fundamentals( "MSFT", view="as_reported", period_type="annual", start="2017-06-30", end="2017-06-30", fields=["revenue", "net_income"],)print(df[["period_end", "fiscal_year", "filing_date", "version", "revenue", "net_income"]].to_string(index=False))period_end fiscal_year filing_date version revenue net_income
2017-06-30 2017 2017-08-02 original 89950 21204
2017-06-30 2017 2018-08-03 restated 96571 25489
2017-06-30 2017 2019-08-01 restated 96571 25489Join insider trades to holdings
1. Import the client and set your key
Lines 1–32. Form 4 purchases by Berkshire
Lines 5–6insider_namematches any reporting owner on the filing, so filings that list Berkshire Hathaway as a co-owner are included.include_amendments=Noneasks for the version in force of each filing. Insider rows carry the issuer inentity_id.3. Berkshire's Form 13F position
Lines 7–8manageris a case-insensitive match on part of the manager name. Holdings rows carry the share class inentity_idand the issuer inissuer_entity_id.sharesis the reported share count andvalue_usdis in whole USD. Both endpoints need Pro.4. Sum the purchases by quarter
Each purchase is assigned to its calendar quarter end.
Lines 10–12form4_boughtis in shares.form4_held_afteris the largestshares_held_afterin the quarter, the holding after the last purchase.5. Join on the issuer and quarter
The 13F
Lines 14–19sharesat each quarter end equals the holding after the last Form 4 purchase in that quarter.value_usd_bnisvalue_usdin billions of USD. Quarters without purchases show<NA>.
import xfinlink as xflxfl.set_api_key("YOUR_API_KEY")buys = xfl.insiders("OXY", start="2023-01-01", end="2025-12-31", insider_name="berkshire", transaction_type="open_market_buy", include_amendments=None)held = xfl.holdings("OXY", start="2023-01-01", end="2025-12-31", manager="berkshire hathaway inc", include_amendments=None)buys["report_date"] = buys["transaction_date"].dt.to_period("Q").dt.end_time.dt.normalize()form4 = buys.groupby(["entity_id", "report_date"]).agg( form4_bought=("shares", "sum"), form4_held_after=("shares_held_after", "max")).reset_index()joined = held.merge(form4, left_on=["issuer_entity_id", "report_date"], right_on=["entity_id", "report_date"], how="left", suffixes=("", "_issuer"))joined["value_usd_bn"] = (joined["value_usd"] / 1e9).round(2)cols = ["issuer_entity_id", "report_date", "shares", "value_usd_bn", "form4_bought", "form4_held_after"]print(joined[cols].astype({"form4_bought": "Int64", "form4_held_after": "Int64"}) .sort_values("report_date").to_string(index=False)) issuer_entity_id report_date shares value_usd_bn form4_bought form4_held_after
5451 2023-03-31 211707119 13.22 17355469 211707119
5451 2023-06-30 224129192 13.18 12422073 224129192
5451 2023-09-30 224129192 14.54 <NA> <NA>
5451 2023-12-31 243715804 14.55 19586612 243715804
5451 2024-03-31 248018128 16.12 4302324 248018128
5451 2024-06-30 255281524 16.09 7263396 255281524
5451 2024-09-30 255281524 13.16 <NA> <NA>
5451 2024-12-31 264178414 13.05 8896890 264178414
5451 2025-03-31 264941431 13.08 763017 264941431
5451 2025-06-30 264941431 11.13 <NA> <NA>
5451 2025-09-30 264941431 12.52 <NA> <NA>
5451 2025-12-31 264941431 10.89 <NA> <NA>Track a manager's portfolio
1. Import pandas and the client, set your key
Lines 1–42. Find the manager's ids
Lines 6–8managerssearches Form 13F filers from 2013 onward and returns the filing-era id. Quarters on or beforemeta.archive_edge, 2025-12-31 on 2026-09-27, are served under a historical-era id instead. Line 7 reads it from a holdings row, which carries it inmanager_id.3. Download both eras
Lines 10–13manager_holdingsreturns one row per position and quarter. Each quarter comes from one era only, so nothing is counted twice.4. Summarise each year end
Line 14 keeps every December quarter and the latest quarter.
Lines 14–19value_usdis in whole USD, shown here in billions of USD. In the historical era it is shares times the quarter-end price. In the filing era it is the value the filer reported. Compare values within one era.5. Name the largest position
Lines 20–21tickeris the symbol of each position's security on its report date.
import pandas as pdimport xfinlink as xflxfl.set_api_key("YOUR_API_KEY")filing_id = xfl.managers("berkshire hathaway")["manager_id"].iloc[0]historical_id = xfl.holdings("KO", quarter="2025-12-31", manager="berkshire hathaway inc")["manager_id"].iloc[0]print("filing-era id:", filing_id, "historical-era id:", historical_id)book = pd.concat([ xfl.manager_holdings(historical_id, start="2016-01-01"), xfl.manager_holdings(filing_id, start="2016-01-01"),], ignore_index=True)snap = book[book["report_date"].dt.month.eq(12) | book["report_date"].eq(book["report_date"].max())]summary = snap.groupby("report_date").agg( source=("source", "first"), positions=("shares", "size"), value_usd_bn=("value_usd", lambda v: round(v.sum() / 1e9, 1)),)summary["largest"] = snap.loc[snap.groupby("report_date")["value_usd"].idxmax()].set_index("report_date")["ticker"]print(summary.to_string())filing-era id: 1067983 historical-era id: 900008350
source positions value_usd_bn largest
report_date
2016-12-31 historical 45 147.1 KHC
2017-12-31 historical 48 152.7 AAPL
2018-12-31 historical 48 183.1 AAPL
2019-12-31 historical 52 242.1 AAPL
2020-12-31 historical 47 269.9 AAPL
2021-12-31 historical 44 331.0 AAPL
2022-12-31 historical 49 299.0 AAPL
2023-12-31 historical 41 347.4 AAPL
2024-12-31 historical 38 267.2 AAPL
2025-12-31 historical 42 274.2 AAPL
2026-06-30 filing 29 299.3 AAPLPull many tickers within your limits
Every page of a response counts each ticker or entity_id in the request, and a page of /v1/prices holds up to 5,000 rows. This recipe reads a year of daily closes for every Nasdaq-100 member in requests sized to fit one page each.
1. Import pandas and the client, set your key
Lines 1–42. List the securities
Line 6xfl.index("ndx100")returns today's Nasdaq-100 members, one share-classentity_idper row, anddropna()keeps the rows that carry one. Any list of ids works the same way, such as one built with Search.3. Size each request to one page
A year holds about 252 trading days, so 19 securities fit in one page of 5,000 rows. A request that runs to a second page counts every id again.
Lines 7–84. Fetch in batches
Each call sends up to 19 ids and returns one page. The plan caps, 100 ids per request on Pro, 500 on Max and 5,000 on Redistribution, are upper limits; for daily rows the page size sets the cheapest batch.
Lines 10–12closeis in USD per share, as traded.5. Check the result
The run counts 100 requests against your daily quota: 1 for the roster and 1 for each of the 99 ids. The 24,347 price rows count toward the row allowances, 1,000,000 per clock hour and 5,000,000 per day on Pro. See Rate limits.
Lines 14–16
import pandas as pdimport xfinlink as xflxfl.set_api_key("YOUR_API_KEY")ids = xfl.index("ndx100")["entity_id"].dropna().astype(int).tolist()start, end = "2025-10-01", "2026-09-30"batch = 5000 // 252frames = [xfl.prices(entity_id=ids[i:i + batch], start=start, end=end, fields=["close"]) for i in range(0, len(ids), batch)]px = pd.concat(frames, ignore_index=True)print(len(ids), "securities,", len(frames), "requests of up to", batch, "ids,", len(px), "rows")closes = px.pivot(index="date", columns="ticker", values="close")print(closes.iloc[-3:, :5].to_string())99 securities, 6 requests of up to 19 ids, 24347 rows
ticker AAPL ABNB ADBE ADI ADP
date
2026-09-28 338.40 156.08 231.01 395.43 261.80
2026-09-29 329.40 156.96 233.17 398.22 261.80
2026-09-30 333.02 160.65 239.94 396.71 258.06Page through a cursor
1. Set up the request
Lines 1–5httpxis installed withxfinlink.quarterselects one report date andlimitsets the page size, up to 5,000 rows.2. Follow
next_cursorto the endPass each
Lines 7–15next_cursorback unchanged ascursor. On the last pagenext_cursorisnull. Holdings and insiders returnnext_cursorat the top level of the body. Prices, fundamentals and metrics return it inmeta.next_cursor, andxfl.prices,xfl.fundamentalsandxfl.metricsfollow it for you. See Pagination.3. Count the positions
Each page counts as one request against your daily quota.
Line 17
import httpxurl = "https://api.xfinlink.com/v1/holdings/AAPL"headers = {"X-API-Key": "YOUR_API_KEY"}params = {"quarter": "2026-06-30", "limit": 1000}rows, pages = [], 0while True: body = httpx.get(url, params=params, headers=headers, timeout=120).raise_for_status().json() rows += body["data"] pages += 1 print(f"page {pages}: {body['count']} rows, next_cursor={body['next_cursor'] is not None}") if not body["next_cursor"]: break params["cursor"] = body["next_cursor"]print(len(rows), "positions in AAPL on", rows[0]["report_date"], "in", pages, "pages")page 1: 1000 rows, next_cursor=True
page 2: 1000 rows, next_cursor=True
page 3: 1000 rows, next_cursor=True
page 4: 1000 rows, next_cursor=True
page 5: 1000 rows, next_cursor=True
page 6: 1000 rows, next_cursor=True
page 7: 473 rows, next_cursor=False
6473 positions in AAPL on 2026-06-30 in 7 pagesRefresh only what changed
1. Import the modules
Lines 1–5xfl.status()calls/v1/status, which needs no key.2. Load saved state and current freshness
Lines 7–10/v1/statuslists every dataset withthrough, the last date it covers, andpromoted_at, when that build went live, in UTC.3. Skip tickers whose inputs have not moved
Every data response names the datasets it was built from in
Lines 12–16meta.freshness, with the samedataset,throughandpromoted_atfields as/v1/status. Onlythroughandpromoted_atare compared, and a ticker is downloaded again only when one of its datasets shows a new value.4. Download and remember the freshness
The client's DataFrame functions do not return
Lines 17–21meta, so this recipe reads prices withhttpx. The output shows two runs: the first downloads both tickers, the second finds nothing changed and sends no data request.5. Save the state
This recipe also runs on Free. On Max and Redistribution, the change feed lists exactly what changed, by
Line 23entity_idand date.
import jsonimport osimport httpximport xfinlink as xflSTATE = "freshness_state.json"headers = {"X-API-Key": "YOUR_API_KEY"}state = json.load(open(STATE)) if os.path.exists(STATE) else {}live = {f["dataset"]: f for f in xfl.status()["freshness"]}for ticker in ["AAPL", "MSFT"]: saved = state.get(ticker) if saved and all(live.get(f["dataset"], {}).get(k) == f[k] for f in saved["freshness"] for k in ("through", "promoted_at")): print(ticker, "unchanged since last run: skipped") continue body = httpx.get(f"https://api.xfinlink.com/v1/prices/{ticker}", params={"start": "2026-09-01"}, headers=headers, timeout=120).raise_for_status().json() state[ticker] = {"freshness": body["meta"]["freshness"], "data": body["data"]} print(ticker, "downloaded", len(body["data"]), "rows; depends on", [(f["dataset"], f["through"]) for f in body["meta"]["freshness"]])json.dump(state, open(STATE, "w"), indent=2)AAPL downloaded 18 rows; depends on [('prices', '2026-09-25'), ('price_adjustments', '2026-09-25'), ('shares_outstanding', '2026-09-23')]
MSFT downloaded 18 rows; depends on [('prices', '2026-09-25'), ('price_adjustments', '2026-09-25'), ('shares_outstanding', '2026-09-23')]
AAPL unchanged since last run: skipped
MSFT unchanged since last run: skippedWas 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.