All APIs

Indices API for live and historical index levels

Get the latest level, the previous close and daily or one minute history for 18 indices through REST or MCP. Levels are decimal strings.

First request

Get the latest level of the S&P 500

curl --request GET \
  --url "https://api.narwhalapi.com/v1/indices/SPX/price" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"
Example response
{
  "id": "SPX",
  "name": "S&P 500",
  "currency": "USD",
  "price": "7696.46",
  "market_session": "open",
  "timestamp": "2026-10-29T18:38:00Z",
  "stale": false
}

Endpoints

GETList indices/v1/indices

List every index we price, with its name, region and currency.

Response fields

  • indiceslist of object

    Every index we price, each with its id, name, region and currency.


Full reference →
GETGet an index price/v1/indices/{id}/price

Get the latest level of one index, with the previous close and the change.

Parameters

  • idrequired

    Index id, for example SPX, NDX or DJI. Any case.

Main response fields

  • idstring

    The index code, such as SPX.

  • namestring

    The official name of the index.

  • currencystring

    The currency of the index. Left out for a volatility index.

  • pricestring

    The last level of the index, as a decimal string.

  • previous_closestring

    The close of the previous trading day. Left out when it is not known.

  • changestring

    price minus previous_close. Left out with previous_close.

  • change_percentstring

    The change in percent: 1.5 means 1.5%. Left out with change.

  • market_sessionone of open, closed

    open while the index trades by its published hours, otherwise closed.

  • timestampdate-time

    When the price was valid, in UTC with whole seconds.

  • staleboolean

    True when the index is open and its level is more than 15 minutes old. A closed index is never stale.


Full reference →
GETGet several index prices/v1/indices/prices

Get the latest levels of up to 50 indices in one call.

Parameters

  • idsrequired

    Comma-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.

Response fields

  • priceslist of object

    One entry for each id that returned a price, with the fields of a single price.

  • errorslist of object

    Ids that returned no price, each with the code not_found. They are not counted against your quota.


Full reference →
GETGet index bars/v1/indices/{id}/bars

Get daily or one minute bars of one index, oldest first.

Parameters

  • idrequired

    Index id, for example SPX, NDX or DJI. Any case.

  • intervaloptional

    1d (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.

  • startoptional

    First 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.

  • endoptional

    Last 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).

  • cursoroptional

    next_cursor of the previous page, with the same parameters.

Response fields

  • idstring

    The index code, such as SPX.

  • currencystring

    The currency of the index. Left out for a volatility index.

  • startstring

    Sent only when your plan moved the start of the range forward.

  • endstring

    Sent only on Free daily bars, when the 15 minute delay shortened the range.

  • barslist of object

    The bars, oldest first. Each has timestamp, open, high, low and close, and no volume.

  • next_cursorstring

    Pass it back to read the next page. Null on the last page.


Full reference →

Use cases

Backfill a full history

Page through all the history, save it to a file and resume if it stops.

Read the guide →

A daily data pull

Run a small script once a day and append the result to a CSV.

Read the guide →

Caching and 429 errors

Cache responses by data type and tell a rate limit from a used-up quota.

Read the guide →

Coverage

  • S&P 500SPX · US · USD
  • Nasdaq-100NDX · US · USD
  • Dow Jones Industrial AverageDJI · US · USD
  • Russell 2000RUT · US · USD
  • Nasdaq CompositeCOMP · US · USD
  • Cboe Volatility IndexVIX · US
  • MSCI WorldMXWLD · Global · USD
  • MSCI Emerging MarketsMXEF · Global · USD
  • Cboe UK 100BUK100P · UK · GBP
  • Cboe Germany 40BDE40P · Europe · EUR
  • Cboe Europe 50BEP50P · Europe · EUR
  • Cboe Eurozone 50BEZ50P · Europe · EUR
Show all 18 indices
  • Cboe France 40BFR40P · Europe · EUR
  • PHLX Semiconductor SectorSOX · US · USD
  • KBW Nasdaq BankBKX · US · USD
  • Cboe Crude Oil ETF Volatility IndexOVX · US
  • Cboe Gold ETF Volatility IndexGVZ · US
  • PHLX Gold/Silver SectorXAU · US · USD

Related APIs

Futures API for live prices and daily history

Prices and history for 29 futures through REST and MCP

Explore the API →

Stocks API for listed stocks

Listed stock prices and company data through REST and MCP

Explore the API →

Plans and pricing

Free to start. Paid plans add more history and higher limits.

See pricing →

FAQ

Which indices can I get?

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.

Does a level come with the change from yesterday?

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.

Why does a volatility index have no currency?

VIX, OVX and GVZ measure expected volatility, not money, so their answers have no currency.

Are levels live or delayed?

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.

How much history can I get?

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.

What does each plan cost?

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.

Get a free API key