Get startedDashboard

Prices

Get end-of-day prices, volume, adjusted close, total return, dividends, splits and share counts for US-listed securities.

GET/v1/prices/{ticker}
View llms.txt

GET /v1/prices/{ticker} returns end-of-day bars: one row per security per trading day, or one row per period when you pass interval. To name securities by id instead of by ticker, call GET /v1/prices?entity_id=.... Rows are sorted by entity_id, then by date, oldest first.

open, high, low, close and adj_close are in USD per share. volume is a number of shares. return_daily is a decimal ratio, not a percentage: 0.031794 is a return of 3.1794%. dividend is in USD per share. split_ratio is new shares per old share. shares_outstanding is a number of shares and market_cap is in USD, not millions. Every field is defined on Price fields.

Rows are security grain. entity_id names one share class, so GOOGL and GOOG are two series with two ids, and meta.entity_id_grain reads security. See Tickers and entities for how security ids differ from the issuer ids used by Fundamentals.

close is the price as traded and is never adjusted, so it steps at a split. adj_close restates the close to today's share basis for splits, stock dividends and spin-offs, and not for cash dividends; meta.adj_close_basis reads split. return_daily is the total return for the day, cash distributions included.

Daily bars start on 1962-01-02 and run to the latest trading day, which meta.freshness reports as the through date of the prices dataset. Delisted securities are included. Common stocks, ADRs, ETFs and preferred shares listed on US exchanges are covered. See Data coverage and boundaries.

A ticker is resolved on a date: first the request's end, then its start, then today. The first of those dates on which the ticker names a security decides which security you get, and each ticker returns one security. A ticker that names nothing on any of those dates resolves to its most recent holder. When the security served is not the ticker's holder today, meta.historical_resolution says so. An entity_id request skips ticker resolution. The edge cases below show each path.

Each ticker counts against your quota

Every ticker or entity_id in a request counts as one request against your quota, repeats included. A request for AAPL,MSFT uses two. A request rejected with 400 does not count. See Rate limits.

Parameters

tickerstr | list[str]Required unless entity_id is given

Path segment: one ticker, or a comma-separated list such as AAPL,MSFT. The list may be percent-encoded: AAPL%2CMSFT and AAPL,%20MSFT name the same two tickers. Case-insensitive. BRK-B and BRK.B name the same security. Every ticker in the list counts toward the per-request limit, repeats included: 1 on Free, 100 on Pro, 500 on Max and 5,000 on Redistribution.

entity_idint | list[int]Default: none

Query parameter used in place of the ticker path: /v1/prices?entity_id=10003635. One id or a comma-separated list; repeated ids are served once. A security id serves that share class. An issuer id serves the issuer's one listed security, or its one listed common share class, on the resolution dates; when that choice is not unique it returns 409. Same per-request limits as ticker. Cannot be combined with a ticker in the path.

startstrDefault: none; on Free, one year before today

First date to return, inclusive, as YYYY-MM-DD. Must be a real calendar date. On paid plans, no start means the series starts at its first bar. On Free, a start earlier than one year before today (UTC), or no start, is replaced by that date without an error, and the X-Data-Floor response header shows the date used. When the request's start or end is earlier than that date, warnings also says so.

endstrDefault: none (latest trading day)

Last date to return, inclusive, as YYYY-MM-DD. Must be a real calendar date. Also the first date the ticker is resolved on. Not changed on any plan.

adjuststrDefault: "split"

split or none. none removes adj_close from every row, even when fields names it. No other field changes: open, high, low and close are the traded prices under both values.

intervalstrDefault: "1d"

1d (daily), 3d (three-calendar-day buckets counted from 1970-01-01), 1w (weeks starting Monday), 1mo (calendar months), 3mo (calendar quarters), 6mo (January to June and July to December) or 1y (calendar years). How each field aggregates is on Price fields.

fieldsstr | list[str]Default: the 11 default fields

Comma-separated subset of open, high, low, close, adj_close, volume, return_daily, shares_outstanding, exchange_code, split_ratio, dividend and market_cap. The default and fields=all both return the first 11; market_cap is returned only when named. entity_id, ticker, entity_name, gics_sector and date are always returned, so you do not name them. Unknown names are ignored and listed in warnings; if no name is valid the request fails with 400.

limitintDefault: 1000

Rows per page, from 1 to 5,000. A larger whole number, up to nine digits, is treated as 5,000; 0, a negative or a non-numeric value returns 400. meta.limit shows the value used.

cursorstrDefault: none

Opaque token from meta.next_cursor. Send it with the same path and other parameters to get the next page.

start in the Python client

xfl.prices() sends a start one year before end, or before today, when you pass neither start nor period, on every plan. Over REST, a paid-plan request without start begins at the security's first bar.

Response

A 200 response is a JSON object with two members: data, an array of rows, and meta, an object. A third member, warnings, an array of strings, appears when there is something to report, such as an unknown name in fields, a parameter the endpoint does not read, or an ambiguous ticker in a list.

response.json
{
  "data": [
    ...
    {
      "entity_id": 10003635,
      "ticker": "AAPL",
      "entity_name": "APPLE INC",
      "gics_sector": "Information Technology",
      "date": "2026-09-25",
      "open": 336.04,
      "high": 341.67,
      "low": 334.53,
      "close": 341.07,
      "adj_close": 341.07,
      "volume": 29950100,
      "return_daily": 0.015331031197904244,
      "exchange_code": "NASDAQ",
      "price_basis": "trade",
      "shares_outstanding": 14594180000,
      "shares_as_of": "2026-07-17",
      "shares_source": "filing",
      "shares_stale": false,
      "split_ratio": null,
      "split_ratio_suspect": false,
      "dividend": null,
      "dividend_type": null,
      "ca_source": "vendor"
    }
  ],
  "meta": {
    "tickers_requested": ["AAPL"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": [],
    "resolved_via": {"AAPL": "security_alias"},
    "entity_id_grain": "security",
    "adj_close_basis": "split",
    "segments": [
      {"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2026-09-21", "last_date": "2026-09-25"}
    ],
    "interval": "1d",
    "data_through": "2026-09-25",
    "count": 5,
    "limit": 1000,
    "has_more": false,
    "next_cursor": null,
    "knowledge_time": "2026-09-29T10:33:17Z",
    "as_of": "2026-09-25",
    "freshness": [
      {"dataset": "prices", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "price_adjustments", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "shares_outstanding", "through": "2026-09-25", "promoted_at": "2026-09-27T20:26:42Z"}
    ]
  }
}

That is the last row of GET /v1/prices/AAPL?start=2026-09-21&end=2026-09-25.

Row fields

A row always carries entity_id, ticker, entity_name, gics_sector and date. The other fields follow fields, adjust and the companion rules in the descriptions. With the default fields, a row lists its fields in the order shown.

fieldtypeunitnullabledescription
entity_idintnonenoSecurity id of the share class. Always returned.
tickerstrnoneyesSymbol in force on the row's date; on an interval row, on the bucket's last trading day. A later symbol is never applied to earlier rows: Booking Holdings reads PCLN in 2016. Class shares read in hyphen form, for example BRK-B. null before the first recorded symbol. Always returned.
entity_namestrnonenoCurrent name of the security as recorded, for example APPLE INC. Always returned.
gics_sectorstrnoneyesGICS sector of the issuer. null when the issuer has no GICS classification, for example the ETF GLD. Always returned.
datestrISO datenoTrading date. On an interval row, the first trading date in the bucket. Always returned.
openfloatUSD per shareyesOpening price as traded. null where no opening price is recorded.
highfloatUSD per shareyesHighest price as traded.
lowfloatUSD per shareyesLowest price as traded.
closefloatUSD per shareyesClosing price as traded, never adjusted. On a midpoint row, the midpoint of the bid and ask.
adj_closefloatUSD per shareyesClose restated to today's share basis for splits, stock dividends and spin-offs. Not adjusted for cash dividends. Removed by adjust=none.
volumeintsharesyesShares traded.
return_dailyfloatdecimal ratioyesTotal return including cash distributions: 0.01 is 1%. null on a security's first bar and on a day with no close.
exchange_codestrnoneyesListing exchange on the row's date: NYSE, NASDAQ, AMEX, ARCA, BATS or IEX. null when no listing exchange is recorded.
price_basisstrnonenotrade, or midpoint when the close is a bid/ask midpoint rather than a trade. Returned when open, high, low or close is selected.
shares_outstandingfloatsharesyesShares outstanding for this share class, on the same split basis as close. Not millions. null before the first share-count observation, and when the latest observation is more than 400 days older than the row.
market_capfloatUSDyesclose × shares_outstanding for this share class. Not millions. Returned only when named in fields.
shares_as_ofstrISO dateyesDate of the share-count observation behind shares_outstanding. Returned with shares_outstanding or market_cap.
shares_sourcestrnoneyesOrigin of that observation: filing, filing_class or archive. Returned with shares_outstanding or market_cap.
shares_staleboolnonenotrue when the observation is more than 400 days older than the row; shares_outstanding and market_cap are then null. Returned with shares_outstanding or market_cap.
split_ratiofloatratioyesNew shares per old share on the ex-date: 4 for a 4-for-1 split, 0.125 for a 1-for-8 reverse split, 1.05 for a 5% stock dividend. null on other days.
split_ratio_suspectboolnonenotrue when the day carries a capital change that is not a plain split; split_ratio is then null and adj_close still reflects the change. Returned with split_ratio.
dividendfloatUSD per shareyesCash distributed per share on the ex-date, on that date's share basis. null on days with no distribution.
dividend_typestrnoneyesKind of distribution: cash_dividend, special_dividends, return_of_capital, capital_gains or cash_distribution. Several kinds on one day are comma-separated in alphabetical order and dividend is their sum. Returned with dividend.
ca_sourcestrnonenoWhich of the two corporate-action records answered split_ratio and dividend on the row: archive (the historical record) or vendor (the record kept current with each trading day). Price fields describes both. Returned with split_ratio or dividend.

high, low, close and adj_close are null together on a trading day with no recorded price. On interval rows, several fields are aggregated over the bucket; the rules are on Price fields.

meta fields

What each shared meta field means is explained once on Response metadata.

fieldtypeunitnullabledescription
tickers_requestedlist[str]nonenoTickers as read from the path, upper-cased, in request order, repeats kept. Empty on an entity_id request.
tickers_resolveddict[str, int]nonenoEach served ticker and the security id it resolved to. Empty on an entity_id request.
tickers_unresolvedlist[str]nonenoTickers that name no security.
tickers_ambiguousdict[str, list[object]]nonenoOmitted when empty. Tickers that name more than one listed security on the resolution date, each with its candidates, when other tickers in the request were served. The candidate object is described under 409 in Errors.
tickers_no_listed_securitylist[str]nonenoOmitted when empty. Inputs whose company had nothing listed on the resolution dates, when other inputs were served. On an entity_id request it holds the ids as strings.
entity_ids_requestedlist[int]nonenoPresent on entity_id requests only. Ids as parsed, repeats removed.
entity_ids_unresolvedlist[int]nonenoPresent on entity_id requests only. Ids that match nothing.
entity_ids_received_asdict[str, str]nonenoOmitted when empty. For each served id: security_id or issuer_id.
historical_resolutiondict[str, object]nonenoOmitted when empty. Present when a ticker resolved to a security that is not its holder today: entity_id (served), current_entity_id (today's holder, null when nobody holds the ticker today) and as_of (the date the ticker was resolved on, or the last date of the holder's claim).
historical_resolution_notestrnonenoOmitted with historical_resolution. One fixed sentence explaining historical_resolution.
resolved_viadict[str, str]nonenoOmitted on entity_id requests. How each served ticker was matched: security_alias (the share class carries the ticker on the date), issuer_alias (the company carries the ticker and has one listed security, or one listed common share class, on the date), security_alias_censored (the company lists several share classes, and the answer is the class that itself last carried the ticker) or last_holder (nobody holds the ticker on any resolution date; its most recent holder is served).
entity_id_grainstrnonenoAlways security.
adj_close_basisstrnonenoAlways split.
segmentslist[object]nonenoOne entry per security on this page: entity_id, entity_name, first_date, last_date. Empty when the page has no rows.
intervalstrnonenoThe interval used.
data_throughstrISO dateyesLatest date on this page. On interval rows this is the first date of the last bucket. null when the page has no rows.
countintrowsnoRows on this page.
limitintrowsnoPage size used.
has_moreboolnonenotrue when another page follows.
next_cursorstrnoneyesToken for the next page; null on the last page.
delistingdict[str, object]nonenoOmitted when empty. For a series whose last bar is on or before its recorded exit, keyed by security id: event_date (ISO date), event_type (for example merger, exchange, liquidation or dropped) and delisting_return (the return from the last close to the value recorded at the exit, as a decimal ratio; null when not recorded).
knowledge_timestrUTC timestampyesNewest knowledge time across the datasets the response was built from.
as_ofstrISO datenoOmitted without end. Equals the end parameter.
freshnesslist[object]nonenodataset, through and promoted_at for prices, price_adjustments and shares_outstanding.

Response headers

  • X-Data-Floor: on Free only, the one-year floor applied to start, as YYYY-MM-DD.
  • Cache-Control: public, max-age=86400 when end is before today (UTC), otherwise no-store.
  • Request quota headers are described on Rate limits.

Pagination

Pages hold up to limit rows: 1,000 by default, 5,000 at most. Rows are ordered by entity_id, then date, so a multi-ticker request returns one security's rows before the next. When meta.has_more is true, repeat the request with the same path and parameters and add cursor set to meta.next_cursor. The last page has has_more: false and next_cursor: null. meta.count, meta.segments and meta.data_through describe the current page only.

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2026-09-21&end=2026-09-25&fields=close&limit=2"
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2026-09-21", "close": 338.98, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2026-09-22", "close": 339.75, ...}
  ],
  "meta": {
    "data_through": "2026-09-22",
    "count": 2,
    "limit": 2,
    "has_more": true,
    "next_cursor": "djJ8ZXlKeUlqb2ljSEpwWTJWeklpd2ljU0k2SW5kMmJraHVOMk10ZWxnMFpIcFJYMlJ2V25velpGRWlMQ0p3SWpveUxDSnJJam9pVFZSQmQwMUVUVEpOZWxZNFRXcEJlVTVwTUhkUFV6QjVUVzUzZVNKOXxrTTc3ZmUwSnMxaG1QdkwwVGlZV2xn",
    ...
  }
}
Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2026-09-21&end=2026-09-25&fields=close&limit=2&cursor=djJ8ZXlKeUlqb2ljSEpwWTJWeklpd2ljU0k2SW5kMmJraHVOMk10ZWxnMFpIcFJYMlJ2V25velpGRWlMQ0p3SWpveUxDSnJJam9pVFZSQmQwMUVUVEpOZWxZNFRXcEJlVTVwTUhkUFV6QjVUVzUzZVNKOXxrTTc3ZmUwSnMxaG1QdkwwVGlZV2xn"

The second page returns 2026-09-23 and 2026-09-24 with a new next_cursor; the third returns 2026-09-25 with has_more: false.

One query can run to a fixed number of pages: 10 on Free, 50 on Pro, 100 on Max and 200 on Redistribution. Asking for the page after the last one allowed returns 400 with Pagination limit reached. To stay inside the limit, raise limit or split the date range. The Python client follows next_cursor for you. See Pagination.

Errors

statuserror codewhen it happenshow to fix
400bad_requeststart or end is not a real date in YYYY-MM-DD form.Send a valid ISO date, such as 2025-02-28.
400bad_requestend is before start.Send an end on or after start.
400bad_requestadjust is not split or none.Use split or none.
400bad_requestinterval is not an accepted value.Use 1d, 3d, 1w, 1mo, 3mo, 6mo or 1y.
400bad_requestfields names no valid field.Use names from the list in detail.
400bad_requestcursor 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 meta.next_cursor unchanged with the same path and parameters, or repeat the request without cursor.
400bad_requestThe path has no ticker, a ticker and entity_id are both given, or entity_id is empty or not a positive integer.Send either a ticker path or entity_id, with ids from rows, Resolve or Search.
400bad_requestMore tickers or ids than the plan allows in one request.Split the list, or see Plans and limits.
400pagination_limit_reachedThe cursor asks for a page past the plan's page limit. error reads Pagination limit reached.Raise limit or narrow the date range.
401unauthorizedThe API key is missing, invalid or revoked.Send a valid key in X-API-Key. See Authentication.
404not_foundNo ticker or id in the request matches anything.Check the spelling, or look the company up with Search.
404not_foundAn issuer id had nothing listed on any resolution date.Pass a window from when the company traded, or a security id.
404not_foundGET /v1/prices with neither a ticker path nor entity_id.Add a ticker or entity_id.
405method_not_allowedA method other than GET and OPTIONS.Use GET.
409ambiguous_tickerEvery input names more than one listed security on the resolution date.Pick one candidate and request it by entity_id.
429see Rate limitsA request or row allowance is used up.Wait for the reset. A request-limit body gives the wait in retry_after_seconds; daily allowances reset at 00:00 UTC and hourly ones at the top of the UTC hour.
400-date.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Invalid start date format (YYYY-MM-DD)"}
400-adjust.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"adjust must be 'split' or 'none'"}
400-interval.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Invalid interval: '2w'. Valid: 1d, 3d, 1w, 1mo, 3mo, 6mo, 1y"}
400-fields.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"No valid fields in request. Unknown field ignored: 'vwap'. Available fields: open, high, low, close, adj_close, volume, shares_outstanding, return_daily, exchange_code, split_ratio, dividend, market_cap"}
400-cursor.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Invalid cursor: not a cursor this API issued, or one from an earlier paging scheme. Repeat the request without cursor to start from the first page."}
400-entity-id.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Provide either a ticker in the path or an entity_id parameter, not both."}

The other entity_id and path messages are Invalid entity_id: 'AAPL'. Must be a positive integer., entity_id must be a positive integer, or a comma-separated list of them and No ticker provided.

400-too-many.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Maximum 100 tickers per request"}

On Free the same limit reads Free tier allows 1 ticker per request. Upgrade to Pro for up to 100. https://xfinlink.com/pricing; see Plan differences.

400-pages.json
{"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."}
401.json
{"error":"unauthorized","code":"unauthorized","status":401,"detail":"No API key was sent. Pass your key in the X-API-Key header or the ?api_key= query parameter. Get one free at https://xfinlink.com/signup","message":"No API key was sent. Pass your key in the X-API-Key header or the ?api_key= query parameter. Get one free at https://xfinlink.com/signup"}
404-unknown.json
{"error":"not_found","code":"not_found","status":404,"detail":"No matching entities for: XQZQX"}
404-not-listed.json
{"error":"not_found","code":"not_found","status":404,"detail":"No listed security on 2015-06-30 for: 4"}
404-endpoint.json
{"error":"not_found","code":"not_found","status":404,"detail":"Unknown endpoint"}
405.json
{"error":"method_not_allowed","code":"method_not_allowed","status":405,"detail":"This endpoint accepts GET only. Send a GET request."}

A 409 lists the candidates for each ambiguous input, and hint reads pass entity_id=. Each candidate carries entity_id (the security id to request), name, exchange, share_class, last_bar_date (its latest bar on or before the resolution date) and valid_from and valid_to (the dates of its claim on the ticker, null when open).

409.json
{
  "error": "ambiguous_ticker",
  "code": "ambiguous_ticker",
  "status": 409,
  "detail": "BRK names more than one security on 2026-09-25. Request by entity_id to choose one.",
  "candidates": {
    "BRK": [
      {"entity_id": 10006133, "name": "BERKSHIRE HATHAWAY INC DEL", "exchange": "NYSE", "share_class": "A", "last_bar_date": "2026-09-25", "valid_from": null, "valid_to": null},
      {"entity_id": 10025221, "name": "BERKSHIRE HATHAWAY INC DEL", "exchange": "NYSE", "share_class": "B", "last_bar_date": "2026-09-25", "valid_from": null, "valid_to": null}
    ]
  },
  "hint": "pass entity_id="
}

When some inputs resolve and others do not, the request succeeds with 200: unknown tickers are listed in meta.tickers_unresolved, unknown ids in meta.entity_ids_unresolved, and ambiguous tickers with their candidates in meta.tickers_ambiguous and by name in warnings.

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL,XQZQX,BRK?start=2026-09-25&end=2026-09-25&fields=close"
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2026-09-25", "close": 341.07, "price_basis": "trade"}
  ],
  "meta": {
    "tickers_requested": ["AAPL", "XQZQX", "BRK"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": ["XQZQX"],
    "tickers_ambiguous": {"BRK": [{"entity_id": 10006133, "name": "BERKSHIRE HATHAWAY INC DEL", "exchange": "NYSE", "share_class": "A", "last_bar_date": "2026-09-25", "valid_from": null, "valid_to": null}, {"entity_id": 10025221, "name": "BERKSHIRE HATHAWAY INC DEL", "exchange": "NYSE", "share_class": "B", "last_bar_date": "2026-09-25", "valid_from": null, "valid_to": null}]},
    ...
  },
  "warnings": ["BRK names more than one security on that date; pick one from meta.tickers_ambiguous and request it by entity_id"]
}

A fields list that mixes valid and unknown names returns 200 with the valid fields and a warnings array, for example ["Unknown field ignored: 'vwap'"].

Plan differences

Prices are available on every plan. Free differs from paid plans in history depth, tickers per request and pages per query. Max works as Pro does, with the higher limits shown.

One-year history on Free

The same request on Pro and on Free:

Terminal
curl -s -D - -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2025-09-22&end=2025-10-01&fields=close"

Pro returns every trading day from 2025-09-22, with no X-Data-Floor header:

headers
HTTP/2 200
content-type: application/json
cache-control: public, max-age=86400
...
x-ratelimit-limit-day: 10000
...
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-22", "close": 256.08, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-23", "close": 254.43, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-24", "close": 252.31, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-25", "close": 256.87, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-26", "close": 255.46, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-29", "close": 254.43, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-09-30", "close": 254.63, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-10-01", "close": 255.45, ...}
  ],
  "meta": {
    "count": 8,
    ...
  }
}

Free, on 2026-09-27, moves start to 2025-09-27, reports the floor in a header and says so in warnings. The first trading day on or after it is 2025-09-29:

headers
HTTP/2 200
content-type: application/json
cache-control: public, max-age=86400
x-data-floor: 2025-09-27
...
x-ratelimit-limit-day: 100
x-ratelimit-limit-hour: 40
...
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2025-09-29", "close": 254.43, "price_basis": "trade"},
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2025-09-30", "close": 254.63, "price_basis": "trade"},
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2025-10-01", "close": 255.45, "price_basis": "trade"}
  ],
  "meta": {
    "segments": [{"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2025-09-29", "last_date": "2025-10-01"}],
    "count": 3,
    "as_of": "2025-10-01",
    ...
  },
  "warnings": ["The Free plan covers the last year, from 2025-09-27; rows before that date are not included. Paid plans cover the full history: https://xfinlink.com/pricing"]
}

No error is returned for the moved start. end is never moved, so on Free a window that ends before the floor returns 200 with an empty data array and a warning that the window has no rows. The ticker is still resolved on the dates you asked for: /v1/prices/GM?start=2008-12-29&end=2008-12-31 on Free returns no rows and the same meta.historical_resolution for General Motors Corporation that Pro returns with three rows.

Tickers and ids per request

/v1/prices/AAPL,MSFT returns both series on Pro. On Free it returns 400:

400-free-tickers.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Free tier allows 1 ticker per request. Upgrade to Pro for up to 100. https://xfinlink.com/pricing"}

/v1/prices?entity_id=10003635,10030636 on Free:

400-free-entity-ids.json
{"error":"bad_request","code":"bad_request","status":400,"detail":"Free tier allows 1 entity_id per request. Upgrade to Pro for up to 100. https://xfinlink.com/pricing"}

On Pro, 101 tickers return Maximum 100 tickers per request. Redistribution accepts 101.

Pages per query

Free allows 10 pages per query, Pro 50, Max 100 and Redistribution 200. The Free message adds an upgrade hint:

400-free-pages.json
{"error":"Pagination limit reached","code":"pagination_limit_reached","status":400,"detail":"Free tier supports up to 10 pages per query. Upgrade to Pro for 50-page queries: https://xfinlink.com/pricing","message":"Free tier supports up to 10 pages per query. Upgrade to Pro for 50-page queries: https://xfinlink.com/pricing"}

Request quotas per plan are on Plans and limits and Rate limits.

Edge cases

Most examples in this section read dates more than 12 months back. Paid plans return these rows; on Free, the same requests return only the rows inside the one-year window described above.

Delisted companies

A delisted company resolves on a window from when it traded. A series that ends at a recorded exit carries meta.delisting. Lehman Brothers was dropped from its exchange on 2008-09-17:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/LEH?start=2008-09-12&end=2008-09-19&fields=close,volume,return_daily"
response.json
{
  "data": [
    {"entity_id": 10023380, "ticker": "LEH", "date": "2008-09-12", "close": 3.65, "volume": 307134300, "return_daily": -0.135071, "price_basis": "trade", ...},
    {"entity_id": 10023380, "ticker": "LEH", "date": "2008-09-15", "close": 0.21, "volume": 467808800, "return_daily": -0.942466, "price_basis": "trade", ...},
    {"entity_id": 10023380, "ticker": "LEH", "date": "2008-09-16", "close": 0.3, "volume": 141625000, "return_daily": 0.428572, "price_basis": "trade", ...},
    {"entity_id": 10023380, "ticker": "LEH", "date": "2008-09-17", "close": 0.13, "volume": 215333100, "return_daily": -0.566667, "price_basis": "trade", ...}
  ],
  "meta": {
    "tickers_resolved": {"LEH": 10023380},
    "historical_resolution": {"LEH": {"entity_id": 10023380, "current_entity_id": null, "as_of": "2008-09-12"}},
    "resolved_via": {"LEH": "security_alias"},
    "delisting": {"10023380": {"event_date": "2008-09-17", "event_type": "dropped", "delisting_return": -0.6}},
    ...
  }
}

The window's end, 2008-09-19, falls after the last trade, so the ticker resolved on start instead, as historical_resolution.as_of shows. current_entity_id is null because no security holds LEH today. delisting_return is the return from the last close to the value recorded at the exit, as a decimal ratio: -0.6 is a fall of 60%.

Twitter's series ends at its 2022 acquisition:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/TWTR?start=2022-10-24&end=2022-10-31&fields=close,volume,return_daily"
response.json
{
  "data": [
    {"entity_id": 10003373, "ticker": "TWTR", "date": "2022-10-24", "close": 51.52, "volume": 22987553, "return_daily": 0.032672, "price_basis": "trade", ...},
    {"entity_id": 10003373, "ticker": "TWTR", "date": "2022-10-25", "close": 52.78, "volume": 35077848, "return_daily": 0.024457, "price_basis": "trade", ...},
    {"entity_id": 10003373, "ticker": "TWTR", "date": "2022-10-26", "close": 53.35, "volume": 28064973, "return_daily": 0.0108, "price_basis": "trade", ...},
    {"entity_id": 10003373, "ticker": "TWTR", "date": "2022-10-27", "close": 53.7, "volume": 140831508, "return_daily": 0.00656, "price_basis": "trade", ...}
  ],
  "meta": {
    "data_through": "2022-10-27",
    "count": 4,
    "delisting": {"10003373": {"event_date": "2022-10-27", "event_type": "merger", "delisting_return": 0.009311}},
    "as_of": "2022-10-31",
    ...
  }
}

With no dates at all, /v1/prices/TWTR resolves through resolved_via: last_holder and serves Twitter's whole series from 2013-11-07 on paid plans.

Recycled tickers

GM belonged to General Motors Corporation until 2009 and has belonged to General Motors Company since 2010. The window decides which one you get, and one request never mixes them.

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/GM?start=2008-12-29&end=2008-12-31&fields=close,volume"
response.json
{
  "data": [
    {"entity_id": 10001629, "ticker": "GM", "entity_name": "GENERAL MOTORS CORP", "gics_sector": "Consumer Discretionary", "date": "2008-12-29", "close": 3.6, "volume": 18431200, "price_basis": "trade"},
    {"entity_id": 10001629, "ticker": "GM", "entity_name": "GENERAL MOTORS CORP", "gics_sector": "Consumer Discretionary", "date": "2008-12-30", "close": 3.8, "volume": 25272300, "price_basis": "trade"},
    {"entity_id": 10001629, "ticker": "GM", "entity_name": "GENERAL MOTORS CORP", "gics_sector": "Consumer Discretionary", "date": "2008-12-31", "close": 3.2, "volume": 26131000, "price_basis": "trade"}
  ],
  "meta": {
    "tickers_resolved": {"GM": 10001629},
    "historical_resolution": {"GM": {"entity_id": 10001629, "current_entity_id": 10001879, "as_of": "2008-12-31"}},
    "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.",
    "delisting": {"10001629": {"event_date": "2009-06-01", "event_type": "dropped", "delisting_return": -0.186667}},
    ...
  }
}

The same ticker on a 2026 window returns General Motors Company, entity_id 10001879, with no historical_resolution:

response.json
{
  "data": [
    {"entity_id": 10001879, "ticker": "GM", "entity_name": "GENERAL MOTORS CO", "gics_sector": "Consumer Discretionary", "date": "2026-09-24", "close": 80.57, "volume": 7936246, "price_basis": "trade"},
    {"entity_id": 10001879, "ticker": "GM", "entity_name": "GENERAL MOTORS CO", "gics_sector": "Consumer Discretionary", "date": "2026-09-25", "close": 82.63, "volume": 7222357, "price_basis": "trade"}
  ],
  "meta": {
    "tickers_resolved": {"GM": 10001879},
    "resolved_via": {"GM": "security_alias"},
    ...
  }
}

With only a start, the ticker is resolved on start. /v1/prices/GM?start=2009-05-27 returns General Motors Corporation's last four bars, from 2009-05-27 to 2009-06-01, and stops there: it does not continue into General Motors Company's series. A window whose end falls on or after 2010-11-18, General Motors Company's first day, returns General Motors Company only.

To read one holder whatever the window, pass its id. entity_id=10001629 is the security id of General Motors Corporation's shares. entity_id=4 is the company's issuer id, and resolves to the share class it had listed on the dates asked:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices?entity_id=4&start=2008-12-30&end=2008-12-31&fields=close"
response.json
{
  "data": [
    {"entity_id": 10001629, "ticker": "GM", "date": "2008-12-30", "close": 3.8, "price_basis": "trade", ...},
    {"entity_id": 10001629, "ticker": "GM", "date": "2008-12-31", "close": 3.2, "price_basis": "trade", ...}
  ],
  "meta": {
    "entity_ids_requested": [4],
    "entity_ids_received_as": {"4": "issuer_id"},
    "delisting": {"10001629": {"event_date": "2009-06-01", "event_type": "dropped", "delisting_return": -0.186667}},
    ...
  }
}

The same issuer id on a 2015 window returns 404 No listed security on 2015-06-30 for: 4. Resolve lists every holder of a ticker with its dates.

Share classes

Each share class is its own series. Alphabet's class C (GOOG) and class A (GOOGL) have different ids, prices, volumes and share counts:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/GOOGL,GOOG?start=2026-09-24&end=2026-09-25&fields=close,volume,shares_outstanding,market_cap"
response.json
{
  "data": [
    {"entity_id": 10003590, "ticker": "GOOG", "entity_name": "ALPHABET INC", "gics_sector": "Communication Services", "date": "2026-09-24", "close": 339.01, "volume": 15964993, "price_basis": "trade", "shares_outstanding": 5527000000, "market_cap": 1873708270000, "shares_as_of": "2026-07-15", "shares_source": "filing_class", "shares_stale": false},
    {"entity_id": 10003590, "ticker": "GOOG", "entity_name": "ALPHABET INC", "gics_sector": "Communication Services", "date": "2026-09-25", "close": 341.08, "volume": 13313053, "price_basis": "trade", "shares_outstanding": 5527000000, "market_cap": 1885149160000, "shares_as_of": "2026-07-15", "shares_source": "filing_class", "shares_stale": false},
    {"entity_id": 10030636, "ticker": "GOOGL", "entity_name": "ALPHABET INC", "gics_sector": "Communication Services", "date": "2026-09-24", "close": 342.36, "volume": 23777199, "price_basis": "trade", "shares_outstanding": 5868000000, "market_cap": 2008968480000, "shares_as_of": "2026-07-15", "shares_source": "filing_class", "shares_stale": false},
    {"entity_id": 10030636, "ticker": "GOOGL", "entity_name": "ALPHABET INC", "gics_sector": "Communication Services", "date": "2026-09-25", "close": 343.92, "volume": 21880846, "price_basis": "trade", "shares_outstanding": 5868000000, "market_cap": 2018122560000, "shares_as_of": "2026-07-15", "shares_source": "filing_class", "shares_stale": false}
  ],
  "meta": {
    "tickers_requested": ["GOOGL", "GOOG"],
    "tickers_resolved": {"GOOGL": 10030636, "GOOG": 10003590},
    "segments": [{"entity_id": 10003590, "entity_name": "ALPHABET INC", "first_date": "2026-09-24", "last_date": "2026-09-25"}, {"entity_id": 10030636, "entity_name": "ALPHABET INC", "first_date": "2026-09-24", "last_date": "2026-09-25"}],
    ...
  }
}

GOOG comes first because rows are ordered by entity_id, not by the order of the path. market_cap covers the requested class only; the whole-company figure is on Metrics.

A ticker that names two listed classes returns 409. BRK names both Berkshire Hathaway classes; the 409 body is shown under Errors. BRK-B and BRK.B both name class B, and every row reads BRK-B:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/BRK-B,BRK.B?start=2026-09-25&end=2026-09-25&fields=close"
response.json
{
  "data": [
    {"entity_id": 10025221, "ticker": "BRK-B", "date": "2026-09-25", "close": 505.48, "price_basis": "trade", ...}
  ],
  "meta": {
    "tickers_requested": ["BRK-B", "BRK.B"],
    "tickers_resolved": {"BRK-B": 10025221, "BRK.B": 10025221},
    "resolved_via": {"BRK-B": "security_alias", "BRK.B": "security_alias"},
    "count": 1,
    ...
  }
}

Two tickers that resolve to one security return its rows once. On a 1998 window, BRK.B names both classes and returns 409. entity_id=10025221 returns class B for any window, and its rows read BRK-B.

Renamed companies

A row's ticker is the symbol in force on that row's date. Booking Holdings traded as PCLN until 2018, and its 2016 rows read PCLN when you ask for BKNG:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/BKNG?start=2016-01-04&end=2016-01-05&fields=close,exchange_code"
response.json
{
  "data": [
    {"entity_id": 10027852, "ticker": "PCLN", "date": "2016-01-04", "close": 1245.37, "exchange_code": "NASDAQ", "price_basis": "trade", ...},
    {"entity_id": 10027852, "ticker": "PCLN", "date": "2016-01-05", "close": 1210.68994, "exchange_code": "NASDAQ", "price_basis": "trade", ...}
  ],
  "meta": {
    "tickers_resolved": {"BKNG": 10027852},
    ...
  }
}

Dates before coverage

A window that ends before a security's first bar returns 200 with no rows. IBM's bars start on 1962-01-02, the first date of daily coverage:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/IBM?start=1955-01-01&end=1961-12-31&fields=close"
response.json
{
  "data": [],
  "meta": {
    "tickers_resolved": {"IBM": 10001962},
    "segments": [],
    "data_through": null,
    "count": 0,
    "as_of": "1961-12-31",
    ...
  }
}

The earliest rows can precede the first recorded symbol. IBM's rows read ticker: null until 1962-07-02:

response.json
{
  "data": [
    {"entity_id": 10001962, "ticker": null, "date": "1962-06-28", "close": 344, "exchange_code": "NYSE", "price_basis": "trade", ...},
    {"entity_id": 10001962, "ticker": null, "date": "1962-06-29", "close": 339.25, "exchange_code": "NYSE", "price_basis": "trade", ...},
    {"entity_id": 10001962, "ticker": "IBM", "date": "1962-07-02", "close": 350, "exchange_code": "NYSE", "price_basis": "trade", ...},
    {"entity_id": 10001962, "ticker": "IBM", "date": "1962-07-03", "close": 351.5, "exchange_code": "NYSE", "price_basis": "trade", ...}
  ],
  "meta": {
    ...
  }
}

A company that listed later starts at its first trading day. Apple's first bar is 1980-12-12, and its early closes are bid/ask midpoints with no recorded open or volume:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=1980-12-01&end=1980-12-17&fields=open,high,low,close,adj_close,volume,return_daily"
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "1980-12-12", "open": null, "high": 28.875, "low": 28.75, "close": 28.8125, "adj_close": 0.12862723214285715, "volume": null, "return_daily": null, "price_basis": "midpoint", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "1980-12-15", "open": null, "high": 27.375, "low": 27.25, "close": 27.3125, "adj_close": 0.12193080357142858, "volume": null, "return_daily": -0.052061, "price_basis": "midpoint", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "1980-12-16", "open": null, "high": 25.375, "low": 25.25, "close": 25.3125, "adj_close": 0.11300223214285714, "volume": null, "return_daily": -0.073227, "price_basis": "midpoint", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "1980-12-17", "open": null, "high": 26, "low": 25.875, "close": 25.9375, "adj_close": 0.11579241071428571, "volume": null, "return_daily": 0.024691, "price_basis": "midpoint", ...}
  ],
  "meta": {
    ...
  }
}

adj_close is close divided by 224, the product of Apple's splits since 1980 (2, 2, 2, 7 and 4). return_daily is null on the first bar.

Missing values

Missing numbers are null, never 0. On a trading day with no recorded price the row is still returned, with its prices, volume and return null, and the next day's return_daily runs from the last recorded close.

A share count whose latest observation is more than 400 days older than the row is withheld: shares_outstanding and market_cap are null, shares_as_of still gives the date of that observation, and shares_stale is true.

A security with no share-count observation, such as Whirlpool's Series A depositary shares (WHR-PA), has every share field null and shares_stale: false. The same security has no recorded listing exchange, so exchange_code is null:

response.json
{
  "data": [
    {"entity_id": 10034076, "ticker": "WHR-PA", "date": "2026-09-25", "close": 29, "price_basis": "trade", "shares_outstanding": null, "market_cap": null, "shares_as_of": null, "shares_source": null, "shares_stale": false, ...}
  ],
  "meta": {
    ...
  }
}

Split days

On the ex-date of a split, close steps, split_ratio is set, and adj_close is continuous. Apple's 4-for-1 split took effect on 2020-08-31:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2020-08-27&end=2020-09-02&fields=close,adj_close,return_daily,shares_outstanding,split_ratio,dividend"
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-08-27", "close": 500.04001, "adj_close": 125.0100025, "return_daily": -0.011954, "shares_outstanding": 4275634000, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-08-28", "close": 499.23001, "adj_close": 124.8075025, "return_daily": -0.00162, "shares_outstanding": 4275634000, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-08-31", "close": 129.03999, "adj_close": 129.03999, "return_daily": 0.033912, "shares_outstanding": 17102536000, "split_ratio": 4, "ca_source": "archive", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-09-01", "close": 134.17999, "adj_close": 134.17999, "return_daily": 0.039833, "shares_outstanding": 17102536000, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-09-02", "close": 131.39999, "adj_close": 131.39999, "return_daily": -0.020718, "shares_outstanding": 17102536000, "split_ratio": null, "ca_source": "archive", ...}
  ],
  "meta": {
    "adj_close_basis": "split",
    ...
  }
}

shares_outstanding moves with the split, so close × shares_outstanding stays comparable across it. return_daily on 2020-08-31 is the real one-day return, 3.39%, not the −74% step in close.

A reverse split has a ratio below 1. GE's 1-for-8 reverse split on 2021-08-02 reads split_ratio: 0.125:

response.json
{
  "data": [
    {"entity_id": 10001611, "ticker": "GE", "date": "2021-07-30", "close": 12.95, "adj_close": 64.05507264181495, "shares_outstanding": 8778641000, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10001611, "ticker": "GE", "date": "2021-08-02", "close": 100.6, "adj_close": 62.20019602091297, "shares_outstanding": 1097330125, "split_ratio": 0.125, "ca_source": "archive", ...},
    ...
  ],
  "meta": {
    ...
  }
}

GE's adj_close differs from close on both days because it also carries later capital changes, such as the 2024 GE Vernova spin-off shown below. Booking Holdings' 25-for-1 split on 2026-04-06 reads split_ratio: 25 with ca_source: vendor:

response.json
{
  "data": [
    {"entity_id": 10027852, "ticker": "BKNG", "date": "2026-04-02", "close": 4194.31, "adj_close": 167.7724, "return_daily": 0.002329994073450914, "shares_outstanding": 31673346, "shares_as_of": "2026-02-10", "split_ratio": null, "ca_source": "vendor", ...},
    {"entity_id": 10027852, "ticker": "BKNG", "date": "2026-04-06", "close": 176.19, "adj_close": 176.19, "return_daily": 0.05017273401346101, "shares_outstanding": 791833650, "shares_as_of": "2026-02-10", "split_ratio": 25, "ca_source": "vendor", ...},
    ...
  ],
  "meta": {
    ...
  }
}

A stock dividend reads as a split ratio. Commerce Bancshares' 5% stock dividend on 2025-12-02 reads split_ratio: 1.05, on the same day as a cash dividend of 0.275 USD per share:

response.json
{
  "data": [
    {"entity_id": 10012349, "ticker": "CBSH", "date": "2025-12-01", "close": 54.5, "adj_close": 51.904761904761905, "return_daily": 0.010944, "shares_outstanding": 132415000, "shares_as_of": "2025-11-06", "split_ratio": null, "dividend": null, "dividend_type": null, "ca_source": "archive", ...},
    {"entity_id": 10012349, "ticker": "CBSH", "date": "2025-12-02", "close": 50.59, "adj_close": 50.59, "return_daily": -0.020284, "shares_outstanding": 139035750, "shares_as_of": "2025-11-06", "split_ratio": 1.05, "dividend": 0.275, "dividend_type": "cash_dividend", "ca_source": "archive", ...},
    ...
  ],
  "meta": {
    ...
  }
}

Spin-offs

A spin-off adjusts adj_close before its ex-date and is counted in return_daily, but does not set split_ratio. GE Vernova was spun off from GE on 2024-04-02:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/GE?start=2024-03-27&end=2024-04-04&fields=close,adj_close,return_daily,split_ratio,dividend"
response.json
{
  "data": [
    {"entity_id": 10001611, "ticker": "GE", "date": "2024-03-28", "close": 175.53, "adj_close": 139.70124165616764, "return_daily": -0.025483, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10001611, "ticker": "GE", "date": "2024-04-01", "close": 175.36, "adj_close": 139.56594164430902, "return_daily": -0.000968, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10001611, "ticker": "GE", "date": "2024-04-02", "close": 136.47, "adj_close": 136.47, "return_daily": -0.022183, "split_ratio": null, "ca_source": "archive", ...},
    {"entity_id": 10001611, "ticker": "GE", "date": "2024-04-03", "close": 145.62, "adj_close": 145.62, "return_daily": 0.067048, "split_ratio": null, "ca_source": "archive", ...},
    ...
  ],
  "meta": {
    ...
  }
}

close falls 22% on 2024-04-02 while return_daily is −2.2%, because the value of the GE Vernova shares holders received is in the return. split_ratio stays null.

Where a capital change is recorded as a ratio that is not a plain split, split_ratio is null, split_ratio_suspect is true, and adj_close carries the change. Comcast's capital change on 2026-01-05 reads this way. The same rows show ca_source moving from archive to vendor at the start of 2026:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/CMCSA?start=2025-12-30&end=2026-01-07&fields=close,adj_close,return_daily,split_ratio,dividend"
response.json
{
  "data": [
    {"entity_id": 10029932, "ticker": "CMCSA", "date": "2025-12-31", "close": 29.89, "adj_close": 28.01312089971884, "return_daily": -0.002669, "split_ratio": null, "split_ratio_suspect": false, "ca_source": "archive", ...},
    {"entity_id": 10029932, "ticker": "CMCSA", "date": "2026-01-02", "close": 29.54, "adj_close": 27.68509840674789, "return_daily": -0.011709601873536313, "split_ratio": null, "split_ratio_suspect": false, "ca_source": "vendor", ...},
    {"entity_id": 10029932, "ticker": "CMCSA", "date": "2026-01-05", "close": 28.13, "adj_close": 28.13, "return_daily": 0.016070074475287743, "split_ratio": null, "split_ratio_suspect": true, "ca_source": "vendor", ...},
    {"entity_id": 10029932, "ticker": "CMCSA", "date": "2026-01-06", "close": 27.42, "adj_close": 27.42, "return_daily": -0.025239957340917107, "split_ratio": null, "split_ratio_suspect": false, "ca_source": "vendor", ...},
    ...
  ],
  "meta": {
    ...
  }
}

Dividend days

dividend is set on the ex-date, in USD per share as paid, and return_daily on that day includes it. adj_close is not reduced for cash dividends. Apple's 0.26 USD dividend went ex on 2025-08-11:

response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-08-08", "close": 229.35, "adj_close": 229.35, "return_daily": 0.042358, "dividend": null, "dividend_type": null, "ca_source": "archive", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2025-08-11", "close": 227.18, "adj_close": 227.18, "return_daily": -0.008328, "dividend": 0.26, "dividend_type": "cash_dividend", "ca_source": "archive", ...},
    ...
  ],
  "meta": {
    ...
  }
}

return_daily is (227.18 + 0.26) / 229.35 − 1 = −0.008328.

Other kinds of distribution are named in dividend_type. The next three rows show Costco's 15 USD special dividend on 2023-12-27, a Kimbell Royalty Partners distribution typed as return of capital on 2024-03-12, and Central Securities' combined income and capital-gains distribution on 2025-11-14:

response.json
{"entity_id": 10028101, "ticker": "COST", "date": "2023-12-27", "close": 666.79999, "return_daily": 0.010643, "dividend": 15, "dividend_type": "special_dividends", "ca_source": "archive", ...}
response.json
{"entity_id": 10005171, "ticker": "KRP", "date": "2024-03-12", "close": 15.27, "return_daily": 0.000637, "dividend": 0.43, "dividend_type": "return_of_capital", "ca_source": "archive", ...}
response.json
{"entity_id": 10013916, "ticker": "CET", "date": "2025-11-14", "close": 48.87, "return_daily": 0.005683, "dividend": 2.45, "dividend_type": "capital_gains,cash_dividend", "ca_source": "archive", ...}

On Central Securities' 2025-11-14 row, dividend is the sum of both kinds, 2.45 USD per share.

Aggregated intervals

With interval, each row is one bucket, dated on its first trading day. open is the first open, high and low the extremes, close and adj_close the last, volume the sum, return_daily the compounded return, split_ratio the product and dividend the sum. Prices inside a bucket are as traded, so a bucket that contains a split mixes pre-split and post-split prices in open, high and low:

Terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2020-07-01&end=2020-10-31&interval=1mo"
response.json
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-07-01", "open": 365.12, "high": 425.66, "low": 356.57999, "close": 425.04001, "adj_close": 106.2600025, "volume": 754302265, "return_daily": 0.16513008396106676, "shares_outstanding": 4275634000, "shares_as_of": "2020-07-17", "split_ratio": 1, "dividend": null, "dividend_type": null, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-08-03", "open": 432.79999, "high": 515.14001, "low": 126, "close": 129.03999, "adj_close": 129.03999, "volume": 1184423167, "return_daily": 0.21662183075090669, "shares_outstanding": 17102536000, "shares_as_of": "2020-08-31", "split_ratio": 4, "dividend": 0.82, "dividend_type": "cash_dividend", ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-09-01", "open": 132.75999, "high": 137.98, "low": 103.1, "close": 115.81, "adj_close": 115.81, "volume": 3881627383, "return_daily": -0.10252556356324982, "shares_outstanding": 16976763000, "shares_as_of": "2020-09-25", "split_ratio": 1, "dividend": null, "dividend_type": null, ...},
    {"entity_id": 10003635, "ticker": "AAPL", "date": "2020-10-01", "open": 117.64, "high": 125.39, "low": 107.72, "close": 108.86, "adj_close": 108.86, "volume": 2893828236, "return_daily": -0.06001274268432488, "shares_outstanding": 17001802000, "shares_as_of": "2020-10-16", "split_ratio": 1, "dividend": null, "dividend_type": null, ...}
  ],
  "meta": {
    "interval": "1mo",
    "data_through": "2020-10-01",
    "count": 4,
    "as_of": "2020-10-31",
    ...
  }
}

On interval rows split_ratio is 1 in a bucket with no split, where a daily row reads null. return_daily is the bucket's total return: 16.5% for July 2020. Use adj_close or return_daily for comparisons across a split.

Request examples

Apple's daily bars for the week of 2026-09-21 to 2026-09-25.

request.pycurlprompt
import xfinlink as xfl

xfl.set_api_key("YOUR_API_KEY")

df = xfl.prices("AAPL", start="2026-09-21", end="2026-09-25")
print(df[["ticker", "date", "close", "adj_close", "return_daily", "volume"]].to_string(index=False))
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2026-09-21&end=2026-09-25"
Get Apple's daily prices from 21 to 25 September 2026.
stdoutresponse.jsontool result
ticker       date  close  adj_close  return_daily   volume
  AAPL 2026-09-21 338.98     338.98      0.008479 34999200
  AAPL 2026-09-22 339.75     339.75      0.002272 40711800
  AAPL 2026-09-23 337.02     337.02     -0.008035 31658800
  AAPL 2026-09-24 335.92     335.92     -0.003264 24733100
  AAPL 2026-09-25 341.07     341.07      0.015331 29950100
{
  "data": [
    {
      "entity_id": 10003635,
      "ticker": "AAPL",
      "entity_name": "APPLE INC",
      "gics_sector": "Information Technology",
      "date": "2026-09-21",
      "open": 335.28,
      "high": 339.64,
      "low": 333.05,
      "close": 338.98,
      "adj_close": 338.98,
      "volume": 34999200,
      "return_daily": 0.008478862344926119,
      "exchange_code": "NASDAQ",
      "price_basis": "trade",
      "shares_outstanding": 14594180000,
      "shares_as_of": "2026-07-17",
      "shares_source": "filing",
      "shares_stale": false,
      "split_ratio": null,
      "split_ratio_suspect": false,
      "dividend": null,
      "dividend_type": null,
      "ca_source": "vendor"
    },
    ...
    {
      "entity_id": 10003635,
      "ticker": "AAPL",
      "entity_name": "APPLE INC",
      "gics_sector": "Information Technology",
      "date": "2026-09-25",
      "open": 336.04,
      "high": 341.67,
      "low": 334.53,
      "close": 341.07,
      "adj_close": 341.07,
      "volume": 29950100,
      "return_daily": 0.015331031197904244,
      "exchange_code": "NASDAQ",
      "price_basis": "trade",
      "shares_outstanding": 14594180000,
      "shares_as_of": "2026-07-17",
      "shares_source": "filing",
      "shares_stale": false,
      "split_ratio": null,
      "split_ratio_suspect": false,
      "dividend": null,
      "dividend_type": null,
      "ca_source": "vendor"
    }
  ],
  "meta": {
    "tickers_requested": ["AAPL"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": [],
    "resolved_via": {"AAPL": "security_alias"},
    "entity_id_grain": "security",
    "adj_close_basis": "split",
    "segments": [
      {"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2026-09-21", "last_date": "2026-09-25"}
    ],
    "interval": "1d",
    "data_through": "2026-09-25",
    "count": 5,
    "limit": 1000,
    "has_more": false,
    "next_cursor": null,
    "knowledge_time": "2026-09-29T10:33:17Z",
    "as_of": "2026-09-25",
    "freshness": [
      {"dataset": "prices", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "price_adjustments", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "shares_outstanding", "through": "2026-09-25", "promoted_at": "2026-09-27T20:26:42Z"}
    ]
  }
}
{"tool": "get_prices", "arguments": {"ticker": "AAPL", "start": "2026-09-21", "end": "2026-09-25"}}
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2026-09-21", "open": 335.28, "high": 339.64, "low": 333.05, "close": 338.98, "adj_close": 338.98, "volume": 34999200, "return_daily": 0.008478862344926119, "exchange_code": "NASDAQ", "price_basis": "trade", "shares_outstanding": 14594180000, "shares_as_of": "2026-07-17", "shares_source": "filing", "shares_stale": false, "split_ratio": null, "split_ratio_suspect": false, "dividend": null, "dividend_type": null, "ca_source": "vendor"},
    ...
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2026-09-25", "open": 336.04, "high": 341.67, "low": 334.53, "close": 341.07, "adj_close": 341.07, "volume": 29950100, "return_daily": 0.015331031197904244, "exchange_code": "NASDAQ", "price_basis": "trade", "shares_outstanding": 14594180000, "shares_as_of": "2026-07-17", "shares_source": "filing", "shares_stale": false, "split_ratio": null, "split_ratio_suspect": false, "dividend": null, "dividend_type": null, "ca_source": "vendor"}
  ],
  "meta": {
    "tickers_requested": ["AAPL"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": [],
    "resolved_via": {"AAPL": "security_alias"},
    "entity_id_grain": "security",
    "adj_close_basis": "split",
    "segments": [{"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2026-09-21", "last_date": "2026-09-25"}],
    "interval": "1d",
    "data_through": "2026-09-25",
    "count": 5,
    "limit": 1000,
    "has_more": false,
    "next_cursor": null,
    "knowledge_time": "2026-09-29T10:33:17Z",
    "as_of": "2026-09-25",
    "freshness": [
      {"dataset": "prices", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "price_adjustments", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "shares_outstanding", "through": "2026-09-25", "promoted_at": "2026-09-27T20:26:42Z"}
    ]
  }
}

Was this page helpful?

request.pycurlprompt
import xfinlink as xfl

xfl.set_api_key("YOUR_API_KEY")

df = xfl.prices("AAPL", start="2026-09-21", end="2026-09-25")
print(df[["ticker", "date", "close", "adj_close", "return_daily", "volume"]].to_string(index=False))
curl -s -H "X-API-Key: YOUR_API_KEY" \
  "https://api.xfinlink.com/v1/prices/AAPL?start=2026-09-21&end=2026-09-25"
Get Apple's daily prices from 21 to 25 September 2026.
stdoutresponse.jsontool result
ticker       date  close  adj_close  return_daily   volume
  AAPL 2026-09-21 338.98     338.98      0.008479 34999200
  AAPL 2026-09-22 339.75     339.75      0.002272 40711800
  AAPL 2026-09-23 337.02     337.02     -0.008035 31658800
  AAPL 2026-09-24 335.92     335.92     -0.003264 24733100
  AAPL 2026-09-25 341.07     341.07      0.015331 29950100
{
  "data": [
    {
      "entity_id": 10003635,
      "ticker": "AAPL",
      "entity_name": "APPLE INC",
      "gics_sector": "Information Technology",
      "date": "2026-09-21",
      "open": 335.28,
      "high": 339.64,
      "low": 333.05,
      "close": 338.98,
      "adj_close": 338.98,
      "volume": 34999200,
      "return_daily": 0.008478862344926119,
      "exchange_code": "NASDAQ",
      "price_basis": "trade",
      "shares_outstanding": 14594180000,
      "shares_as_of": "2026-07-17",
      "shares_source": "filing",
      "shares_stale": false,
      "split_ratio": null,
      "split_ratio_suspect": false,
      "dividend": null,
      "dividend_type": null,
      "ca_source": "vendor"
    },
    ...
    {
      "entity_id": 10003635,
      "ticker": "AAPL",
      "entity_name": "APPLE INC",
      "gics_sector": "Information Technology",
      "date": "2026-09-25",
      "open": 336.04,
      "high": 341.67,
      "low": 334.53,
      "close": 341.07,
      "adj_close": 341.07,
      "volume": 29950100,
      "return_daily": 0.015331031197904244,
      "exchange_code": "NASDAQ",
      "price_basis": "trade",
      "shares_outstanding": 14594180000,
      "shares_as_of": "2026-07-17",
      "shares_source": "filing",
      "shares_stale": false,
      "split_ratio": null,
      "split_ratio_suspect": false,
      "dividend": null,
      "dividend_type": null,
      "ca_source": "vendor"
    }
  ],
  "meta": {
    "tickers_requested": ["AAPL"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": [],
    "resolved_via": {"AAPL": "security_alias"},
    "entity_id_grain": "security",
    "adj_close_basis": "split",
    "segments": [
      {"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2026-09-21", "last_date": "2026-09-25"}
    ],
    "interval": "1d",
    "data_through": "2026-09-25",
    "count": 5,
    "limit": 1000,
    "has_more": false,
    "next_cursor": null,
    "knowledge_time": "2026-09-29T10:33:17Z",
    "as_of": "2026-09-25",
    "freshness": [
      {"dataset": "prices", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "price_adjustments", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "shares_outstanding", "through": "2026-09-25", "promoted_at": "2026-09-27T20:26:42Z"}
    ]
  }
}
{"tool": "get_prices", "arguments": {"ticker": "AAPL", "start": "2026-09-21", "end": "2026-09-25"}}
{
  "data": [
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2026-09-21", "open": 335.28, "high": 339.64, "low": 333.05, "close": 338.98, "adj_close": 338.98, "volume": 34999200, "return_daily": 0.008478862344926119, "exchange_code": "NASDAQ", "price_basis": "trade", "shares_outstanding": 14594180000, "shares_as_of": "2026-07-17", "shares_source": "filing", "shares_stale": false, "split_ratio": null, "split_ratio_suspect": false, "dividend": null, "dividend_type": null, "ca_source": "vendor"},
    ...
    {"entity_id": 10003635, "ticker": "AAPL", "entity_name": "APPLE INC", "gics_sector": "Information Technology", "date": "2026-09-25", "open": 336.04, "high": 341.67, "low": 334.53, "close": 341.07, "adj_close": 341.07, "volume": 29950100, "return_daily": 0.015331031197904244, "exchange_code": "NASDAQ", "price_basis": "trade", "shares_outstanding": 14594180000, "shares_as_of": "2026-07-17", "shares_source": "filing", "shares_stale": false, "split_ratio": null, "split_ratio_suspect": false, "dividend": null, "dividend_type": null, "ca_source": "vendor"}
  ],
  "meta": {
    "tickers_requested": ["AAPL"],
    "tickers_resolved": {"AAPL": 10003635},
    "tickers_unresolved": [],
    "resolved_via": {"AAPL": "security_alias"},
    "entity_id_grain": "security",
    "adj_close_basis": "split",
    "segments": [{"entity_id": 10003635, "entity_name": "APPLE INC", "first_date": "2026-09-21", "last_date": "2026-09-25"}],
    "interval": "1d",
    "data_through": "2026-09-25",
    "count": 5,
    "limit": 1000,
    "has_more": false,
    "next_cursor": null,
    "knowledge_time": "2026-09-29T10:33:17Z",
    "as_of": "2026-09-25",
    "freshness": [
      {"dataset": "prices", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "price_adjustments", "through": "2026-09-28", "promoted_at": "2026-09-27T20:18:18Z"},
      {"dataset": "shares_outstanding", "through": "2026-09-25", "promoted_at": "2026-09-27T20:26:42Z"}
    ]
  }
}