Home / Blog / Use Cases

Use Cases

Build a Copy-Trading Thesis Bot That Reacts Faster Than the FOMO App

A step-by-step build for a copy-trading bot that listens to our live WebSocket for a followed trader’s buy and thesis, checks the written reasoning, resolves the trader’s real wallet, and acts faster than a human refreshing the FOMO app.

A copy-trading bot is only as good as its reaction time and its judgment. Most people try to copy traders by watching a feed in the FOMO app and clicking when they see something move. By the time a human notices a trade on screen, opens a chart, and decides, the entry is already gone. A bot removes the lag. It also removes the guesswork, because it can read the same thing a careful human would read before copying: the trader's written thesis.

This tutorial shows how to build a copy-trading thesis bot on top of our API and WebSocket feed. We provide the data. You run the bot. Nothing here mirrors trades blindly. The whole point is to copy with a reason attached.

Why a Human Refreshing the App Is Always Late

The FOMO app shows trades after they happen. A person scrolling it is polling by hand, on their own schedule, with a screen in between them and the data. That gap is where the entry price drifts.

A bot wired to a live feed does not poll. It holds an open connection and gets pushed the event the moment it lands. In our own capture the trade and thesis events arrive sub-second from when they occur on chain. That is the difference between reacting to a move and reading about it later.

The feed to connect to is:

wss://api.fomoapi.io/ws/alerts

It streams trade events, thesis events, and large-buy and large-sell events as they happen. If your bot restarts or you miss a window, you backfill with a plain request:

curl "https://api.fomoapi.io/v2/alerts?limit=50" \
  -H "x-api-key: YOUR_KEY"

Use the WebSocket for live reaction and /v2/alerts for catch-up. Together they mean the bot never has a blind spot.

The Thesis Is the Real Signal

A price feed alone tells you what happened. It does not tell you why. On the FOMO app a trader can attach a written thesis to a trade, which is the reasoning behind it. That text is the differentiator for a copy bot, because it lets the bot decide whether a given buy is worth following or worth skipping.

Three endpoints expose thesis data.

The recent thesis feed, for a running view of what traders are writing:

curl "https://api.fomoapi.io/v2/thesis?limit=20" \
  -H "x-api-key: YOUR_KEY"

Every thesis on a single coin, keyed by mint, for when you want to see the full case around a token:

curl "https://api.fomoapi.io/v2/thesis/token/So11111111111111111111111111111111111111112" \
  -H "x-api-key: YOUR_KEY"

And a single trader's reasoning history, so you can judge whether their theses tend to hold up:

curl "https://api.fomoapi.io/v2/thesis/user/kolwhale" \
  -H "x-api-key: YOUR_KEY"

A thesis response carries the trader, the mint, the trade it is attached to, the written text, and a timestamp:

{
  "user": "kolwhale",
  "mint": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PB7bd",
  "side": "buy",
  "thesis": "adding here, holders up 3x in an hour and the deployer is doxxed",
  "created_at": "2026-08-28T14:02:11Z"
}

That text field is what your bot reads before it acts.

Resolve the Trader Behind the Handle

Before you follow anyone you need to know who they actually are on chain. Our user endpoint takes a handle and returns the trader's resolved wallets across Solana and EVM, plus their stats:

curl "https://api.fomoapi.io/v2/users/kolwhale" \
  -H "x-api-key: YOUR_KEY"
{
  "handle": "kolwhale",
  "wallets": {
    "solana": "7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2",
    "evm": "0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE"
  },
  "stats": {
    "trades_30d": 214,
    "realized_pnl_usd": 48210
  }
}

For sizing and history you have two more calls. Trade history:

curl "https://api.fomoapi.io/v2/users/kolwhale/trades?limit=50" \
  -H "x-api-key: YOUR_KEY"

And current holdings, so your bot can size its own copy against what the trader is actually holding rather than guessing:

curl "https://api.fomoapi.io/v2/users/kolwhale/balances" \
  -H "x-api-key: YOUR_KEY"

Wiring It Together

Here is a working WebSocket client that follows one trader, waits for a buy with a thesis attached, checks the thesis text, and then acts. The trade execution is left as a function you fill in with your own broker or on-chain logic, because that part is yours, not ours.

import WebSocket from 'ws';

const API_KEY = process.env.FOMOAPI_KEY;
const FOLLOW = 'kolwhale';

// words that make you skip a copy even if the trader bought
const RED_FLAGS = ['exit', 'trimming', 'derisk', 'not financial advice test'];

function passesThesisCheck(text) {
  if (!text || text.length < 12) return false;
  const lower = text.toLowerCase();
  return !RED_FLAGS.some(flag => lower.includes(flag));
}

async function executeCopy(mint, trader, thesis) {
  // your own execution goes here: quote, size against holdings, place the buy
  console.log('copying', trader, 'into', mint, 'because:', thesis);
}

const ws = new WebSocket('wss://api.fomoapi.io/ws/alerts', {
  headers: { 'x-api-key': API_KEY }
});

ws.on('open', () => {
  ws.send(JSON.stringify({ action: 'subscribe', users: [FOLLOW] }));
});

ws.on('message', raw => {
  const event = JSON.parse(raw);
  if (event.type !== 'thesis') return;
  if (event.user !== FOLLOW) return;
  if (event.side !== 'buy') return;

  if (passesThesisCheck(event.thesis)) {
    executeCopy(event.mint, event.user, event.thesis);
  } else {
    console.log('skipped', event.mint, 'thesis did not pass');
  }
});

ws.on('close', () => {
  // reconnect so the bot never sits with a dead connection
  setTimeout(() => process.exit(1), 1000);
});

The logic is deliberately plain. The bot only fires on a buy from the followed trader that carries a thesis, and only when that thesis clears a check you control. A trade event with no thesis, or a thesis that reads like an exit, gets skipped. That is judgment, and it is the reason to build on thesis data instead of raw fills.

Extending the Bot

Once the skeleton runs, the same data supports more selective rules. You can pull the trader's recent thesis history from /v2/thesis/user/{id} and only copy when their current reasoning is consistent with a run of theses that worked out. You can read /v2/thesis/token/{mint} to see whether several tracked traders are writing bullish theses on the same coin at once, and weight the copy accordingly. You can watch the large-buy events on the WebSocket to catch size moving before the smaller follow-on trades appear. And you can size each copy against the holdings returned by /v2/users/{handle}/balances so you are never copying a rounding-error position as if it were a conviction bet.

None of this requires us to run anything for you. You hold the connection, you read the thesis, you decide, and you place the trade. We keep the data flowing in real time with the written reasoning attached, which is the part a human refreshing an app can never keep up with.

A note on scope. This is a build guide using our data, not a trading service and not investment advice. fomoapi.io is an independent project and is not affiliated with the FOMO app. What we sell is verified social-trading data. What you do with it is your bot.

Ship on verified trader data

Both-chain wallets, real PnL, and a realtime feed. One API.

Get an API key

FAQ

What makes a thesis bot different from blindly mirroring trades?
It reads the written thesis a trader attaches to a trade before copying. The bot only acts on a buy whose reasoning clears a check you control, so it copies with judgment instead of mirroring every fill. Thesis data comes from /v2/thesis, /v2/thesis/token/{mint}, and /v2/thesis/user/{id}.
How does the bot react faster than a person using the FOMO app?
A human polls the app by hand and sees trades after the fact. The bot holds an open connection to wss://api.fomoapi.io/ws/alerts and is pushed trade, thesis, and large-buy events the moment they land. In our capture those events arrive sub-second, and GET /v2/alerts backfills anything missed during a restart.
How do I know which wallet a followed trader is actually trading from?
Call /v2/users/{handle} to get the trader’s resolved on-chain wallets across Solana and EVM plus their stats. Use /v2/users/{handle}/trades for history and /v2/users/{handle}/balances for current holdings so the bot can size each copy against what the trader really holds.