How to embed a live prediction-market chart on your website
Polymarket's own iframe, a Dune or Lychee chart, or a small script on a keyless history endpoint — and the Kalshi terms that rule out the obvious version.
For a Polymarket market, paste its URL into Polymarket's embed builder and copy the iframe: it is free, needs no key and has a chart switch. For a chart you design, fetch the keyless price-history endpoint on your own server and draw it yourself. Kalshi has no embed widget, and its developer agreement bars sharing API data with third parties without written permission, so a Kalshi chart on a public page needs Kalshi's say-so first.
The short way
If the market is on Polymarket, use Polymarket's own widget. Open the embed builder, paste the market's URL, switch on Chart, and choose whether to show buy buttons, volume, live activity, a Y axis and dark mode. Width and height can be fixed in pixels or left to fit the container. Copy the code and paste it into your page or CMS. There is no account, key or plan behind it.
The code comes as a figure containing the iframe and an absolutely positioned link to
polymarket.com laid over the frame's logo. That link sits in your page's markup, not inside the
frame, so it is yours to keep or drop — the builder also offers a Minimal form without it.
If you want a chart in your own style, or a market the widget does not suit, draw it from the keyless history endpoint — but fetch on your server, not in the reader's browser. A scheduled job that writes a small JSON file to your site keeps the venue's rate limits, availability and any regional block off your readers' page loads:
import json
import requests
TOKEN_ID = "YOUR_OUTCOME_TOKEN_ID" # the CLOB token id of the outcome you are charting
r = requests.get(
"https://data-api.polymarket.com/v2/prices-history",
params={"token_id": TOKEN_ID, "interval": "1m"}, # last month, 30-minute buckets by default
timeout=15,
)
r.raise_for_status()
points = [
{"t": p["timestamp"], "p": p["price"], "w": p["resolution_seconds"]}
for p in r.json()["data"]
]
with open("public/market-history.json", "w") as f:
json.dump({"last_observation": points[-1]["t"] if points else None, "points": points}, f)
Then let your page read market-history.json and draw it with whatever charting code you already
use. Print the time of last_observation beside the chart: a static file is "live" only as often as
the job runs, and the last point is the last trade-time observation, not the time of the run.
What the options are
Polymarket Embeds is the venue's own route and the only one here that
is plainly meant for display on somebody else's page. One market per frame, or Rotate All to
cycle one frame through every market in an event. The affiliate code field appends ?via= to every
outbound link in the frame. There is no JavaScript event to listen to and no way to read the price
back out of the iframe. Polymarket's help article describes starting from the embed link on the market's own page
instead, choosing light or dark mode and copying the generated code.
Polymarket dashboards on Dune give you an iframe for any public
visualization — dune.com/embeds/ followed by the query id and the visualization id — and
parameterized queries accept their parameters appended to that URL. Dune's documentation says an
embed stays current "as the underlying query re-runs", which is the catch: reading a dashboard is
free, but scheduling a query to run is a paid-plan feature, so a chart nobody re-runs keeps showing
its last result. It is the route for views a venue's own chart does not draw, computed from
Polymarket's on-chain record.
Lychee publishes interactive charts and dashboards from its workspace, over both Polymarket and Kalshi, and you embed what you publish. There is no free plan, only a demo; paid plans start at 19.99 USD a month, and taking Lychee's branding off a public chart is on Pro at 39.99 USD. It is the no-code way to put a chart of your own design on a page.
The Polymarket Data API is the endpoint in the script above. It takes
an outcome token id and exactly one window form — a relative interval (1h, 6h, 1d, 1w,
1m, max), an absolute start and end, or a single as_of. Left to itself it chooses a bucket
width that keeps the series under roughly 2,500 points. Every point carries resolution_seconds,
the width of the window it was observed in, and the last point is an exact tick that can fall
between bucket edges.
The Kalshi API serves candlesticks at
/series/{series_ticker}/markets/{ticker}/candlesticks with no authentication, in periods of 1, 60
or 1,440 minutes between a required start_ts and end_ts. Each candle has bid, ask and trade
prices as fixed-point dollar strings. Technically it is the easiest Kalshi chart there is; the
obstacle is the agreement under "Where this breaks", not the code.
PredictWidget turns up in searches for this task and is not an answer to it: it shows probability bars for the Polymarket events its own API ranks highest, not a chart, and not a market you choose.
Where this breaks
Kalshi's developer agreement covers the chart. Version 1.1 of the agreement, the one at Kalshi's developer-agreement address on 4 October 2026, binds "any user" of the API and limits use to "facilitating a members own trading on the Exchange". It lists as prohibited caching or storing API data for any other purpose, and sharing it "with third parties in any manner without prior written authorization from Kalshi". A chart on a public web page is sharing it with third parties. The endpoint answering without a key does not change what the agreement says. Ask Kalshi in writing first, and if a third-party product already shows Kalshi charts, whether its arrangement extends to your page is a question for that vendor.
A blocked domain is a blank frame. Polymarket's embed is served from a subdomain of polymarket.com, so a national block on the domain takes the widget with it. The catalogue's check on 30 September 2026 found a Turkish ISP resolver returning the national block page for the embed host and for the data API behind it. Your page loads and a white rectangle sits where the chart was meant to be. A chart drawn from a JSON file on your own host does not have this problem for your readers — though your server needs to reach the venue, and some hosting regions may not.
Your own security headers can block it first. If your site sends a Content-Security-Policy,
the frame-src directive lists which origins may load in a frame; an embed host missing from it is
refused by the browser, and unless you collect CSP reports the only trace is a console error. Add the exact host you embed. For the
script route, a browser-side fetch would also need connect-src to allow the venue — another
reason to fetch on the server.
Fine history expires. On Polymarket's Data API, one-minute data is documented as kept for at least 7
days, five-minute for 60 and thirty-minute for 90; only the 3-hour and 12-hour series are permanent,
and the Data API v2 overview dates the 3-hour series from July 2026, so older history is 12-hour.
An explicit start/end window is capped at 15 days, so a long chart goes through interval=max.
Ask for a bucket width the store no longer holds and you get an empty page, not a coarser one — so a
chart that worked last month can render empty today with the same code. Kalshi's live endpoint stops
at a historical cutoff, and older candles move to a separate historical endpoint.
Gaps are real, and a line hides them. Polymarket's documentation says sparse data forbids assuming uniform spacing, and Kalshi's trade-price fields are null for a period with no trade. A line chart that joins the dots draws a smooth price through hours when nothing happened. Plot points, or break the line where a gap is wider than the bucket.
Which price the chart shows is a choice. Polymarket's history is a price series per outcome token; Kalshi's candles carry bid, ask and traded price separately. A chart of last trades on a quiet market and a chart of the midpoint can disagree by several cents. Label the series with what it is.
The market ends and the frame does not. An embedded market keeps rendering after it resolves, and a Polymarket resolution can be a 50/50 split. An article written around a live figure ends up beside a resolved chart with no explanation. Polymarket's history series ends with a settlement point at 0, 1 or a fraction for voided and split outcomes, which a chart will draw as a cliff unless you handle it.
Buy buttons follow the venue's map, not your audience's. The widget's buy buttons and links go to the international platform, which bars trading from the United States, the United Kingdom and more than thirty other countries. If most of your readers cannot use them, switch buy buttons off.
If you outgrow this
If one chart becomes a page of them, that is a dashboard, and building a dashboard on Polymarket data covers the data plumbing. If you need the history of markets that have already closed, see getting resolved market history. For why the frame is blank for some readers, why a venue is unavailable where you are explains the blocks; for what the plotted number does and does not tell a reader, how accurate the price is.
The approaches, in order
Cards in the catalogue that do this, ordered editorially. Paid placement does not affect this order.
1.Polymarket Embeds
Polymarket's free iframe builder: one market or a rotating event, with chart, buy-button, volume and dark-mode switches, and an affiliate code field.
Polymarket's own iframe widgets and livestream ticker, for putting live odds on a page.
FreeFree tier
2.Polymarket dashboards on Dune
Any public Dune visualization as an iframe; it is exactly as current as the last time the query behind it ran.
Community SQL dashboards over Polymarket's on-chain record, free to read and fork.
Free tier onlyFree tier
3.Lychee
Published interactive charts over Polymarket and Kalshi from a paid workspace; removing Lychee branding from a public chart is a Pro feature.
No-code queries, charts and backtests over Kalshi and Polymarket history.
$19.99/mo
4.Polymarket Data API
Keyless GET /v2/prices-history by outcome token id, for a chart you draw; fine buckets expire, 3-hour and 12-hour buckets are permanent.
Polymarket's keyless read API for trades, positions, holders and price history.
FreeFree tier
5.Kalshi API
Public candlesticks in 1-minute, 1-hour and 1-day periods with no key — but read the developer agreement before putting them on a page.
REST, WebSocket and FIX access to a CFTC-regulated event exchange.
Per-trade feeFree tier
FAQ
Does Kalshi have an embed widget like Polymarket's?
Not one it documents. On 4 October 2026 Kalshi's help centre returned no article for "embed" and its developer documentation index listed no widget. The route left is the API, and Kalshi's developer agreement limits API use to a member's own trading and bars sharing the data with third parties without written authorization.
Why does my embedded Polymarket chart show a blank box to some readers?
Because the frame is served from a subdomain of polymarket.com, and a country that blocks the domain blocks the frame. On 30 September 2026 a Turkish ISP resolver returned the national block page for the embed host. Your page loads; the frame inside it does not, and nothing tells the reader why.
Is an embedded chart a forecast I am publishing?
No, and it should not be presented as one. The chart shows what traders paid on one venue at one time, from a book that may be thin. This page covers getting the number onto your page accurately and labelled; what the number means is covered in the guide on how accurate the price is.
Sources
- Polymarket Embeds (embed builder) — Polymarket, read
- How To Use Embeds — Polymarket, read
- Data API v2 OpenAPI description (GET /v2/prices-history) — Polymarket, read
- Data API v2 overview (price history resolution and availability) — Polymarket, read
- Get Market Candlesticks — Kalshi, read
- Kalshi Developer Agreement v1.1 — Kalshi, read
- Share and Embed — Dune, read
- Pricing (Pro tier, public chart branding) — Lychee, read
- Content-Security-Policy: frame-src directive — MDN Web Docs, read
The catalogue next door
This page names a handful of cards. The rest of them are in Prediction Market Analytics & Dashboards, each filled in against the same schema, with the fields to narrow it yourself.
Last updated . Corrected in place: this is a reference page, not a dated post.