Polymarket Up/Down Markets: Live Crypto Price Data and OHLC Charts

Polymarket's Up/Down markets resolve on short price windows for BTC, ETH, and more. Here's how they work and how to pull window outcomes, OHLC candles, and live ticks via the Struct API.

Struct Team
Struct Team
7 min read
Polymarket Up/Down Markets: Live Crypto Price Data and OHLC Charts

The fastest markets on Polymarket

Most prediction markets run for weeks or months. Will a candidate win? Will a bill pass? You take a position and wait.

Polymarket's Up/Down markets are different. They resolve in minutes. Will BTC be higher five minutes from now? Will ETH close the hour above where it opened? A new window opens, traders pick a direction, and the outcome is settled the moment the window ends.

That speed makes them one of the most active corners of Polymarket, and one of the hardest to build on. To trade, chart, or analyze Up/Down markets you need clean crypto price data, mapped to the exact windows the market resolves against, in real time. This post explains how these markets work and how to pull every layer of their data through the Struct API.

The short version:

  • An Up/Down market resolves on whether a crypto asset closes a fixed window higher or lower than it opened.
  • Struct exposes them for BTC, ETH, XRP, SOL, DOGE, BNB, and HYPE, at 5m, 15m, 30m, 1h, 4h, and 1d windows.
  • Past outcomes come from /asset-history, OHLC charts from /asset-history/candlestick, and live ticks plus window events from two WebSocket rooms.
  • Prices come from the same Chainlink feeds Polymarket settles against.

What is a Polymarket Up/Down market?

An Up/Down market is a bet on the direction of a crypto asset over a fixed window of time.

Each market is defined by an asset (BTC, ETH, SOL, and others) and a window length, anywhere from a few minutes to a full day. When a window starts, the asset's open price is locked in. While the window runs, the spot price moves around. When the window ends, the close price is locked, and the market resolves:

  • UP if the close price is greater than the open price
  • DOWN otherwise

That's the whole mechanic. No ambiguity, no waiting on a human to grade the outcome, no oracle dispute window. The price at the start and the price at the end decide everything.

Because the rule is purely numeric, the asset price feed is the market. If you have the open price, the live spot, and the close price for a window, you know exactly where the market stands and how it will resolve.


Why the data is harder than it looks

The mechanic is simple. Getting the data is not.

Polymarket's market data tells you about positions, orders, and trades. It does not hand you a tidy stream of asset prices aligned to each Up/Down window. To reconstruct that yourself, you would need to:

  • Pull the underlying Chainlink price feed for each asset
  • Figure out the exact boundaries of every window for every timeframe
  • Lock the open price at the start of each window and the close at the end
  • Compute the resolution for past windows and keep a live view of the current one
  • Do all of it again for every asset and every timeframe you care about

That's a lot of plumbing before you can draw a single chart. Struct does it for you and exposes the result through three primitives. The Crypto Up/Down feed guide walks through all of them end to end.

Prices come from Chainlink

Struct's asset prices are sourced from the same Chainlink feeds Polymarket uses to settle Up/Down windows. The data you chart is the data the market resolves against.


Three ways to get Up/Down data

What you needHow you get it
Past window outcomesREST: /asset-history
Historical OHLC chartsREST: /asset-history/candlestick
Live spot ticksWebSocket: polymarket_asset_prices
Window open and close eventsWebSocket: polymarket_asset_window_updates

Use the REST endpoints to load history when your app starts. Use the WebSocket rooms to keep it live as new prices and windows arrive. Together they give you a complete, real-time view of every Up/Down market.

Supported assets across all four: BTC, ETH, XRP, SOL, DOGE, BNB, and HYPE.


Past window outcomes

The /asset-history endpoint returns resolved windows: the open price, the close price, the percentage change, and the outcome.

curl "https://api.struct.to/v1/polymarket/asset-history?asset_symbol=BTC&variant=1h&limit=10" \
  -H "X-API-Key: YOUR_API_KEY"

variant is the window length: 5m, 15m, 30m, 1h, 4h, or 1d. Each row in the response is one resolved window:

[
	{
		"asset_symbol": "BTC",
		"asset_open_price": 45250.75,
		"asset_close_price": 45890.5,
		"price_change_percentage": 1.41,
		"outcome": "up",
		"variant": "1h",
		"start_time": 1699564800,
		"end_time": 1699568400
	}
]

This is your backtesting and analytics layer. Pull a few hundred 1h windows for ETH and you can measure how often UP wins, how streaks behave, or how a strategy would have performed. Pass from and to to scan a specific range, and use pagination_key to walk through longer histories.

The same call from the TypeScript SDK:

import Struct from "@structbuild/sdk";

const struct = new Struct({ apiKey: "YOUR_API_KEY" });

const { data: windows } = await struct.assets.getAssetHistory({
	asset_symbol: "BTC",
	variant: "1h",
	limit: 10,
});

OHLC candles for charts

Window outcomes tell you what happened. To draw a price chart, you want candles. The /asset-history/candlestick endpoint returns OHLC bars for any supported asset at TradingView resolutions.

curl "https://api.struct.to/v1/polymarket/asset-history/candlestick?asset_symbol=BTC&resolution=60&count_back=500" \
  -H "X-API-Key: YOUR_API_KEY"

resolution uses TradingView's naming, so it drops straight into a charting library:

  • 1S for one-second bars
  • 1, 5, 15, 30, 60, 240 for minutes
  • D or 1D for daily

count_back returns up to 2500 of the most recent candles, and from / to scope an exact time range. Each bar is compact:

[
	{
		"t": 1700000000,
		"o": 43250.5,
		"h": 43500.75,
		"l": 43100.25,
		"c": 43400.0
	}
]

t is the bar's timestamp, and o, h, l, c are open, high, low, and close. Because the field names and resolution strings already match TradingView conventions, you can feed the response into Lightweight Charts or a TradingView datafeed with almost no transformation.

const { data: candles } = await struct.assets.getAssetCandlestick({
	asset_symbol: "BTC",
	resolution: "60",
	count_back: 500,
});

Live ticks and window events

History gets your chart on screen. Two WebSocket rooms keep it moving. Both connect to wss://api.struct.to/ws.

Live spot prices stream from polymarket_asset_prices. Subscribe with the assets you care about:

{
	"type": "room_message",
	"payload": {
		"room_id": "polymarket_asset_prices",
		"message": { "action": "subscribe", "asset_symbols": ["BTC", "ETH"] }
	}
}

Each tick is an asset_price_tick event carrying the symbol, price, and timestamp_ms. At 0.005 credits per message, this is the cheapest way to drive a live price ticker.

Window events stream from polymarket_asset_window_updates. This room tells you the exact moment a window opens or closes:

{
	"type": "room_message",
	"payload": {
		"room_id": "polymarket_asset_window_updates",
		"message": {
			"action": "subscribe",
			"asset_symbols": ["BTC"],
			"timeframes": ["5m", "1h", "1d"]
		}
	}
}

Each asset_price_window_update event carries the symbol, variant, start_time, end_time, open_price, close_price, and an update_type of either open or close. An open event locks the price a new window will be measured against. A close event locks the final price and resolves the market.


Putting it together

The full lifecycle of a single Up/Down window, end to end:

  1. A window_update with update_type: "open" fires. The open price is locked.
  2. asset_price_tick events stream the live spot price while the window runs. Compare each tick to the open price to know whether UP or DOWN is currently winning.
  3. A window_update with update_type: "close" fires. The close price is locked and the market resolves: UP if close is greater than open, DOWN otherwise.

A live Up/Down chart is just those pieces composed:

  • Load history once with /asset-history/candlestick so the chart has context at mount
  • Subscribe to polymarket_asset_prices and append each tick to the current candle
  • Subscribe to polymarket_asset_window_updates to draw window boundaries and flip the outcome the instant a window closes

No polling, no window math, no Chainlink integration. The data arrives already shaped for the market.


What you can build

Directional trading bots and alerts. Watch live ticks against the locked open price and act when the move is decisive, before the window closes. The same window-close events can drive notifications: see how we built a Polymarket Telegram alerts bot on Struct webhooks.

Multi-timeframe dashboards. Subscribe to polymarket_asset_window_updates for one asset across 5m, 30m, 1h, and 1d, and show every active window for BTC at a glance.

Backtesting and research. Pull thousands of resolved windows from /asset-history and measure UP/DOWN base rates, streak behavior, or strategy performance.

Spot-versus-market arbitrage. Compare the live Chainlink price to where the Up/Down market is pricing the outcome, and trade the gap.

AI agents. Feed window opens, live ticks, and closes to an LLM that narrates each market in real time and flags asymmetric setups.


Get started

Up/Down data is live in production today. Create an API key and pull your first window in under two minutes.

Get started at struct.to/dashboard

Read the Crypto Up/Down guide

TypeScript SDK on npm

Frequently asked questions

Ship faster with Struct

REST API, WebSockets, and Webhooks for Polymarket — free to start, no credit card required.