Pull a symbol's history

Download one symbol's daily volatility risk premium between two dates, then request it each day without downloading an unchanged response.

Goal

Save the daily volatility risk premium of SPY for October 2026 to a file. A second call downloads the file again only when the site has new data.

Before you start

Make your first API call, so that $TP_TOKEN contains a token with data:read. The examples use curl and jq, a command-line JSON processor.

Steps

  1. Request SPY between two dates, and save the response headers: curl -s -D headers.txt -H "Authorization: Bearer $TP_TOKEN" "https://tickplunge.com/api/v1/vrp/SPY?from=2026-10-01&to=2026-10-23" > spy-vrp.json
  2. Count the records: jq .count spy-vrp.json.
  3. Print the last record: jq '.records[-1]' spy-vrp.json.
  4. Save the ETag: grep -i '^etag' headers.txt | cut -d' ' -f2 | tr -d '\r' > etag.txt.
  5. After the next daily run, send the request again with the saved ETag: curl -s -o new.json -w '%{http_code}\n' -H "Authorization: Bearer $TP_TOKEN" -H "If-None-Match: $(cat etag.txt)" "https://tickplunge.com/api/v1/vrp/SPY?from=2026-10-01"
  6. If the call prints 304, keep spy-vrp.json. If it prints 200, new.json contains the new response. Save its ETag as in step 4.

Result

Step 2 prints the number of trade dates in the range. Step 3 prints one record:

{
  "trade_date": "2026-10-23",
  "symbol": "SPY",
  "iv30d": 0.1521,
  "hv30": 0.102,
  "vrp": 0.49117647058823555,
  "ex_ern_iv_30d": 0.1521,
  "log_return_adj": -0.005435295451083226
}

trade_date is the session of the record. The range includes both the from date and the to date. Leave both out to get the whole history. For SPY the history starts on 2020-01-02. The API reference gives the meaning and unit of every field.

A 304 response has no body. It still counts against your plan's daily calls, which are summed across all your tokens. A 304 saves the download only.

Other ways

Every symbol at once

Get the list from /api/v1/symbols, then request each symbol in turn:

for s in $(curl -s -H "Authorization: Bearer $TP_TOKEN" https://tickplunge.com/api/v1/symbols | jq -r '.symbols[]'); do
  curl -s -H "Authorization: Bearer $TP_TOKEN" "https://tickplunge.com/api/v1/vrp/$s" > "vrp-$s.json"
  sleep 1
done

The pause keeps the loop under the slowest plan's rate of 2 calls a second.

Other daily series

The same from and to parameters work on /api/v1/vix/{symbol}, /api/v1/straddle/{symbol} and /api/v1/chart/{symbol}/features. /api/v1/fred/{series} returns the whole history of a rates series.

When to request

Cache-Control shows how many seconds the response stays current. The count ends at 05:00 UTC each day. The daily run starts at 00:15 UTC. A retry starts at 00:30 New York time (04:30 UTC in summer, 05:30 UTC in winter). Either can finish later. Send the request with If-None-Match once a day after the run. A 304 means the new day's data is not available yet.

If something goes wrong

  • records is empty: no trade date is in the range. Check that from is not after to, and that both use YYYY-MM-DD.
  • The newest record is a day old: this is expected. The daily run covers the previous session, and the next run starts at 00:15 UTC.
  • A value is null: the site has no value for that field on that date, such as log_return_adj on the first date of the history.
  • The call returns 429: wait the number of seconds in Retry-After, then increase the pause in the loop.