-
Notifications
You must be signed in to change notification settings - Fork 0
Recipes
Practical, copyable patterns for using the cryptohopper CLI interactively. For CI/automation flows (--json, exit codes, jq pipelines, cron) see Scripting — this page is what to type at a terminal when you actually want to look at something.
Every example assumes you've run cryptohopper login once. The CLI persists your token in ~/.cryptohopper/config.json (mode 0600).
- Find your most active hopper
- See what every hopper is currently holding
- Watch a ticker in your terminal
- Kick off a 30-day backtest and wait for it
- Compare two strategies side-by-side
- Browse the marketplace
- Quick health check before you trade
- Inspect open positions and orders together
- Stop a runaway bot fast
- Switch between accounts (work / personal)
- Self-update without leaving the terminal
- Diagnose an auth failure end-to-end
cryptohopper hoppers list --json | jq '
.data
| map({id, name, exchange, position_count: (.positions // 0)})
| sort_by(-.position_count)
| .[0:5]
'Top-5 hoppers by current open-position count. Useful when you have many bots and want to focus on the busy ones.
for id in $(cryptohopper hoppers list --json | jq -r '.data[].id'); do
name=$(cryptohopper hoppers get "$id" --json | jq -r '.data.name')
echo "── $name (#$id) ──"
cryptohopper positions "$id"
donePrints a tabbed snapshot per hopper. positions (no --json) renders a Unicode table — easy to read in a terminal. For machine-readable output, add --json and pipe to jq.
watch -n 3 'cryptohopper ticker binance BTC/USDT'Refreshes every 3 seconds. cryptohopper ticker still requires you to be logged in (run cryptohopper login first). Although /exchange/ticker is conceptually "public market data," the API gateway requires an OAuth bearer on every call today.
For a multi-pair watcher:
watch -n 5 '
for pair in BTC/USDT ETH/USDT SOL/USDT; do
cryptohopper ticker binance "$pair" --json | jq -r "\"\($pair) \(.data.last)\""
done
'hopper_id=42
from=$(date -d "30 days ago" +%Y-%m-%d)
to=$(date +%Y-%m-%d)
bt_id=$(cryptohopper backtest new "$hopper_id" --from "$from" --to "$to" --json \
| jq -r '.data.id')
echo "Submitted backtest #$bt_id, polling..."
while :; do
status=$(cryptohopper backtest status "$bt_id" --json | jq -r '.data.status')
echo " status=$status"
case "$status" in
completed|failed) break ;;
esac
sleep 5
done
cryptohopper backtest status "$bt_id"Backtests have a separate rate bucket (1 request per 2 seconds). 5-second polling stays well clear.
cryptohopper strategy get 5 > /tmp/strategy-A.json
cryptohopper strategy get 12 > /tmp/strategy-B.json
diff -u /tmp/strategy-A.json /tmp/strategy-B.jsonstrategy get pretty-prints the full JSON config. Diffing two strategies tells you exactly what differs — useful when iterating on a copy.
# Note: the API gateway requires a real OAuth bearer on every call.
cryptohopper signals list --type buy --limit 20
cryptohopper template list
cryptohopper tournaments activeThe first one shows live buy signals from the marketplace, the second shows your saved templates, the third shows currently-running tournaments.
cryptohopper whoami # confirm which account is active
cryptohopper subscription get # confirm plan and remaining bots
cryptohopper backtest limits # confirm backtest quota
cryptohopper subscription credits # confirm AI creditsA 4-command health check before you start a session. Each is one quick GET — no rate-limit pressure.
hopper_id=42
echo "── positions ──"
cryptohopper positions "$hopper_id"
echo
echo "── open orders ──"
cryptohopper orders "$hopper_id"Two side-by-side tables. Useful when reviewing what a bot is doing right now, before deciding whether to intervene.
cryptohopper hoppers panic 42 --yespanic cancels every open order and closes every position immediately. The --yes skips the confirmation gate; don't add --yes until you're sure. Without it the CLI prompts and waits — that's the safe default.
For machine-readable output (e.g. you want to check what got cancelled in a script), add --json --yes. The --yes is required even with --json — the CLI explicitly refuses to silently bypass confirmation for --json callers (see the 0.5.1-alpha.1 changelog for the underlying fix).
The CLI reads CRYPTOHOPPER_TOKEN from the env before falling back to ~/.cryptohopper/config.json. So per-shell account switching is trivial:
# Personal account: use the saved config.
cryptohopper whoami
# Work account: override via env, leave saved config alone.
CRYPTOHOPPER_TOKEN=$WORK_BEARER cryptohopper whoamiOr with shell functions in your .bashrc / .zshrc:
ch-work() { CRYPTOHOPPER_TOKEN="$WORK_BEARER" cryptohopper "$@"; }
ch-personal() { cryptohopper "$@"; } # uses saved configCRYPTOHOPPER_APP_KEY follows the same precedence rule.
cryptohopper upgrade --check # is there a newer release?
cryptohopper upgrade # download + verify SHA256 + atomic swapupgrade only works for the standalone Bun-compiled binaries. If you installed via npm install -g @cryptohopper/cli, the CLI prints a hint to use npm instead.
When something goes wrong with your token, the right next step depends on which error you're seeing. This sequence narrows it down in 30 seconds.
# 1. CLI version sanity check. Earlier versions sent the wrong auth header
# (Authorization: Bearer instead of access-token); 0.6.0-alpha.2+ is fixed.
cryptohopper --version
# 2. Token presence + length sanity check.
[ -n "$CRYPTOHOPPER_TOKEN" ] \
&& echo "env var: ${#CRYPTOHOPPER_TOKEN} chars (expected 40)" \
|| echo "env var: not set (will fall back to ~/.cryptohopper/config.json)"
# 3. Config file presence + perms.
ls -l ~/.cryptohopper/config.json 2>&1
# 4. The minimal authenticated probe.
cryptohopper whoami --jsonThe output of step 4 tells you everything:
| Output | What's wrong | Fix |
|---|---|---|
{"ok": true, ...email/username...} |
Nothing — auth works | (none) |
{"ok": false, "error": {"code": "UNAUTHORIZED"}} |
Token is invalid, expired, or revoked | Re-run cryptohopper login, or re-issue the token in the developer dashboard |
{"ok": false, "error": {"code": "FORBIDDEN", "ip_address": "1.2.3.4"}} |
Token is valid but your IP isn't on the OAuth app's allowlist | Add 1.2.3.4 to the OAuth app's IP allowlist on cryptohopper.com, or disable the allowlist for that app |
{"ok": false, "error": {"code": "FORBIDDEN", ...}} (no ip_address) |
Token is valid but lacks the required scope | Re-issue the token with the right scopes (read manage trade user) |
{"ok": false, "error": {"message": "Missing Authentication Token"}} |
The CLI is sending the wrong auth header (likely 0.6.0-alpha.1) |
cryptohopper upgrade to 0.6.0-alpha.2+ |
{"ok": false, "error": {"code": "NETWORK_ERROR"}} |
Can't reach api.cryptohopper.com
|
Check DNS, firewall, corporate proxy (HTTPS_PROXY env var) |
{"ok": false, "error": {"code": "TIMEOUT"}} |
Reached the API but it didn't respond within 30s | Retry; if persistent, check Cryptohopper status page |
Common quick-fixes inferred from the matrix:
# Re-auth from scratch (drops the saved token, re-runs the OAuth browser flow)
cryptohopper logout && cryptohopper login
# Verify which token is actually being used (env var beats config file)
env | grep CRYPTOHOPPER_TOKEN || echo "no env var; config file in use"
# Print the config file (with token masked)
cryptohopper config get | sed -E 's/("token": "[a-zA-Z0-9]{4})[a-zA-Z0-9]+/\1.../g'If whoami --json returns the right user but a specific command (e.g. hoppers buy) returns FORBIDDEN, the issue is per-scope: your token has read but not trade, etc. Re-issue the token with broader scopes.
- Scripting — CI/automation, stable exit codes, jq pipelines, cron, Prometheus textfile
-
Troubleshooting — port-conflict errors,
upgradepermission denials, UNAUTHORIZED diagnosis, shell-completion install - Public CLI reference (PR pending) — every subcommand, every flag, JSON output contract, exit-code table
Pages
SDK wikis
Resources