Fresh row
Quote age is inside the alert threshold, spread percent is acceptable, and the row can trigger user-facing alerts.
State: fresh
A real-time workflow for initializing option dashboard rows with REST, keeping them fresh with WebSockets, backfilling missed quote windows, and explaining every alert.
Initialize rows with expirations, chain data, and contract snapshots; subscribe to quote and trade WebSocket messages; mark stale rows; backfill after reconnects; and include bid/ask, quote age, spread percent, Greeks, and reject reasons in each alert.
Initialization
REST first
Use expirations, chains, and snapshots to build stable rows before streaming updates arrive.
Live updates
WebSockets
Subscribe to quote and trade channels for exact OCC tickers that are visible or alert-eligible.
Reliability
Backfill
Use REST quote history after reconnects so alerts do not depend on a perfect stream.
State model
Start with Expirations, Options Chain API, and Option Contract Snapshot data so every row has a stable identity before live messages arrive. The row key should be the exact OCC ticker, not a display label assembled from strike and expiration text.
The initialized row should include underlying, expiration, strike, call/put side, DTE, moneyness, open interest, day volume, bid, ask, midpoint, implied volatility, Greeks, last trade, and snapshot timestamp. That lets the UI show useful context immediately and update the quote or trade fields independently.
Streaming
Use WebSockets for quote and trade updates, then keep Market Data Access Methods in mind for reconnect and REST backfill behavior. A stream update should patch the row, recalculate spread percent and quote age, and update freshness labels without losing the static contract metadata.
For alerting, combine quote freshness, spread percent, volume/open-interest pressure, trade condition, moneyness, and Greeks in the condition itself. A dashboard that says why an alert fired is more useful than a dashboard that only flashes a contract ticker.
Quote age is inside the alert threshold, spread percent is acceptable, and the row can trigger user-facing alerts.
State: fresh
No quote update arrived within the threshold, so the row remains visible but cannot trigger fresh-price alerts.
State: stale
The contract failed a no-bid, wide-spread, entitlement, or missing-data rule and should show a reject reason.
State: rejected
Operations
When the WebSocket reconnects, request Quotes for the missed window and apply the same freshness and spread checks used by live messages. This prevents duplicate alerts, missed exits, and false positives caused by a temporary network gap.
Each alert should store the OCC ticker, trigger timestamp, bid, ask, midpoint, spread percent, quote age, latest trade, volume, open interest, Greeks, alert rule, backfill status, entitlement state, and reject reason. That record turns a live dashboard into a reviewable research and operations system.
Implementation detail
Treat this page as an implementation boundary, more than a short answer. For How to Build Options Alerts and Dashboards, the practical record should include the request inputs, timestamp context, selected object, freshness state, and the reason a row was accepted or rejected. That is what keeps a concise answer usable when it becomes a scanner, dashboard, backtest, alert, or support note.
The core page facts are Initialization: REST first; Live updates: WebSockets; Reliability: Backfill. Those values should map to fields in code or to visible labels in the interface. If a developer cannot point to the endpoint family, market-data object, date window, entitlement state, or review artifact behind the answer, the workflow is still too vague for production use.
A reliable implementation should store source URLs or endpoint paths, query parameters, pagination state, market timestamps, application timestamps, and any reject reason beside the result. That evidence makes it possible to rerun the answer later, compare it with another provider, and explain why a value changed after a calendar update, feed repair, plan change, or data-quality review.
In the checklist, the handoff starts with Create the row universe and ends with Persist alert evidence. Keep those steps connected with stable identifiers rather than display labels, especially when the workflow moves from stocks into options, from chains into exact contracts, or from current snapshots into historical replay.
A reliable dashboard keeps static contract identity, live market updates, and backfill evidence separate.
| Phase | Data source | Dashboard behavior |
|---|---|---|
| Initialize | Expirations, chain, snapshot | Create rows with stable OCC tickers, DTE, moneyness, Greeks, IV, open interest, and latest quote context. |
| Stream | WebSocket quotes and trades | Patch bid, ask, last trade, size, timestamp, quote age, spread percent, and freshness labels. |
| Alert | Rule engine | Trigger only when quote quality, liquidity, moneyness, Greeks, and user thresholds all pass. |
| Recover | REST quote backfill | After reconnects, fill missed quote windows and prevent duplicate or stale alerts. |
| Review | Alert evidence store | Persist trigger timestamp, row state, fill context, rule version, and reject reason. |
API example
dashboard REST initialization and backfill
# Initialize the dashboard with REST so every row has contract metadata.
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.cutemarkets.com/v1/options/chain/QQQ/?expiration_date=2026-05-15&limit=250"
# Backfill the active alert window after reconnects or missed WebSocket messages.
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.cutemarkets.com/v1/options/quotes/O:QQQ260515C00450000/?timestamp.gte=2026-05-01T13:30:00Z×tamp.lt=2026-05-01T13:45:00Z"
# Drill into one contract when a user opens a dashboard row.
curl -H "Authorization: Bearer YOUR_API_KEY" "https://api.cutemarkets.com/v1/options/snapshot/QQQ/O:QQQ260515C00450000/"WebSocket subscription and stale-row handling
const API_KEY = process.env.CUTEMARKETS_API_KEY;
const state = new Map();
function markRow(ticker, patch) {
const previous = state.get(ticker) || {};
const next = { ...previous, ...patch, updatedAt: Date.now() };
const quote = next.quote || {};
const bid = Number(quote.bid_price || 0);
const ask = Number(quote.ask_price || 0);
const mid = bid > 0 && ask >= bid ? (bid + ask) / 2 : 0;
next.spreadPct = mid > 0 ? (ask - bid) / mid : Infinity;
next.freshness = Date.now() - next.updatedAt > 15000 ? "stale" : "fresh";
state.set(ticker, next);
}
function subscribe(tickers) {
const ws = new WebSocket("wss://api.cutemarkets.com/v1/ws/options/?apiKey=" + encodeURIComponent(API_KEY));
ws.addEventListener("open", () => {
for (const ticker of tickers) {
ws.send(JSON.stringify({ action: "subscribe", params: "Q." + ticker }));
ws.send(JSON.stringify({ action: "subscribe", params: "T." + ticker }));
}
});
ws.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
if (message.ev === "Q") markRow(message.sym, { quote: message });
if (message.ev === "T") markRow(message.sym, { trade: message });
});
ws.addEventListener("close", () => {
setTimeout(() => backfillAndReconnect(tickers), 1000);
});
}
async function backfillAndReconnect(tickers) {
for (const ticker of tickers) {
await fetch("/api/options/backfill-quotes?ticker=" + encodeURIComponent(ticker));
}
subscribe(tickers);
}How to implement
Load listed expirations, chain rows, and contract snapshots so each dashboard row has a stable OCC ticker and metadata.
Open WebSocket subscriptions for quote and trade updates on visible, watchlisted, or alert-eligible contracts.
Update bid, ask, last trade, quote age, spread percent, freshness, and alert eligibility every time a message arrives.
On reconnect, request quote history for the missed interval before resuming alert evaluation.
Store the trigger rule, quote evidence, trade context, row state, entitlement status, and reject reason for later review.
Last verified
This guide was last reviewed on June 4, 2026. Date-sensitive market calendars, provider docs, and listed contracts can change, so production workflows should verify the live source before trading or publishing an automated answer.
No. Use REST for initialization and backfill, then WebSockets for low-latency quote and trade updates.
Keep the row visible but mark it stale and suppress fresh-price alerts until a new quote or validated backfill arrives.
Store the OCC ticker, trigger timestamp, bid, ask, spread percent, quote age, latest trade, volume, open interest, Greeks, rule version, and reject reason.
Operational usage
Treat this page as a decision boundary for the surrounding API workflow. Before a value from How to Build Options Alerts and Dashboardsenters a scanner, dashboard, calendar, backtest, or support answer, store the source route, request parameters, relevant timestamp, freshness label, and the reason the value is suitable for the next step.
The important implementation habit is to keep display labels separate from stable identifiers. Dates should remain tied to the calendar rule or listed-expiration source that produced them. Option rows should keep the OCC symbol, expiration, strike, side, quote state, and pagination context that created the row. Provider or product answers should keep the entitlement, licensing, and support assumptions visible.
When the workflow changes, rerun the page against one concrete example instead of trusting a general claim. Pick the ticker, date window, endpoint family, and expected output artifact. Then verify that the same terminology appears in the API request, UI label, log entry, and review checklist.
Related pages
Real-time options data API
Use live data and streaming updates for options dashboards.
WebSockets
Review the WebSocket subscription model for live market-data updates.
Live and delayed entitlements
Handle live, delayed, and quote-access states in production dashboards.
Real-time options system design
Plan ingestion, state, backfill, and alerting for real-time options systems.