Financial Data API: 1,255 Daily Bars, Both Closes
Financial data API: 1,255 AAPL daily bars with both closes, plus statements, an 81-contract options chain, and ticker news. Live from GET /v1/finance/.
A financial data API in 2026 is four joinable surfaces, not a quote panel. Quote, ticker-search, and markets paint a panel. A client does not buy a panel. It buys daily OHLCV with corporate actions on the same row, statements that reuse the field names already on a quote, an options chain you can filter, and ticker news that concats with a web news-search row.
History APIs usually make you pick adjusted or unadjusted close. Statements live under different field names than the quote, so you write a second mapper. News is a proprietary object that will not concat with a web news-search row. Korean filings need a different parser again.
Then I measured. One GET /v1/finance/history on AAPL over 2021-09-05 through 2026-09-05 returned 1,255 daily bars, close and adj_close on the same row, 20 dated dividend rows, 0 splits, 1 credit. That number is why this post exists.
So I shipped four new reads under GET /v1/finance/: history, statements, options, news. I left quote, ticker-search, and markets unchanged on purpose. Moving them would have dropped fields already populated. Old /v1/google_finance/ paths still resolve. Below is the live harvest from 2026-09-05 — real curl, trimmed JSON, 15 credits billed — plus the Korean supporting cut and the limits I will not paper over.
How do you pull stock price history (1,255 daily bars, both closes) from the API?
Most stock price history APIs make you pick a close. This one does not. GET /v1/finance/history returns daily bars with close and adj_close on the same row, and corporate actions as dated rows in the same list. Default interval is 1d. No second call for the adjustment. No third call for the dividend calendar.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/history?keyword=AAPL&start_date=2021-09-05&end_date=2026-09-05"Pulled 2026-09-05, 00:46–00:49 UTC. 1,255 daily bars. Range returned 2021-09-07 → 2026-09-04 (weekends and unlisted sessions omitted). currency=USD on 1,255/1,255. 1,254 rows have both close and adj_close. 19 rows where they are equal. 20 dividend rows. 0 split rows. 1 credit.
First bar, 2021-09-07T13:30:00Z:
{
"id": "AAPL:2021-09-07T13:30:00Z",
"symbol": "AAPL",
"date": "2021-09-07T13:30:00Z",
"open": 154.97000122070312,
"high": 157.25999450683594,
"low": 154.38999938964844,
"close": 156.69000244140625,
"adj_close": 152.83091735839844,
"volume": 82278300,
"dividend": null,
"split_ratio": null,
"currency": "USD",
"interval": "1d"
}Open 154.97, high 157.26, low 154.39, close 156.69, adj_close 152.83. That is a $3.86 gap on day one of a five-year window. Substituting one for the other compounds that gap the further back you go. Use adj_close for total return. Use close when you want the print close that actually traded that session.
Dividends sit on the session they take effect, same list, not a second endpoint. First captured: 0.22 on 2021-11-05. Last captured, 2026-08-10T13:30:00Z:
{
"id": "AAPL:2026-08-10T13:30:00Z",
"symbol": "AAPL",
"date": "2026-08-10T13:30:00Z",
"open": 306.8299865722656,
"high": 308.260009765625,
"low": 304.6099853515625,
"close": 308.260009765625,
"adj_close": 308.260009765625,
"volume": 44812500,
"dividend": 0.27,
"split_ratio": null,
"currency": "USD",
"interval": "1d"
}On 2026-08-10, close equals adj_close (308.26) because the dividend is already on the row as dividend: 0.27. This pull found zero split_ratio rows. Do not write a split that is not there.
Last bar, 2026-09-04T13:30:00Z:
{
"id": "AAPL:2026-09-04T13:30:00Z",
"symbol": "AAPL",
"date": "2026-09-04T13:30:00Z",
"open": 328.30499267578125,
"high": 328.92999267578125,
"low": 317.8599853515625,
"close": null,
"adj_close": null,
"volume": 38272821,
"dividend": null,
"split_ratio": null,
"currency": "USD",
"interval": "1d"
}Open 328.305, high 328.930, low 317.860, volume 38,272,821, close null, adj_close null. Volume showed up. The close did not. The session is not finalized. Do not treat ticker-search's 319.97 as that bar's close — 319.97 is price.current from a different read, timestamped 2026-09-05 00:30:00 +00:00. In a stock data API pipeline, join on date. The dividend is already on the bar.
Can one financial statements API call return income, balance sheet, and cash flow?
Yes. One GET /v1/finance/statements call returns income, balance sheet, and cash flow as a single statement: "combined" object per period. Field names match the financials block on a quote (revenue, net_income, earnings_per_share, free_cash_flow). You parse the quote financials block and this list with the same mapper. _delta is the period-over-period fractional change, not a percentage point: revenue_delta: 0.064 is +6.4%, not 0.064%.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/statements?keyword=AAPL"Default type=annual. 5 credits. 5 reporting periods (2021-09-30 … 2025-09-30). 4 populated. FY2021 is identity-only: the oldest period has nothing to compare against, so the numeric leaves are null. "5 periods" is not "5 complete statements".
| period_end | revenue | net_income | EPS | free_cash_flow |
|---|---|---|---|---|
| 2021-09-30 | — | — | — | — (identity only) |
| 2022-09-30 | 394,328,000,000 | 99,803,000,000 | 6.11 | 111,443,000,000 |
| 2023-09-30 | 383,285,000,000 | 96,995,000,000 | 6.13 | 99,584,000,000 |
| 2024-09-30 | 391,035,000,000 | 93,736,000,000 | 6.08 | 108,807,000,000 |
| 2025-09-30 | 416,161,000,000 | 112,010,000,000 | 7.46 | 98,767,000,000 |
Latest populated period, trimmed:
{
"symbol": "AAPL",
"statement": "combined",
"period_type": "annual",
"period_end": "2025-09-30T00:00:00Z",
"revenue": 416161000000,
"revenue_delta": 0.0642551178283274,
"net_income": 112010000000,
"net_income_delta": 0.19495177946573355,
"earnings_per_share": 7.46,
"free_cash_flow": 98767000000,
"free_cash_flow_delta": -0.09227347505215656
}FY2025 revenue 416,161,000,000 against FY2024's 391,035,000,000 is that 0.064 fraction. Net income 112,010,000,000 is the 0.195 jump. Free cash flow 98,767,000,000 is the −0.092 move. All three statements, one object.
31 populated financial leaves — canonical keys that were non-null in at least one period, identity keys (id, symbol, statement, period_type, period_end) excluded. Always null on this surface, every period: currency, price_to_book, return_on_assets, return_on_capital. That 31 is the honest count. It is not a 143-item chart of accounts.
period_end is fiscal period end, not filing date. Filing dates live on SEC EDGAR, not on this row. Restatements overwrite. This surface cannot reconstruct what was known on a past date. Delay and point-in-time limits sit two sections down.
Samsung quarterly 005930.KS is the same combined shape in won-scale magnitudes. Full numbers in the Korean section.
How do you fetch an options chain — 81 contracts, calls and puts, IV — for one expiry?
GET /v1/finance/options is an options chain API: calls and puts in one flat list. Filter on option_contract.type. Default keyword=AAPL is the nearest expiry, not every listed expiry. Pass a different expiry when you want a later one; this harvest did not walk the rest of the calendar.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/options?keyword=AAPL"First attempt returned 503 SERVICE_UNAVAILABLE ("retry after 30s") and billed 0 — auto-refunded. The retry ~90 seconds later billed 5 and succeeded. The first attempt was not clean. The refund was.
81 contracts (39 calls / 42 puts). 1 expiry in the default response (2026-09-09T00:00:00Z). Strike 240–405. 77 with bid and ask. 76 with open interest. 81 with implied volatility. 21 ITM calls / 17 ITM puts.
Three rows from the same response:
| contract_symbol | type | strike | last | bid | ask | volume | OI | IV | ITM |
|---|---|---|---|---|---|---|---|---|---|
AAPL260909C00250000 | call | 250 | 61.42 | 69.05 | 71.85 | — | 1 | 1.143 | true |
AAPL260909C00320000 | call | 320 | 3.74 | 3.80 | 3.90 | 14,431 | 6,926 | 0.262 | false |
AAPL260909P00320000 | put | 320 | 3.85 | 3.75 | 3.85 | 8,621 | 2,721 | 0.257 | true |
[
{
"contract_symbol": "AAPL260909C00250000",
"type": "call",
"strike": 250,
"expiry": "2026-09-09T00:00:00Z",
"last_price": 61.42,
"bid": 69.05,
"ask": 71.85,
"volume": null,
"open_interest": 1,
"implied_volatility": 1.142582412109375,
"in_the_money": true
},
{
"contract_symbol": "AAPL260909C00320000",
"type": "call",
"strike": 320,
"expiry": "2026-09-09T00:00:00Z",
"last_price": 3.74,
"bid": 3.8,
"ask": 3.9,
"volume": 14431,
"open_interest": 6926,
"implied_volatility": 0.26197027099609377,
"in_the_money": false
},
{
"contract_symbol": "AAPL260909P00320000",
"type": "put",
"strike": 320,
"expiry": "2026-09-09T00:00:00Z",
"last_price": 3.85,
"bid": 3.75,
"ask": 3.85,
"volume": 8621,
"open_interest": 2721,
"implied_volatility": 0.2567213000488281,
"in_the_money": true
}
]Ticker-search had AAPL at 319.97, so the 320-strike pair is the near-the-money row. The 320 call is out of the money (IV 0.262, volume 14,431). The 320 put is in the money (IV 0.257, volume 8,621). The 250 call is deep ITM with volume: null and open interest 1 — a contract that exists, not a contract that traded that session. Calls and puts share one list. Contract symbols follow OCC OSI (AAPL260909C00250000 is AAPL, 2026-09-09, call, strike 250). Fields present: strike, bid, ask, open_interest, implied_volatility. This is not an execution feed. The delay is in the limits section.
How do you get ticker news in the same row shape as Google News search?
GET /v1/finance/news is a ticker news API that returns a NewsArticleList. Article fields match the Google News search row: id, title, url, source, domain, snippet, image_url, published_at, rank, placement. Only placement differs (ticker_news vs news_search / top_stories). Concat the two arrays. The unified schema is the point: you do not write a second news parser. It is stock market data API output you can join, not a second news object to special-case.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/news?keyword=AAPL"10 articles. 1 credit. page_size=10, dropped=0, every row placement=ticker_news. snippet was null on the captured rows. Rank 1, full article object:
{
"id": "6571f3fe-4381-306c-9df3-a7b8ebcdf27c",
"title": "Why Apple (AAPL) Dipped More Than Broader Market Today",
"url": "https://finance.yahoo.com/markets/stocks/articles/why-apple-aapl-dipped-more-214503780.html",
"source": "Zacks",
"domain": "finance.yahoo.com",
"snippet": null,
"image_url": "https://s.yimg.com/uu/api/res/1.2/G.Op7E_jldj.32ijwZluBQ--~B/aD03NDE7dz05MDA7YXBwaWQ9eXRhY2h5b24-/https://media.zenfs.com/en/zacks.com/7853de8d69faeccb7d1ad6ebba40b8a2.jpg",
"published_at": "2026-09-04T21:45:03Z",
"rank": 1,
"placement": "ticker_news"
}Rank 1 is the Zacks piece carried on Yahoo Finance (published_at 2026-09-04T21:45:03Z). This is ticker news, not a filings feed. Rank 8 is a broad-market futures headline that merely mentions Apple. Sources in the 10: Zacks, MT Newswires, Yahoo Finance Video, Motley Fool, 24/7 Wall St., Investor's Business Daily, Proactive.
Do Korean instruments return the same shapes in won?
Same schema. Same reads. Won magnitudes. That is the stock market API test I actually ran: a US-only combined object is a US object with extra fields, not a schema that held.
Hangul is locale-sensitive. Live, this harvest:
keyword=삼성전자under the default US/English locale → 0 items, 0 credits.keyword=삼성전자withlanguage=koandlocation=South Korea→ 5 hits, #1005930:KRX삼성전자 at 255,500 KRW. Also preferred005935:KRX(삼성전자우, 191,600).- Numeric
keyword=005930(English locale) → 4 hits, #1005930:KRX255,500 KRW, then unrelated Israeli-bank collisions (FBKIF/FIBI). Take rank 1 and stop, or use Hangul plus locale.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/ticker-search?keyword=%EC%82%BC%EC%84%B1%EC%A0%84%EC%9E%90&language=ko&location=South%20Korea"Identifier rule, said plainly: ticker-search returns TICKER:EXCHANGE (005930:KRX). History and statements that succeeded in this pull used 005930.KS. Those two strings are not the same. This harvest did not re-paste 005930:KRX into history.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/history?keyword=005930.KS&start_date=2021-09-05&end_date=2026-09-05"1,220 daily bars. currency=KRW on every bar. 20 dividend rows, 0 splits. Last close 255,500. Cache hit (0 credits this run). First bar, 2021-09-06:
{
"id": "005930.KS:2021-09-06T00:00:00Z",
"symbol": "005930.KS",
"date": "2021-09-06T00:00:00Z",
"open": 76800,
"high": 77600,
"low": 76600,
"close": 77300,
"adj_close": 69932.9609375,
"volume": 12861180,
"dividend": null,
"split_ratio": null,
"currency": "KRW",
"interval": "1d"
}Close 77,300, adj_close 69,932.96. Same close-versus-adjusted trap as AAPL, five years earlier, in won.
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/statements?keyword=005930.KS&type=quarterly"6 periods (5 populated). 2024-12-31 is identity-only. Latest 2026-03-31: revenue 133,873,444,000,000, net income 47,101,190,000,000, EPS 7,056. 29 populated leaves. Statements currency leaf is always null — read the unit off history bar.currency=KRW. Magnitudes are won-scale (10¹³–10¹⁴).
{
"symbol": "005930.KS",
"statement": "combined",
"period_type": "quarterly",
"period_end": "2026-03-31T00:00:00Z",
"currency": null,
"revenue": 133873444000000,
"revenue_delta": 0.42665382217496267,
"net_income": 47101190000000,
"earnings_per_share": 7056,
"free_cash_flow": 22097151000000
}I did not pull Samsung options or Samsung news this harvest. Those rows are not below.
What does this financial data API not do?
Prices are delayed. Documented on the changelog, not re-measured this harvest. Korea / London / Tokyo ~20 minutes. US options ~15 minutes. This is not a trading feed. The last AAPL history bar has volume and a null close — consistent with an unfinalized session, not proof of the delay table.
| Venue | Documented delay |
|---|---|
| Korea | 20 minutes |
| London | 20 minutes |
| Tokyo | 20 minutes |
| US options | 15 minutes |
Product-documented, not independently timed on 2026-09-05.
Statements are keyed by fiscal period end, not filing date. No point-in-time reconstruction. Restatements overwrite. The oldest period is identity-only (AAPL FY2021; Samsung 2024-12-31).
Delisted companies return nothing. A recycled ticker returns whoever holds the symbol today. First-trade date is product-documented so you can detect the recycle yourself, but it was not re-measured this harvest — ticker-search metrics was null on the captured rows. I am not going to claim I proved it live.
31 ≠ 143. I counted canonical populated leaves, not raw upstream line items. Options: one expiry per default call, not a walk of every listed expiry. A 503 happened; credits refunded; retry worked.
Quote and markets were not called this harvest. They exist. I left them unchanged on purpose. There is no sample payload for them in this post, because there was no pull.
How do you start using this financial data API?
Get a key. Free credits land on signup. The smallest first call under GET /v1/finance/ is ticker-search:
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/finance/ticker-search?keyword=Apple"5 hits. 1 credit. Rank 1 is AAPL:NASDAQ at 319.97 USD (timestamp 2026-09-05 00:30:00 +00:00). Hit 5 is a name collision: Apple Hospitality REIT (APLE:NYSE) at 15.60. Feed bare AAPL into history, statements, options, and news. Downstream reads in this pull used AAPL, not AAPL:NASDAQ.
The current prefix is /v1/finance/. I moved it because the surface is no longer a Google Finance panel emulator. Old /v1/google_finance/ paths still resolve. Existing keys keep working. I did not break them.
Seven reads, one API key:
| Read | Path | Status | Credits this harvest | What came back |
|---|---|---|---|---|
| quote | /v1/finance/quote | unchanged | — (not pulled) | same fields as before (the stock quote API you already have) |
| ticker-search | /v1/finance/ticker-search | unchanged | 1 | 5 Apple listings |
| markets | /v1/finance/markets | unchanged | — (not pulled) | same fields as before |
| history | /v1/finance/history | new | 1 | 1,255 AAPL bars |
| statements | /v1/finance/statements | new | 5 | 5 annual periods, 31 leaves |
| options | /v1/finance/options | new | 5 | 81 contracts, 1 expiry |
| news | /v1/finance/news | new | 1 | 10 articles |
Harvest billed 15. The other 2 credits were Korean ticker-search lookups (Hangul plus locale, and numeric 005930). Cache hits and the 503 refund billed 0. Per-endpoint credit costs are the live table.
Where next: the visual explorer if you want to see the envelope before writing a single line, and the finance platform reference for params. Pricing-versus-panel is a different post.
Frequently asked questions
Are quotes on this financial data API delayed, and by how much per exchange?
Yes. Documented on the changelog, not re-timed this harvest: Korea / London / Tokyo ~20 minutes; US options ~15 minutes. This is not a trading feed. The last AAPL history bar had volume 38,272,821 with a null close, which is consistent with an unfinalized session, not a stopwatch on the delay table.
What happens if I query a delisted ticker?
Product-documented: empty. A recycled symbol returns whoever holds it today. First-trade date is the documented way to detect the recycle. It was not re-measured on this pull — ticker-search metrics was null — so I am not pasting a field I did not capture.
Does the API cover Korean instruments, including statements in won?
Yes. Same shapes. Live cut: 1,220 KRW daily bars; 6 quarterly periods; Q1 2026 revenue 133,873,444,000,000. Hangul needs language=ko and location=South Korea. History and statements used 005930.KS, not the search id 005930:KRX. The statements currency leaf is null; the unit is on the history bar (currency=KRW).
How many credits does each finance read cost?
This harvest: ticker-search 1, history 1, statements 5, options 5, news 1. Quote and markets were not pulled (unchanged). Korean ticker-search added 2. Total billed 15. The 503 on options refunded. Cache hits billed 0. See per-endpoint credit costs for the live ladder.
Do the old /v1/google_finance/ paths still resolve?
Yes. Current prefix is /v1/finance/. Existing integrations keep working. I moved the prefix because the surface is seven reads, not a three-read panel.
Can I use this as a Google Finance API without changing parsers?
Old paths still resolve, same envelope. For the provider roundup, the pricing table, and "is there an official Google Finance API?", that is Google Finance API pricing compared — the July 2026 comparison. This post is the four new reads, measured.
How do I detect a recycled ticker if the symbol still returns data?
Product-documented: a first-trade date on the row. Not re-measured this harvest. Ticker-search metrics was null on every captured Apple and Samsung row. Do not copy a field I did not capture.
I used to ship three finance reads and call it done. Four more does not make this a tape. The delay table is the point of saying that out loud. If a market or identifier is missing — especially a non-US listing — tell me and I'll try to add it. Korean was the test that the schema had to hold. The explorer and the key form are linked above.
Happy hacking.
— Oscar
Related posts
Instagram Email Finder: 1 Credit, Email When Public
9/9 Instagram about lookups returned country (1 credit). Public email on 3/9 — null when unpublished. YouTube about costs 60 credits. Captured 2026-09-05.
Reddit search API: 25 posts per credit
Reddit search API now returns 25 posts per credit on three English queries (was ~7). Korean search billed 1. Comments flattened 647 at 5 credits, depth 9.
Scrape Threads: 55 Posts for 3 Credits + Comments
Scrape Threads with one API: 55 posts for 3 credits via multi-window search. Plus comments, carousel slides, and phrase expand that turned 0 hits into 44.
