Backfill a full history
Page through all the history, save it to a file and resume if it stops.
Read the guide →Get the latest level, the previous close and daily or one minute history for 18 indices through REST or MCP. Levels are decimal strings.
curl --request GET \
--url "https://api.narwhalapi.com/v1/indices/SPX/price" \
--header "Authorization: Bearer $NARWHAL_API_KEY"{
"id": "SPX",
"name": "S&P 500",
"currency": "USD",
"price": "7696.46",
"market_session": "open",
"timestamp": "2026-10-29T18:38:00Z",
"stale": false
}/v1/indicesList every index we price, with its name, region and currency.
indiceslist of objectEvery index we price, each with its id, name, region and currency.
/v1/indices/{id}/priceGet the latest level of one index, with the previous close and the change.
idrequiredIndex id, for example SPX, NDX or DJI. Any case.
idstringThe index code, such as SPX.
namestringThe official name of the index.
currencystringThe currency of the index. Left out for a volatility index.
pricestringThe last level of the index, as a decimal string.
previous_closestringThe close of the previous trading day. Left out when it is not known.
changestringprice minus previous_close. Left out with previous_close.
change_percentstringThe change in percent: 1.5 means 1.5%. Left out with change.
market_sessionone of open, closedopen while the index trades by its published hours, otherwise closed.
timestampdate-timeWhen the price was valid, in UTC with whole seconds.
stalebooleanTrue when the index is open and its level is more than 15 minutes old. A closed index is never stale.
/v1/indices/pricesGet the latest levels of up to 50 indices in one call.
idsrequiredComma-separated ids, at most 50 after duplicates are removed. Each id follows the same rules as the single-price route. One call is counted for each id that returns a price.
priceslist of objectOne entry for each id that returned a price, with the fields of a single price.
errorslist of objectIds that returned no price, each with the code not_found. They are not counted against your quota.
/v1/indices/{id}/barsGet daily or one minute bars of one index, oldest first.
idrequiredIndex id, for example SPX, NDX or DJI. Any case.
intervaloptional1d (one bar per trading day, dated by the day it belongs to) or 1m (one-minute bars, Basic and Pro only; kept for 12 months). Anything else is 400 invalid_interval.
startoptionalFirst bar. 1d: a date (YYYY-MM-DD), inclusive; left out means the oldest bar your plan reaches. 1m: a UTC time (YYYY-MM-DDTHH:MM:SSZ, or a date for 00:00 UTC), inclusive; left out means one day before end.
endoptionalLast bar. 1d: a date, inclusive; left out means the latest finished day. 1m: a UTC time, exclusive; left out means now, or five days after start. At most 5 days between start and end for 1m (400 range_too_large).
cursoroptionalnext_cursor of the previous page, with the same parameters.
idstringThe index code, such as SPX.
currencystringThe currency of the index. Left out for a volatility index.
startstringSent only when your plan moved the start of the range forward.
endstringSent only on Free daily bars, when the 15 minute delay shortened the range.
barslist of objectThe bars, oldest first. Each has timestamp, open, high, low and close, and no volume.
next_cursorstringPass it back to read the next page. Null on the last page.
Page through all the history, save it to a file and resume if it stops.
Read the guide →Run a small script once a day and append the result to a CSV.
Read the guide →Cache responses by data type and tell a rate limit from a used-up quota.
Read the guide →Prices and history for 29 futures through REST and MCP
Explore the API →Listed stock prices and company data through REST and MCP
Explore the API →Free to start. Paid plans add more history and higher limits.
See pricing →18 indices: five US benchmarks, three volatility indices, two MSCI global indices, five Cboe Europe indices and three US sector indices. An id is the standard code, such as SPX, NDX or DJI, in any case.
Yes. A price carries previous_close, change and change_percent once the index's daily history is in. change_percent of 1.5 means 1.5%. All three are left out when the previous close is not known.
VIX, OVX and GVZ measure expected volatility, not money, so their answers have no currency.
Free levels are 15 minutes late and carry delayed: true. Basic and Pro levels are live. When a market is closed, the API answers with the last level and market_session closed.
History starts where we hold it: the S&P 500 begins in February 2023. Free gets daily bars for the last 12 months, Basic the last 5 years and Pro everything we hold. One minute bars are for Basic and Pro, cover the last 12 months and run at most 5 days a request.
Free is $0 for 5,000 requests a month. Basic is $59 a month for 100,000; Pro is $149 a month for 1,000,000.
Create a free key and call the API from your own code.