Overview

The /v1/data/download endpoint returns time-limited signed URLs for Parquet files stored in Google Cloud Storage. Each file contains one hour of data for a single message type. Signed URLs expire after the requested duration (default 12 hours) and can be used directly with DuckDB, pandas, or any HTTP client.

Authentication requires an API key with datasets:read scope, passed via the X-API-Key header. Keys are scoped to specific feeds and date ranges.

Available Feeds

Feed Stream Message Types
kalshi crypto ticker trade market_lifecycle_v2
kraken-futures futures ticker trade
polymarket markets last_trade_price price_change book best_bid_ask

API Reference

GET /v1/data/download

Query Parameters

Parameter Required Description
feed Yes Feed name: kalshi, kraken-futures, or polymarket
from Yes Start date in YYYY-MM-DD format
to Yes End date in YYYY-MM-DD format
type No Filter by message type (e.g. ticker, trade)
expires No Signed URL expiry duration. Default 12h, range 1–12h

Constraints

  • Maximum 7-day date range per request
  • Maximum 200 files per response
  • API key must be authorized for the requested feed
  • Key date range restrictions are enforced (dates are clamped to the key's allowed range)

Response

{
  "feed": "kalshi",
  "from": "2026-02-15",
  "to": "2026-02-15",
  "type": null,
  "files": [
    {
      "path": "kalshi/crypto/2026-02-15/ticker_0000.parquet",
      "name": "ticker_0000.parquet",
      "type": "ticker",
      "hour": "0000",
      "bytes": 1234567,
      "signedUrl": "https://storage.googleapis.com/...",
      "expiresAt": "2026-02-16T00:00:00.000Z"
    }
  ],
  "expiresIn": "12h"
}

Error Responses

Status Reason
400 Invalid or missing parameters (bad date format, unknown feed, range exceeds 7 days)
403 API key not authorized for the requested feed or date range
503 GCS backend not configured on the server

curl Examples

List available feeds:

curl -H "X-API-Key: $API_KEY" https://api.varshtat.com/v1/data/feeds

Get signed URLs for one day of Kalshi data:

curl -H "X-API-Key: $API_KEY" \
  "https://api.varshtat.com/v1/data/download?feed=kalshi&from=2026-02-15&to=2026-02-15"

Filter by message type:

curl -H "X-API-Key: $API_KEY" \
  "https://api.varshtat.com/v1/data/download?feed=kalshi&from=2026-02-15&to=2026-02-15&type=ticker"

Multi-day range with shorter URL expiry:

curl -H "X-API-Key: $API_KEY" \
  "https://api.varshtat.com/v1/data/download?feed=kalshi&from=2026-02-10&to=2026-02-15&expires=6h"

Download all files from a response:

curl -s -H "X-API-Key: $API_KEY" \
  "https://api.varshtat.com/v1/data/download?feed=kalshi&from=2026-02-15&to=2026-02-15" \
  | jq -r '.files[].signedUrl' \
  | xargs -n1 -P4 curl -O

DuckDB Examples

Query directly from a signed URL (no download needed):

SELECT * FROM read_parquet('https://storage.googleapis.com/...')
LIMIT 10;

Query downloaded files with a time filter:

SELECT * FROM read_parquet('ticker_*.parquet')
WHERE ts BETWEEN '2026-02-15 14:00:00' AND '2026-02-15 15:00:00';

Aggregate across hours:

SELECT
  date_trunc('hour', ts) AS hour,
  count(*) AS ticks,
  avg(yes_price) AS avg_price
FROM read_parquet('ticker_*.parquet')
GROUP BY 1 ORDER BY 1;

Python Example

import pandas as pd
import requests

API_KEY = "sk_live_..."
API_HOST = "https://api.varshtat.com"

resp = requests.get(
    f"{API_HOST}/v1/data/download",
    params={"feed": "kalshi", "from": "2026-02-15", "to": "2026-02-15"},
    headers={"X-API-Key": API_KEY},
)
files = resp.json()["files"]

dfs = [pd.read_parquet(f["signedUrl"]) for f in files]
df = pd.concat(dfs, ignore_index=True)
print(f"Loaded {len(df)} rows from {len(files)} files")

File Naming Convention

Parquet files follow the pattern {type}_{HHMM}.parquet:

  • type — message type (ticker, trade, book, etc.)
  • HHMM — UTC hour (0000, 0100, ... 2300)

For example, ticker_1430.parquet contains ticker data from 14:30–15:29 UTC. A full day of one message type produces up to 24 files.

Limits

Limit Value
Max date range per request 7 days
Max files per response 200
Signed URL expiry 1–12 hours (default 12h)
Authentication API key with datasets:read scope
Feed authorization Per-key feed and date range restrictions