All APIs

Futures API for live prices and daily history

Get the latest price and daily or one minute history for 29 futures through REST or MCP. Each series is the front month contract, so prices step on roll days.

First request

Get the latest price of WTI crude oil

curl --request GET \
  --url "https://api.narwhalapi.com/v1/futures/CL/price" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"
Example response
{
  "id": "CL",
  "name": "WTI Crude Oil",
  "exchange": "NYMEX",
  "currency": "USD",
  "unit": "usd_per_barrel",
  "price": "102.11",
  "market_session": "open",
  "timestamp": "2026-10-29T18:38:00Z",
  "stale": false
}

Get daily bars

curl --request GET \
  --url "https://api.narwhalapi.com/v1/futures/ES/bars?interval=1d&start=2017-04-03&end=2017-04-03" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"
Example response
{
  "id": "ES",
  "currency": "USD",
  "bars": [
    {
      "timestamp": "2017-04-03T00:00:00Z",
      "open": "2357.5",
      "high": "2363.25",
      "low": "2340",
      "close": "2354.5"
    }
  ],
  "next_cursor": null
}

Endpoints

GETList futures/v1/futures

List every futures contract we price, with its name, category, exchange, currency and unit.

Response fields

  • futureslist of object

    Every contract we price, each with its id, name, category, exchange, currency and unit.


Full reference →
GETGet a futures price/v1/futures/{id}/price

Get the latest price of one contract.

Parameters

  • idrequired

    Futures id: the exchange's root code, for example CL, GC, ES or 6E. Any case. The series is the continuous front month, not adjusted: there is a gap in it on each roll day.

Response fields

  • idstring

    The root code, such as CL.

  • namestring

    The official name of the contract.

  • exchangestring

    The exchange where the contract trades.

  • currencystring

    The currency of the price.

  • unitstring

    What the price is per, such as usd_per_barrel or index_point.

  • pricestring

    The last price of the front month contract, as a decimal string.

  • market_sessionone of open, closed

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

  • timestampdate-time

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

  • staleboolean

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

  • delayedalways true

    Present as true only when the price is 15 minutes late (Free plan).


Full reference →
GETGet several futures prices/v1/futures/prices

Get the latest prices of up to 50 contracts 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 futures bars/v1/futures/{id}/bars

Get daily or one minute bars of one contract, oldest first. Prices are raw front month prices, so they step on roll days.

Parameters

  • idrequired

    Futures id: the exchange's root code, for example CL, GC, ES or 6E. Any case. The series is the continuous front month, not adjusted: there is a gap in it on each roll day.

  • 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 root code, such as CL.

  • currencystring

    The currency of the price.

  • 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

Commodity futures

  • WTI Crude OilCL · NYMEX · USD per barrel
  • Henry Hub Natural GasNG · NYMEX · USD per MMBtu
  • RBOB GasolineRB · NYMEX · USD per gallon
  • NY Harbor ULSDHO · NYMEX · USD per gallon
  • GoldGC · COMEX · USD per troy ounce
  • SilverSI · COMEX · USD per troy ounce
  • PlatinumPL · NYMEX · USD per troy ounce
  • CopperHG · COMEX · USD per pound
  • CornZC · CBOT · cents per bushel
  • Chicago SRW WheatZW · CBOT · cents per bushel
  • SoybeanZS · CBOT · cents per bushel
  • Live CattleLE · CME · cents per pound
  • Lean HogHE · CME · cents per pound

Stock index futures

  • E-mini S&P 500ES · CME · index points
  • E-mini Nasdaq-100NQ · CME · index points
  • E-mini Dow Jones Industrial AverageYM · CBOT · index points
  • E-mini Russell 2000RTY · CME · index points

Treasury futures

  • 2-Year T-NoteZT · CBOT · percent of par
  • 5-Year T-NoteZF · CBOT · percent of par
  • 10-Year T-NoteZN · CBOT · percent of par
  • U.S. Treasury BondZB · CBOT · percent of par

Currency futures

  • Euro FX6E · CME · USD per euro
  • British Pound6B · CME · USD per pound
  • Japanese Yen6J · CME · USD per yen
  • Australian Dollar6A · CME · USD per Australian dollar
  • Canadian Dollar6C · CME · USD per Canadian dollar
  • Swiss Franc6S · CME · USD per Swiss franc
  • New Zealand Dollar6N · CME · USD per New Zealand dollar
  • Mexican Peso6M · CME · USD per Mexican peso

Related APIs

Commodity futures API for oil, metals, grains and livestock

Prices and history for 13 commodity futures

Explore the API →

Indices API for live and historical index levels

Levels and history for 18 indices through REST and MCP

Explore the API →

Spot metals price API

Gold, silver, platinum and palladium spot prices, plus WTI, Brent and copper reference prices.

Explore the API →

Plans and pricing

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

See pricing →

FAQ

Which futures can I get?

29 futures: 13 commodities, 4 stock index futures, 4 Treasury futures and 8 currency futures. An id is the exchange's root code, such as CL, GC, ES, ZN or 6E, in any case. The list route returns every one.

Why does a price jump on some days?

Each series is the front month contract, joined end to end and not adjusted. When the front month changes, the series moves to the next contract and the price steps to that contract's price. CL stepped by about 4 dollars on 19 October 2026. Prices and bars show the step as it traded, so do not read it as a move of one day. That is also why a futures price has no previous close or change: across a roll, a change would be false.

Are prices live or delayed?

Free prices are 15 minutes late and carry delayed: true. Basic and Pro prices are live. When a market is closed, the API answers with the last price and market_session closed.

How much history can I get?

Daily bars go back to April 2017. Free gets the last 12 months, Basic the last 5 years and Pro the full history. One minute bars are for Basic and Pro, cover the last 12 months and run at most 5 days a request. Free gets 403 plan_upgrade_required.

Is there volume?

No. A bar has open, high, low and close. A futures price has no volume, previous close or change.

How do I get several prices at once?

Call /v1/futures/prices with up to 50 ids in ids, such as ids=CL,GC,ES. It counts one call for each id that returns a price. An unknown id comes back in errors and is not counted.

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