How integrations work
Guard speaks Hyperliquid's own API on your machine. Point your bot's API URL at it and sign with a Guard client key. What passes, what is checked, what is refused.
Guard listens on your machine and speaks Hyperliquid’s own HTTP API. So most tools need two changes and no new code:
- The API URL points at Guard instead of
https://api.hyperliquid.xyz. - The private key is the client key Guard gave you, not your API wallet key.
http://127.0.0.1:8547filled in from your settings ·
The account address stays your real Hyperliquid account address.
What Guard does with each request
Section titled “What Guard does with each request”| Request | What Guard does |
|---|---|
POST /info (prices, account, orders) | passes it to Hyperliquid unchanged |
POST /exchange, order that opens or grows a position | checks the client signature and nonce, applies the nine rules, re-signs with the API wallet, sends |
POST /exchange, order that reduces or closes | checks the client signature and nonce, re-signs, sends. Exits are never blocked |
POST /exchange, stop moved closer | passes; moved further away: ignored (Stops only tighten) |
POST /exchange, cancel | passes, unless it removes the last stop of an open position |
POST /exchange, updateLeverage | checked against your leverage rules; cross margin is refused, since Guard keeps every position on isolated margin |
Any action that moves funds or approves a key (withdraw3, usdSend, approveAgent, approveBuilderFee, …) | refused. An API wallet cannot sign these anyway |
| WebSocket market data | passed through |
A refusal comes back in Hyperliquid’s own error format, with a readable reason and a veto code. Tools that already handle Hyperliquid errors handle Guard’s.
Send the stop with the entry
Section titled “Send the stop with the entry”Guard sizes from the stop, so it needs the stop when it judges the entry. Two ways count:
- In the same request. Hyperliquid’s order action can carry an entry and its stop-loss together (grouping
normalTpsl). Guard sizes the entry from that stop and resizes the stop with it. - Already resting. A stop that already protects the whole position in that coin (for example a position TP/SL) counts for an entry that grows the position.
An entry with neither gets Guard’s own stop under the default rules (stop = "attach" in guard.toml): a reduce-only stop 2% away, sent with the entry, and the entry is sized from it. With stop = "refuse" it is refused (no_protective_stop). A stop the bot places a moment after the entry, as many bots do, cannot size it: the entry is judged before that stop exists, and Guard keeps its own stop.
One thing every tool does differently: the network in the signature
Section titled “One thing every tool does differently: the network in the signature”Hyperliquid signatures carry the network: source "a" for mainnet, "b" for testnet. Tools decide which one to use in different ways:
| Tool | How it picks the network | Pointed at Guard, it signs as |
|---|---|---|
| Hyperliquid Python SDK | base_url == MAINNET_API_URL (hyperliquid/exchange.py) | testnet ("b"), always |
| ccxt | its sandbox mode | mainnet unless sandbox mode is on |
@nktkas/hyperliquid | the transport’s isTestnet | mainnet unless isTestnet: true |
This does not matter for safety, because the client key is only valid at your Guard and Guard signs the real order itself, for the network Guard is set to. So Guard accepts a client signature with either source. The network your orders reach is decided by Guard’s config, never by the bot.
Guides
Section titled “Guides”This page as plain Markdown, for people and LLMs: /docs/integrations.md