Build on FOMO without talking to FOMO.
This service wraps fomo.family as a public REST API plus one watch WebSocket. Tokens, traders, clans, leaderboards, OHLCV, and live sells — no Privy token in your app, and no browser socket to prod-api.
https://fomo.1sav.xyz
· private service
Server holds the session
It authenticates to FOMO with a server-side Privy session and auto-refresh. The service is access controlled.
Same paths, two prefixes
Every route is mounted at / and at /api/fomo-scanner for the Chain Tools scanner.
Mostly read, one write
No swaps, sends, or follows. Theses can be posted as the server session user on that user’s FOMO trades. Watch list changes stay local to this service.
Do not use fomoapi.io
Do not open FOMO’s own WebSocket from a browser. Use wss://fomo.1sav.xyz/watch/ws instead.
Quickstart
Private integrations receive { "success": true, "data": … }. Failures use HTTP status plus { "detail": "…" }.
curl -sS "https://fomo.1sav.xyz/status" curl -sS "https://fomo.1sav.xyz/tokens?kind=trending" curl -sS "https://fomo.1sav.xyz/tokens/search?q=SOL" curl -sS "https://fomo.1sav.xyz/users/handle/alice"
const API = "https://fomo.1sav.xyz";
const res = await fetch(`${API}/tokens?kind=trending`);
const { success, data } = await res.json();
if (!success) throw new Error("FOMO API error");
// Scanner-compatible prefix also works:
await fetch(`${API}/api/fomo-scanner/me`);
import requests
API = "https://fomo.1sav.xyz"
status = requests.get(f"{API}/status").json()
tokens = requests.get(f"{API}/tokens", params={"kind": "trending"}).json()["data"]
user = requests.get(f"{API}/users/handle/alice").json()["data"]
Conventions
Chains
Token routes take a chain slug or numeric id. GET /status returns the live map.
| Slug | Network id |
|---|---|
solana | 1399811149 |
base | 8453 |
bnb | 56 |
monad | 143 |
robinhood | 4663 |
ethereum | 1 |
hyperliquid | 1337 |
Pagination
List endpoints that accept last_id, last_trade_id, or last_comment_id are cursor-style. Pass the last item’s id from the previous page.
CORS
Browser apps must be listed in this service’s CORS_ORIGINS. Same-origin calls from this docs page always work. Server-side callers have no CORS constraint.
Limits you will hit
- Watch: max 25 accounts and 15 tokens on this process.
- Referrals and referrer details only return for the logged-in session user.
- Upstream FOMO / Cloudflare can return 403/502/504; this API forwards a useful
detail.
Recipes
1. Resolve a token, then load the page
GET /tokens/search?q=SOL GET /tokens/lookup?q=So11111111111111111111111111111111111111112 GET /tokens/solana/So11111111111111111111111111111111111111112 GET /tokens/solana/So11111111111111111111111111111111111111112/warnings GET /tokens/solana/So11111111111111111111111111111111111111112/holders
Search matches a phrase. Lookup is for a mint / contract. Details, warnings, holders, devs, friends, feed, and bars all use /tokens/{chain}/{address}.
2. Chart a token
GET /tokens/solana/So11111111111111111111111111111111111111112/bars?resolution=60&count_back=300
resolution is TradingView-style minutes (1, 5, 15, 60, 240, 1D). The service turns address + chain into FOMO’s address:networkId symbol.
3. Profile a trader
GET /users/search?q=alice
GET /users/handle/alice
GET /users/{userId}/trades
GET /users/{userId}/pnl?window=7d
GET /users/{userId}/rank
GET /users/{userId}/balances
4. Stream theses
const ws = new WebSocket("wss://fomo.1sav.xyz/watch/ws");
ws.onopen = () => {
ws.send(JSON.stringify({
action: "add",
handle: "alice",
watchTheses: true,
}));
ws.send(JSON.stringify({ action: "start" }));
};
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === "event" && !msg.backfill) console.log(msg.kind, msg.handle, msg.token);
};
5. Post a thesis as the session user
GET /me
GET /users/{myUserId}/trades?token_address=DezX…
POST /trades/{tradeId}/thesis
{ "comment": "still early" }
# or let the service find your newest trade on that mint:
POST /thesis
{ "tokenAddress": "DezX…", "comment": "still early" }
A thesis is a comment on a FOMO trade UUID owned by the logged-in session. Transfers / “Received” fills often have no trade id — you need a FOMO-indexed buy or sell first. Posts as whoever GET /me returns.
Reference
Every path below is also available under /api/fomo-scanner.
Session
Session health, expiry, auto-refresh flag, and chain map. No FOMO call — safe for probes and Docker healthchecks.
{
"success": true,
"data": {
"configured": true,
"expired": false,
"seconds_left": 2800,
"can_refresh": true,
"auto_refresh": true,
"api_base": "https://prod-api.fomo.family"
},
"chains": { "solana": 1399811149, "base": 8453 }
}
Force a Privy token refresh. Usually unnecessary — the client refreshes ~2 minutes before expiry.
Logged-in viewer. Optional ?handle= or ?user_id= loads that public profile instead.
Tokens
Discovery lists. Query kind:
| kind | Meaning |
|---|---|
trending | Default. Hot tokens. |
most-held | Most held by FOMO users. |
graduated | Recently graduated. |
crypto-tokens | Majors / crypto tokens feed. |
verified | Verified on FOMO. |
Fuzzy search by name or ticker. q is required.
{
"success": true,
"data": [{
"priceUSD": "105.70",
"marketCap": "60108380023",
"volume24": "123945148",
"token": {
"address": "So11111111111111111111111111111111111111112",
"networkId": 1399811149,
"symbol": "SOL",
"name": "Solana"
}
}]
}
Exact-ish lookup by mint / contract in q.
Token page payload (price, mcap, metadata, socials, launchpad).
Risk / warning flags for the mint.
Top holders.
Dev-linked holders.
Holders you follow. Query limit (default 50).
Token activity feed. Query thesis_only (bool), last_id, min_usd.
OHLCV. Query resolution (default 60), count_back (default 300).
Users & social
Fuzzy user search.
Public profile by @handle (with or without @). solanaAddress / evmAddress are the wallets from on-chain balance matching (address is the same Solana wallet). Query refresh_wallets=true to re-fingerprint. identityAddress / identityEvmAddress are FOMO’s Privy keys. tradingAddress / tradingEvmAddress are trade userAddress values (often a router with no bags).
Public profile by UUID. Same wallet fields as /users/handle/{handle}.
Followers. Query last_id.
Following. Query last_id.
Mutuals. Query last_id.
Recommended users.
Trade history. Query token_address, last_trade_id, order_by (default closedAt).
PnL leaderboard. Query window (all-time, 24h, 7d, 30d; aliases 1d, day, week, month) and limit (default 50).
Leaderboard of accounts the session follows.
Clan board. Query window (default 1d).
Single trade.
Trade comments / thesis thread. Query last_comment_id.
Post a thesis on that trade as the server session user. Body:
{
"comment": "still early",
"visibility": "public"
}
comment (or thesis) is required, max 800 characters. The trade must belong to the session account.
Same write, with optional trade lookup. Pass either tradeId or tokenAddress (aliases token_address, address). Optional orderBy defaults to openedAt.
{
"tokenAddress": "DezX…",
"comment": "still early",
"visibility": "public"
}
Account (FOMO-backed)
These read FOMO as the configured session. Some fields are public; referrals are session-only.
Wallet / token balances as FOMO reports them (not the on-chain owner).
Resolved holding wallets plus identity / trade addresses. First lookup fingerprints on-chain and writes .fomo_wallets.json; later lookups reuse that row. Query refresh_wallets=true to scan again.
Force a new on-chain fingerprint and overwrite the stored wallets for that profile.
Leaderboard rank for that user.
Spotlight cards.
Aggregated PnL snapshot. Query window: 1d (default), 7d, 30d, all.
Session user only. Query last_id, limit (default 25).
Session user only.
Query chain (default solana).
Transfers with that user. Query last_id.
IDs the session currently follows.
FOMO’s own token watchlist (not this service’s account watcher).
Push notification preferences for the session.
Watch WebSocket
This service polls FOMO REST (and a small market socket) and fans events out to your clients.
Connect to wss://fomo.1sav.xyz/watch/ws (or ws://127.0.0.1:8990/watch/ws locally).
The same commands work over HTTP if you do not want a socket.
Current accounts, tokens, platform flags, running state, and upstream WS health.
Replace the account list. Body: { "accounts": [{ "handle": "alice", "watchTheses": true }] }.
One JSON action (same shape as a WS message). Returns { "success": true, "data": { "type": "…", … } }.
Send JSON actions. Receive snapshots and events. After start, recent events are replayed.
Actions you send
| action | Body |
|---|---|
start | Begin polling. Replays recent events on the socket. |
stop | Stop polling and close the command loop on WS. |
add |
handle or userId. Optional watchTheses (default true). |
remove | userId |
addToken |
chain, address. Optional watchTheses (default true). |
removeToken | tokenKey — address:networkId |
platform |
watchVerified, watchGraduated, watchPreGraduated |
Messages you receive
| type | When |
|---|---|
watchlist / ready | Snapshot after start or a list change. |
added / removed | Account add/remove plus snapshot. |
addedToken / removedToken | Token add/remove plus snapshot. |
stopped | Watcher stopped. |
error | { "type": "error", "message": "…" } |
event | A normalized activity row (see below). |
{
"type": "event",
"kind": "thesis",
"source": "rest",
"userId": "…",
"handle": "alice",
"token": "BONK",
"address": "DezX…",
"chain": "solana",
"usd": 420.5,
"thesis": "still early",
"tradeId": "…",
"fillId": "",
"ts": "2026-04-12T16:01:00Z",
"backfill": false
}
Account and token kind values on this socket are thesis, plus platform kinds verified, graduated, and pre_graduated. Buys, sells, and receives are not forwarded. Token-scoped events set scope: "token" and tokenKey. backfill: true means historical seed, not a live tick. Ignore backfill if you only want new activity.
Errors
| Status | Typical cause |
|---|---|
| 400 | Unknown chain, unknown token list kind, bad watch action, or empty / oversized thesis. |
| 401 | FOMO session rejected / expired and refresh failed. |
| 403 | FOMO forbade the resource (e.g. another user’s referrals) or Cloudflare blocked the upstream hop. |
| 404 | User, token, or session trade for thesis not found. |
| 502 / 504 | Upstream FOMO timed out or returned non-JSON. |
| 503 | No Privy token configured on the server. |
{ "detail": "Unknown chain 'aptos'" }