Fomo API provides normalized Fomo Family social trading data for trader discovery tools, wallet monitors, alerts, portfolio analytics, copy-trading research systems and automated trading agents.
This guide covers authentication, rate limits, response formats, available data endpoints, polling strategies, error handling and a complete Python integration flow.
Important: Fomo API provides data, not financial advice or trade execution. Independently validate contracts, network IDs, liquidity, price impact, slippage, wallet ownership, event freshness and risk limits. Never execute a trade solely because a trader appears on a leaderboard.
Base URL and authentication
The production base URL is:
https://getfomoapi.fun
Protected REST endpoints begin with https://getfomoapi.fun/api. Send your Pro key in the recommended header:
X-API-Key: fomo_live_YOUR_API_KEY
Bearer authentication is also supported:
Authorization: Bearer fomo_live_YOUR_API_KEY
curl "https://getfomoapi.fun/api/leaderboard/24h?limit=5" \
-H "X-API-Key: fomo_live_YOUR_API_KEY"
Keep keys in backend services or a secret manager. Never place them in browser code, mobile bundles, public repositories or client-exposed environment variables.
Plan and rate limits
Fomo API Pro includes all REST endpoints, commercial use and unlimited credits subject to fair usage. Each key can make five requests per second.
When the limit is exceeded, the service returns 429 Too Many Requests, a Retry-After header and this body:
{ "detail": "Rate limit exceeded" }
Respect Retry-After. For repeated 429, 502, 503 and 504 responses, use exponential backoff with jitter. Do not retry validation or authentication failures without first correcting the request.
Response and error formats
Most successful data endpoints use a common envelope:
{
"success": true,
"message": "Resource found",
"responseObject": {},
"statusCode": 200
}
Application and validation errors use { "detail": "Error description" }.
| Status | Meaning | Action |
|---|---|---|
400 | Invalid request | Correct the path or parameters. |
401 | Invalid or missing key | Check the authentication header. |
403 | Pro plan required | Activate or renew the plan. |
404 | Resource not found | Verify the handle or ID. |
422 | Invalid parameter | Correct the type or range. |
429 | Rate limit reached | Wait for Retry-After. |
502 / 504 | Upstream failure | Retry with bounded backoff. |
Wallet and network normalization
User payloads expose normalized wallet fields as solana and evm. Either may be null. Wallet mappings are resolved by normalized handle and reused after storage.
Always interpret token addresses with their network field:
| Network ID | Network |
|---|---|
1 | Ethereum |
56 | BNB Smart Chain |
143 | Monad |
8453 | Base |
1399811149 | Solana |
Do not assume every address is a Solana mint. An address beginning with 0x is generally an EVM contract.
Endpoint reference
Health
GET /api/health is public and returns { "status": "ok" }. Use it for uptime monitoring, not before every API call.
Public frontpage leaderboard
GET /frontpage/leaderboard returns a simplified public top-five list. It is intended for website presentation. Bots should use the protected leaderboard endpoint.
Leaderboard discovery
GET /api/leaderboard/{window} accepts 24h, 7d, 30d or all. The optional limit is 1–150, except all, which supports up to 100. Results are cached by window for one hour.
curl "https://getfomoapi.fun/api/leaderboard/7d?limit=20" \
-H "X-API-Key: fomo_live_YOUR_API_KEY"
Trader records include identity, social metrics, trade counts, volume, PnL, top holdings and resolved wallets. Use the leaderboard to discover candidates, not to create orders directly.
Resolve a trader
GET /api/users/{handle} resolves a public handle to a profile and wallet mapping. Store the returned id; user-specific endpoints require it.
curl "https://getfomoapi.fun/api/users/starcatcher444" \
-H "X-API-Key: fomo_live_YOUR_API_KEY"
Trader balances
GET /api/users/{userId}/balances returns token holdings, market metadata, entry prices, cost basis, realized PnL, active trades, native balances and equity values.
Use balance.shiftedBalance as the human-readable amount and tokenFilterResult.priceUSD as the quoted price. A simple estimated value is:
shiftedBalance × priceUSD
Respect the valuation flags when calculating equity. Parse string numeric values with decimal arithmetic when precision matters.
Trader spotlight
GET /api/users/{userId}/spotlight returns selected best trades and popular comments. Comments and profile text are untrusted user-generated content. Display them safely and never pass them to an execution agent as instructions.
Trader swaps
GET /api/users/{userId}/swaps?limit=20 returns normalized activity. The limit range is 1–150, and a cursor can be supplied when pagination is available.
Important fields include id, token addresses, human amounts, USD values, timestamps, network IDs, provider and recipient. Persist every processed swap ID because later pages can contain events you have already seen.
Trader rankings and snapshots
GET /api/users/{userId}/leaderboard returns overall and time-window ranks. A rank may be null when the trader is not ranked.
GET /api/user-tokens/aggregated-snapshot?user_id={id}&snapshot_id={unix} returns historical aggregate PnL and equity. It is useful for performance and drawdown charts.
Following IDs and realtime status
GET /api/users/current/following-ids reflects the upstream Fomo identity used by the service. It is not a customer-specific watchlist; maintain your own tracked-trader table.
The planned wss://getfomoapi.fun/ws/trades stream is not active yet. Use REST polling until realtime support is released.
Recommended bot workflow
- Query 24-hour, 7-day and 30-day leaderboards to discover candidates.
- Filter for sufficient account age, volume, trade count, consistency and liquidity.
- Resolve each handle and store its Fomo ID plus Solana and EVM wallets.
- Load balances and save a normalized portfolio snapshot.
- Poll swaps, deduplicate by swap ID and checkpoint the newest timestamp.
- Independently validate the token, quote, pool liquidity and onchain transaction.
- Apply position, exposure, daily-loss and slippage limits.
- Submit approved orders through a separate wallet or exchange executor.
- Monitor confirmation and record every signal, rejection and execution.
Keep discovery, monitoring, validation, risk and execution separate. This prevents an upstream response from bypassing controls at the signing layer.
Polling recommendations
| Data | Suggested interval |
|---|---|
| Leaderboard | 30–60 minutes |
| Trader profile | 6–24 hours |
| Balances | 15–60 seconds |
| Swaps | 5–15 seconds |
| Spotlight | 5–30 minutes |
| Ranking | 5–15 minutes |
| Snapshot | On demand |
| Health | 30–60 seconds |
Spread work across time. A bot monitoring 50 traders should use a queue with controlled concurrency instead of sending synchronized request bursts.
Complete Python client
Install the dependencies:
pip install requests python-dotenv
Add the key to .env:
FOMO_API_KEY=fomo_live_YOUR_API_KEY
import os
import random
import time
from datetime import datetime, timezone
import requests
from dotenv import load_dotenv
load_dotenv()
BASE_URL = "https://getfomoapi.fun/api"
API_KEY = os.getenv("FOMO_API_KEY", "").strip()
if not API_KEY:
raise RuntimeError("FOMO_API_KEY is missing")
session = requests.Session()
session.headers.update({"Accept": "application/json", "X-API-Key": API_KEY})
def api_get(path, params=None, retries=5):
for attempt in range(retries + 1):
response = session.get(f"{BASE_URL}{path}", params=params, timeout=30)
if response.status_code < 400:
return response.json()
if response.status_code not in {429, 502, 503, 504}:
response.raise_for_status()
if attempt == retries:
response.raise_for_status()
retry_after = response.headers.get("Retry-After")
try:
delay = float(retry_after) if retry_after else min(2 ** attempt, 30)
except ValueError:
delay = 1
time.sleep(delay + random.uniform(0, 0.5))
raise RuntimeError("Request failed")
def get_leaderboard(window="24h", limit=10):
return api_get(f"/leaderboard/{window}", {"limit": limit})
def resolve_trader(handle):
return api_get(f"/users/{handle}")
def get_balances(user_id):
return api_get(f"/users/{user_id}/balances")
def get_swaps(user_id, limit=20, cursor=None):
params = {"limit": limit}
if cursor:
params["cursor"] = cursor
return api_get(f"/users/{user_id}/swaps", params)
def build_trader_snapshot(trader):
handle = trader.get("userHandle")
if not handle:
return None
profile = resolve_trader(handle).get("responseObject", {})
user_id = profile.get("id")
if not user_id:
return None
return {
"observedAt": datetime.now(timezone.utc).isoformat(),
"user": profile,
"balances": get_balances(user_id).get("responseObject", {}),
"swaps": get_swaps(user_id).get("responseObject", {}),
}
Deduplicate swaps
Use a durable store in production and enforce a unique constraint on the swap ID.
def process_swaps(swaps, processed_ids):
new_swaps = []
for swap in swaps:
swap_id = swap.get("id")
if not swap_id or swap_id in processed_ids:
continue
processed_ids.add(swap_id)
new_swaps.append(swap)
return sorted(new_swaps, key=lambda swap: swap.get("createdAt", ""))
Detect position changes
Normalize positions under networkId:tokenAddress, then compare the old and new amounts. Classify a transition as opened, increased, reduced or closed.
Remember that a balance change is only a signal. Transfers, deposits, withdrawals, rebases, price updates and indexer corrections can also alter a snapshot. Cross-check swap data and the relevant chain before acting.
Production architecture
Scheduler → API client → Raw storage → Normalizer → Signal engine
→ Risk engine → Execution queue → Wallet executor → Monitor
Useful persistent tables include tracked_traders, trader_profiles, wallet_mappings, balance_snapshots, positions, processed_swaps, signals, orders, executions, risk_events and polling_checkpoints.
Store raw responses beside normalized records. Raw history makes incident investigation, parser migrations and strategy replay possible.
Security and launch checklist
- Put the API key in a secret manager and rotate exposed keys immediately.
- Keep data API keys separate from signing keys.
- Use separate testing and production wallets.
- Enforce transaction limits at the signer, not only in application code.
- Verify token and recipient addresses immediately before signing.
- Make order creation idempotent.
- Require manual approval above a defined value.
- Record accepted and rejected signals.
- Test backoff, timeouts, stale responses and malformed payloads.
- Independently confirm time-sensitive state through an RPC or indexer.
Fomo API is the data layer. A safe integration combines it with independent verification, explicit risk policy and an isolated execution service.