View as markdown

Alert bot

Tickerbot is the stock market, in SQL. A stock alert is one WHERE clause on it, subscribed.

Every alert bot has two halves: watching the market, and saying something when a condition trips. Both are built into Tickerbot — write the condition in SQL, point the delivery at your own handler or Discord.

1. Test the condition

Run it as a scan first — same grammar the alert will use — to see who matches right now.

curl -X POST "https://api.tickerbot.io/v2/scan" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "q": "volume_burst_3x AND day_change_pct > 0.05 AND market_cap > 1e9" }'
Response
{
  "as_of": "2026-08-21T11:22:41Z",
  "count": 2,
  "results": [
    { "ticker": "BEKE", "name": "KE Holdings Inc. American Depositary Shares…",
      "price": 18.03, "day_change_pct": 0.0612, "relative_volume": 0.102, … },
    { "ticker": "CRCL", "name": "Circle Internet Group, Inc.",
      "price": 88.19, "day_change_pct": 0.0541, "relative_volume": 0.2111, … }
  ]
}

2. Subscribe it

The same q becomes a webhook: evaluated continuously, POSTed to your endpoint when tickers enter or leave the match set.

curl -X POST "https://api.tickerbot.io/v2/scan/subscribe" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "q": "volume_burst_3x AND day_change_pct > 0.05 AND market_cap > 1e9",
        "target_url": "https://your-bot.example.com/hook" }'
Response
{
  "id": "wh_fqqgu9F7bXI",
  "q": "volume_burst_3x AND day_change_pct > 0.05 AND market_cap > 1e9",
  "channel": "webhook",
  "target_url": "https://your-bot.example.com/hook",
  "signing_secret": "whsec_…",
  "status": "active",
  …
}

Four delivery channels per subscription: webhook, discord (pass discord_url instead and a formatted embed posts straight to your channel — zero code, zero hosting), in_app, mobile_push.

3. Receive the delivery

Your bot is a webhook receiver, and the delivery is the contract: matches are the tickers that just tripped the condition, current_matches is everything matching now. Parse, say something, ack 200.

import express from 'express'
const app = express()
app.use(express.json())

app.post('/hook', (req, res) => {
  for (const row of req.body.matches) {
    const alert = `${row.ticker} up ${(row.day_change_pct * 100).toFixed(1)}% at ${row.price}`
    console.log(alert)   // …or ping Slack, send an email, place a trade
  }
  res.sendStatus(200)
})

app.listen(3000)   // the server behind your target_url

The calls behind it

  • POST /v2/scanTest the condition: same grammar the alert will use, evaluated right now
  • POST /v2/scan/subscribeAny SQL condition as an alert: fires when the match set changes

All build guides