How to Build a Telegram Trading Bot on Hyperliquid
Build a Telegram trading bot for Hyperliquid: per-user API wallets, builder fee approval, fill alerts for every user, and how the bot earns. Tested on both APIs.

A Hyperliquid Telegram trading bot lets people trade from a chat: type /long BTC 100, get a confirmation, get a message when it fills.
Why traders use one:
• Speed. Typing a command in a chat that's already open beats opening an app, connecting a wallet and clicking through.
• Trading where the conversation is. Traders already share calls in Telegram groups; a bot lets them act without leaving the chat.
• Alerts that reach them. Fills and price moves land as messages on their phone.
• Easy to start. A few commands replace charts and order forms.
Why should you choose to build a Telegram trading bot on Hyperliquid?
• Your users are already there. Many traders spend their day in Telegram groups and channels. A bot puts the trade one message away, with nothing new to install.
• A chat bot ranks fourth among Hyperliquid builders. pvp.trade, which puts trading inside Telegram group chats, ranked fourth of all builders on Flowscan with $8.05M in fees by 2 October 2026 (top builders by revenue).
• No exchange deal needed. Each user approves the bot's trading wallet and fee from their own wallet, and the bot sends orders through Hyperliquid's public API.
• No gas on trades. Users trade as often as they like without paying network fees.
• Every trade earns. Each perp trade a user makes in the chat can earn the bot up to 0.1%.
The trading logic is the easy part, and our trading bot guide covers it. What's different here is that one bot trades for many people at once.
How we tested. Parts 1 and 2 use only Hyperliquid's API: we ran the builder-approval check against a live wallet on 31 October 2026. Part 3, the fill alerts, is where the APIs differ, so we built it three ways and raced them against each other. Developers need pip install requests websockets. The examples that read a .txt file expect one full wallet address per line.
What users expect from a Telegram trading bot
The bots ranking for this search share the same short list. Plan for these from the start:
• Trade commands. /long BTC 100 5x, /close BTC, with a confirm button before anything is sent.
• Stop-loss and take-profit. Native order types on Hyperliquid, so the exit sits on the exchange even if your bot goes down (order types).
• Positions and PnL on request. /positions reads the user's account; it needs only their address.
• Fill alerts. "Your BTC long filled at 77,420." Part 3 is all about this.
• A kill switch. One command that cancels every open order.
The three parts below cover what's specific to running this for many people at once.
Part 1: Let the bot trade for each user
Your bot never holds a user's main key. Each user approves an API wallet (Hyperliquid also calls it an agent) that can place and cancel orders on their account. Your bot generates that wallet, and the user approves it once with their main wallet.
Two limits to plan for, from Hyperliquid's docs on sub-accounts and API wallets:
• Each account gets one unnamed and 3 named API wallets (plus 2 per sub-account), so your bot uses one of a small number.
• Your bot now stores keys that can trade for its users. Encrypt them, keep them off the machine that talks to Telegram if you can, and let users revoke the wallet from Hyperliquid's app. An API wallet can be given an expiry date (up to 180 days), so a forgotten bot doesn't keep trading rights forever.
Orders then go to Hyperliquid's /exchange signed by that user's API wallet. Orders always go through Hyperliquid; Hydromancer's part, in Part 3, is reading data for every user at once.
Part 2: Get the builder fee approved
The bot earns through a builder code: a fee you attach to each order, up to 0.1% on perps and 1% on spot sells (spot buys carry none). Each user approves your maximum fee once.
The catch for a chat bot: that approval must be signed by the user's main wallet, not the API wallet. Hyperliquid's builder code docs are explicit that an API wallet can't sign it. So your bot needs a small web page where the user connects their wallet and signs two things once: the API wallet approval and the builder fee approval.
Before each trade, the bot can check the approval is still in place:
import requests
URL = "https://api.hyperliquid.xyz/info"
USER = "0x051c2e6d49cf82ebc47f08f9b85800f94fc9693c"
BUILDER = "0x5af1b5f44207784dcb850bbb4143c5dcd1885f71"
body = {"type": "maxBuilderFee", "user": USER, "builder": BUILDER}
fee = requests.post(URL, json=body).json()
approved = requests.post(URL, json={"type": "approvedBuilders",
"user": USER}).json()
print("max fee (tenths of a bp):", fee, "approved builders:", approved)max fee (tenths of a bp): 0 approved builders: []That wallet hasn't approved this builder, so an order with this builder code would be rejected for that user. A user can hold at most 10 active builder approvals, and your builder address needs 100 USDC in its perps account and the standard account mode.
To see what you've earned, Hyperliquid's referral request returns your all-time builderRewards, and Hyperliquid publishes a daily file of your builder fills at stats-data.hyperliquid.xyz/Mainnet/builder_fills/<your address in lowercase>/<YYYYMMDD>.csv.lz4. That covers a daily revenue line in your admin chat; per-user revenue in real time comes from Hydromancer's builderFills stream (Part 3).
Part 3: Tell every user when their orders fill
This is the message users actually want: "Your BTC long filled at 77,420." It's also the part that breaks first as the bot grows, so we built it three ways and raced them on the same 30 busy wallets, 15 times.
Hyperliquid API, option 1: one subscription per user
The direct way: subscribe to userFills for each user on one connection.
import json, time
from websockets.sync.client import connect
end = time.time() + 120
with connect("wss://api.hyperliquid.xyz/ws") as ws:
for u in open("users.txt").read().split():
ws.send(json.dumps({"method": "subscribe", "subscription":
{"type": "userFills", "user": u}}))
while time.time() < end:
m = json.loads(ws.recv())
if m["channel"] == "error":
print("refused:", m["data"][:40])
elif m["channel"] == "userFills" and not m["data"].get("isSnapshot"):
for f in m["data"]["fills"]:
print(m["data"]["user"][:10], f["coin"], f["side"], f["px"])refused: Cannot track more than 15 total users.
refused: Cannot track more than 15 total users.
refused: Cannot track more than 15 total users.
refused: Cannot track more than 15 total users.
... (2977 more lines)Hyperliquid's docs allow 10 users per IP. In our test it allowed 15, then refused every other wallet with Cannot track more than 15 total users. Beyond that you need more IP addresses, or polling: userFills over REST weighs 20 of the 1,200 a minute, so about 60 users a minute from one IP.
Hyperliquid API, option 2: watch every market instead
The workaround: every public trade carries both wallets, buyer and seller. Subscribe to the trade feed of every market (about 900 perp and spot markets) and pick out your users by address. There's no per-user limit:
import json, time, requests
from websockets.sync.client import connect
ask = lambda t: requests.post("https://api.hyperliquid.xyz/info",
json={"type": t}).json()
coins = [a["name"] for m in ask("allPerpMetas") for a in m["universe"]]
users, start = set(open("users.txt").read().split()), time.time() * 1000
with connect("wss://api.hyperliquid.xyz/ws", ping_timeout=None) as ws:
for c in coins + [p["name"] for p in ask("spotMeta")["universe"]]:
ws.send(json.dumps({"method": "subscribe", "subscription":
{"type": "trades", "coin": c}})) # ~900 subs
while time.time() * 1000 < start + 120000:
m = json.loads(ws.recv())
for t in m["data"] if m["channel"] == "trades" else []:
for u in users & set(t["users"]) if t["time"] > start else []:
print(u[:10], t["coin"], t["side"], t["px"])0x7fdafde5 ETH B 2252.3
0x7019197d LINK B 11.875
0xf5d81a13 NEAR B 4.4241
0xf30120f0 LINK B 11.876
... (3625 more lines)The side printed is the taker's: your user bought if they're first in users and sold if they're second. It works for any number of users, with two catches we hit. Hyperliquid caps a connection at 1,000 subscriptions (Cannot subscribe to more than 1000 channels.), and its prediction markets add about 600 more feeds, and that limit is per IP, so a user trading there gets no alert unless you skip markets you don't need or use a second IP.
And a trade message has no fee or realized PnL, so "you made $40 on that close" needs another request.
Hydromancer API: one subscription for every user
userFills takes a list of addresses in a single subscription; each address counts toward your plan's subscription total (500 on Starter, 5,000 on Growth, 10,000 on Scale):
import json, os, time
from websockets.sync.client import connect
URL = "wss://api.hydromancer.xyz/ws?token="
users, end = open("users.txt").read().split(), time.time() + 120
with connect(URL + os.environ["HYDROMANCER_API_KEY"]) as ws:
ws.send(json.dumps({"type": "subscribe", "subscription":
{"type": "userFills", "addresses": users}}))
while time.time() < end:
m = json.loads(ws.recv())
if m["type"] == "ping":
ws.send(json.dumps({"type": "pong"}))
elif m["type"] == "userFills":
for user, f in m["fills"]:
print(user[:10], f["coin"], f["side"], f["px"])0x010461c1 GALA B 0.001709
0xf30120f0 GALA A 0.001709
0x010461c1 GALA B 0.001709
0xf5d81a13 NEAR B 4.4241
... (2598 more lines)Side by side
Hyperliquid userFills |
Hyperliquid trades workaround |
Hydromancer userFills |
|
|---|---|---|---|
| Wallets it could follow (of 30) | 15 | 30 | 30 |
| Fills delivered, all 15 tests | 72% | 90% | 99.7% |
| Tests where no fill was missed | 0 of 15 | 1 of 15 | 14 of 15 |
| Worst single test | 63% | 19% | 96% |
| Typical delay | 279 ms | 274 ms | 214 ms |
*15 tests of 2 minutes each, run back to back over about an hour. Each test used the 30 wallets that had traded most in the previous 3 minutes. We checked every delivered fill against Hydromancer's fillsByTime record of those wallets' fills (26,387 fills in total), matched by trade ID.
To check that record wasn't biased toward Hydromancer: in the test where Hyperliquid's every-market feed kept up, it matched the record fill for fill, and in the five tests where we also counted it, no feed delivered a fill the record lacked. Delay is the time from the fill's timestamp to its arrival.*
Only Hydromancer's stream was complete in almost every test. Hyperliquid's own subscription can't follow more than half of a 30-user bot, and the every-market workaround fell to 19% in its worst test, when Hyperliquid refused most of its market subscriptions, so check every subscription reply. Even Hydromancer dropped to 96% once, so after any reconnect, have your bot re-check fills by time.
For a bot, the builder-wide streams go one step further. builderFills streams every fill that went through your builder code, and builderApprovedFills every fill by users who approved your builder, including trades they made elsewhere and liquidations, so your bot can tell users they were liquidated even when the position wasn't opened through it. You don't even need the address list. The history version, builderApprovedFillsByTime, shows what that looks like for a busy builder:
import os, time, requests
KEY = os.environ["HYDROMANCER_API_KEY"]
BUILDER = "0x5af1b5f44207784dcb850bbb4143c5dcd1885f71"
now = int(time.time() * 1000)
body = {"type": "builderApprovedFillsByTime", "builder": BUILDER,
"startTime": now - 3600000, "endTime": now}
fills = requests.post("https://api.hydromancer.xyz/info", json=body,
headers={"Authorization": "Bearer " + KEY}).json()
users = {f["user"] for f in fills}
print(len(fills), "fills from", len(users), "approved users in 1 hour")974 fills from 157 approved users in 1 hourThat's one request for an hour of fills across every approved user (up to 2,000 fills per page; follow the cursor for busier hours).
Without Hydromancer, the other complete option is your own Hyperliquid node with --write-fills, which writes every fill on the exchange to disk (what a node needs).
Scaling past 15 chat users
Up to 15 active users per IP, Hyperliquid's free API runs the whole bot: API wallets, builder approvals, orders and fill alerts. The 16th user is where you choose between more servers, polling, your own node, or one stream for everyone.
FAQ
Can a Telegram bot trade on Hyperliquid without the user's private key?
Yes. The user approves an API wallet that can place and cancel orders for their account, and keeps their main key. They can revoke the API wallet from Hyperliquid's app.
How does a Hyperliquid Telegram trading bot make money?
A builder code fee on each trade users place in the chat, approved once per user. Price it low enough that users don't notice it against Hyperliquid's own fees.
How many users can one bot follow on the official API?
Fifteen per IP in our test, though the docs say 10. Part 3 compares the three ways past that limit.
Related reading
• How to build a Hyperliquid trading bot
• Hyperliquid builder codes: how they work
• Top 12 builders on Hyperliquid by revenue
• Hyperliquid testnet guide
Sources
- Hyperliquid docs: Builder codes, Nonces and API wallets, Rate limits
- Hydromancer docs: Monitor approved builder users
Read next

How to Build a Hyperliquid TWAP Execution Tool
Build a TWAP execution tool on Hyperliquid: native TWAP orders vs your own slicing, tracking slice fills, and seeing every active TWAP in a market.

How to Build a Trading Terminal on Hyperliquid
Build a Hyperliquid trading terminal: charts, order book, trades and order entry, plus 1-second candles and older chart history. Tested on both APIs.

How to Build a Trading Journal for Hyperliquid
Build a Hyperliquid trading journal: turn fills into closed trades with entry, exit, fees, funding and hold time, and keep history past 10,000 fills.