A screener is one question asked of every ticker at once. That’s exactly the shape of the Tickerbot table — every ticker × every signal, precomputed — so the screener you’d otherwise assemble from a feed, a warehouse, and indicator math becomes a single SQL call. The UI on top is the only part left to build.
Free plan. Every ticker, every signal, real-time data, all-time history.
the recipe
1. Write the screen — a SQL WHERE clause over 421+ named signals and fundamentals. Sort, cap, and choose the columns your UI shows — the whole market is evaluated server-side:
curl -s -X POST https://api.tickerbot.io/v2/scan \
-H "Authorization: Bearer $TICKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "q": "above_sma_200 AND pe_ratio < 20 AND market_cap > 1e9",
"order": "market_cap", "dir": "desc", "limit": 50,
"columns": "ticker,price,pe_ratio,market_cap,rsi_14" }'2. Screen the past — the same call with ?asof= answers as of any past moment — the market as it was, delisted tickers included. A “what would this screen have shown last January” feature is one query parameter:
curl -s -X POST "https://api.tickerbot.io/v2/scan?asof=2026-01-15" \
-H "Authorization: Bearer $TICKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "q": "above_sma_200 AND pe_ratio < 20 AND market_cap > 1e9" }'3. Make it push — subscribe the same q and the screener stops being something users refresh — it tells them when the answer changes:
curl -s -X POST https://api.tickerbot.io/v2/scan/subscribe \
-H "Authorization: Bearer $TICKERBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "q": "above_sma_200 AND pe_ratio < 20 AND market_cap > 1e9",
"target_url": "https://your-app.example.com/hook" }'4. Render it — the response rows are already UI-shaped — the columns you asked for, in the order you asked for them. No client-side math:
const res = await fetch('https://api.tickerbot.io/v2/scan', {
method: 'POST',
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ q: userQuery, order: sortCol, dir: sortDir, limit: 50 }),
})
const { results } = await res.json()
// results: [ { ticker: "AAPL", price: 231.4, pe_ratio: 18.2, ... }, ... ]
table.render(results) // rows in, rows out — the "screener" part is doneunder the hood
POST /v2/scan | The screen itself — q, order, dir, limit, columns; live or ?asof= |
POST /v2/scan/subscribe | The same screen as a push — fires when the match set changes |
GET /v2/tickers/{ticker} | The detail view — everything about one ticker in one row |
POST /v2/universes | Saved ticker lists — scope any screen with universe= |
Every read runs in three tenses: live, as of any past moment (add ?asof= — no survivorship bias), or on push — the same query as a webhook that fires when the answer changes. Under all of it sits the computed table: every US equity plus rates, FX and crypto, every signal precomputed and refreshed continuously, with all-time history. That pipeline — warehouse, indicator math, refresh, point-in-time storage — is the part you’d otherwise build before writing your first line of product. Buy it as a table instead — data included; there’s no feed to bring.
questions
Every column in the schema: 421+ precomputed signals (trend, momentum, volume, volatility), fundamentals, and identity fields — plus custom signals you define once and reference by name in any screen.
Screens are just strings — store the q per user and replay it. For watchlists, create a universe per user and scope any screen with universe=; the same universe works on scans, series, events, and webhooks.
Because every action it takes — an alert, a screen result, an order, a row in a user-facing app — is a condition over derived values: RSI below 30, price above the 200-day average, volume three times normal. Raw data doesn’t contain those. Something has to compute and refresh them for every symbol, continuously, and keep the history so past answers are reproducible. That’s a data pipeline, not a feature — you either build and operate it, or query one that already runs.
Every call here is also a native tool call: install the MCP server and Claude, ChatGPT, Cursor, or any MCP runtime queries the market directly. Computed state is what makes that work well — hand a model raw data and its context window fills with math to do; hand it computed answers and the context goes to decisions. A scan returns the tickers matching your condition — a list, not a workload.
The Free plan needs no card and carries the full data side: every ticker, every signal, real-time data, all-time history and as-of queries. Paid plans start at $29/mo and add real-time webhooks, websocket streaming, and higher rate limits. Data depth is never a tier lever — every plan sees the same table.
in the wild
What people are saying.
“dude. whoah.”
“Tickerbot is insane. It turns Claude into a quant.”
“Best value for hobbyists and advanced traders alike.”
get started
Free plan. Every ticker, every signal, real-time data, all-time history.