Connecting a bot to your exchange

The customer-side flow end to end — download the connector kit, install it into a Hummingbot checkout, mint a signed API key, run connect bicrypto, add a controller preset and start it with the V2 flag.

5 min readUpdated 3 August 2026connector, setup, api-keys, connect, hummingbot

This is what a user does on their own machine, and what you do on yours if you run a bot outside the Bot Instances panel. The page at /hb/setup walks the same first four steps with live status derived from the account's real keys, and adds an optional fifth for the local agent — so send people there rather than to a copy of the commands.

What has to be true first

A bot needs four things from the exchange and one of them cannot be put in a file:

Thing Where it comes from
The connector package The kit download at /hb/setup — identical for every user
An API key and signing secret /hb/keys. The secret is shown once
The exchange's base URL Shown on /hb/setup, derived from the incoming request
A controller preset /hb/strategies, or authored in the Strategy Studio

The kit deliberately contains nothing account-specific — no key, no secret, no base URL. Those belong in connect, not in a zip thousands of people download, which is also what makes it safe for any authenticated user to fetch.

Step 1 — install the connector

Hummingbot has no idea your exchange exists until a package named bicrypto is inside its own checkout. Until then connect bicrypto answers "not a valid connector" and nothing is logged, because Hummingbot's discovery imports each connector inside a bare except ModuleNotFoundError: continue — an absent or unimportable connector is silently skipped rather than reported.

Download the kit from Connect your bot, unzip it next to the checkout, and run the installer inside the Hummingbot conda environment:

conda activate hummingbot
python install_connectors.py /path/to/your/hummingbot
python install_connectors.py /path/to/your/hummingbot --doctor
python install_connectors.py /path/to/your/hummingbot --clean
Flag What it does
--doctor Read-only. Checks the interpreter, the target directories, compares against the shipped kit, and verifies the import the way Hummingbot's own discovery does
--clean Wipes the target directories before copying. This is the fix for a nested or half-copied install
--force Copies over an existing install the audit flagged as broken, instead of refusing

The installer places both packages (spot and perpetual) and the controller module, patches setup.py, and then imports everything to prove it worked. If it reports that setup.py changed, rebuild before starting Hummingbot:

./install && ./compile

The kit carries the connector and the controller module, but no strategy files, so the installer prints that line and installs no presets. It is a warning, not a failure — strategies come from /hb/strategies in step 3, where the operator versions and republishes them, rather than being frozen into a zip thousands of people already downloaded.

cp -r SRC DST where DST already exists produces DST/bicrypto/bicrypto/ — a nested package Hummingbot never discovers, with no error anywhere. Use the installer, or cp -a SRC/. DST/ with the trailing dot.

Run the installer with the same interpreter the bot runs. A verification that passes under a different Python can pass while Hummingbot still fails to import.

Step 2 — mint a key and connect it

Create the key at /hb/keys. Pick the narrowest preset that does the job:

Preset Scopes
Read-only hb:read:account, hb:read:market
Spot trading the two reads, plus hb:trade:spot and hb:cancel:spot
Perp trading the two reads, plus hb:trade:perp, hb:cancel:perp, hb:perp:positions
Bot control hb:read:account and hb:control:bot — for the local agent only
Full access everything

Optional but worth doing: restrict the key by IP, so a leaked secret is unusable from anywhere else, and set an expiry to force rotation. An IP-restricted key with an empty allowlist denies everything — that is deliberate, because an empty list previously meant allow-all and silently defeated the restriction the user had just switched on.

It is never displayed again, it is excluded from every API response, and no administrator can read it. If it is lost, rotate the key to mint a new one. Rotation invalidates the old secret immediately.

Then, inside Hummingbot:

connect bicrypto

Three prompts:

Prompt Value
API key The key string from /hb/keys
API secret The signing secret shown once at creation or rotation
REST base URL Your exchange URL, e.g. https://your-domain.com

For perpetuals the connector is bicrypto_perpetual and connects the same way.

The connector refuses to guess a base URL and fails with "Bicrypto base URL is not configured. Run 'connect bicrypto'…" instead of falling back. An earlier build shipped a third-party demo hostname as its default, which meant a correctly configured install was still quietly dialling someone else's server on every launch. If you are upgrading from before that fix, reinstall the kit.

Verify with balance. You should see the assets in the Funding (ECO) wallet for the spot connector, and the Futures wallet for the perpetual one.

Answering No aborts the whole prompt sequence, including the base URL — which is one of the two ways a bot ends up with no address saved at all.

Step 3 — add a strategy

Download a preset from /hb/strategies. What you get is a V2 controller config, and Hummingbot never starts one of those directly: a script config names the controller, and you start the script.

id: my-strategy
controller_name: bicrypto_pmm
controller_type: market_making
connector_name: bicrypto
trading_pair: BTC-USDT
script_file_name: v2_with_controllers.py
controllers_config:
  - my-strategy.yml

Every downloaded preset prints this two-file layout in its own header comment, naming the exact filenames to save it under.

create is the Strategy V1 wizard and only ever offers V1 strategies — pure_market_making, amm_arb and so on. That is Hummingbot's design; reinstalling the kit does not change it. bicrypto_pmm is a V2 controller, a separate system.

Step 4 — start it

conda activate hummingbot
python bin/hummingbot_quickstart.py --headless --v2 my-strategy.yml

Or start --v2 my-strategy.yml from inside an interactive session. The flag takes the script config's name, resolved against conf/scripts/. Passing the controller's filename is the usual mistake and fails with "V2 config file not found". If your build rejects the flag, run start --help — the option name has moved between Hummingbot releases, and the config files are valid either way.

An MQTT bridge warning every five seconds is expected and unavoidable in headless mode: Hummingbot forces mqtt_autostart on whenever --headless is passed and raises if it is off, so there is no configuration that both keeps headless working and silences the bridge. Nothing in the connector depends on it.

Step 5 — confirm it is actually talking to the exchange

Open /hb/console. The setup page and the console both compute one honest verdict from the account's real records, because a customer cannot "connect" a bot from a web page — detecting the link is the only truthful thing either surface can do:

Verdict Means
Never connected No key on the account has ever authenticated
Connected Signed requests are arriving and being accepted
Being refused Requests are arriving and failing — a disabled key, a bad signature, a blocked IP
Silent It authenticated once but nothing has arrived recently; the process has probably exited

A tie between a success and a rejection in the same second resolves to the rejection. Both are recorded to the nearest second and a bot polls several times a second, so the exact situation this status exists to describe — last success moments before a block, everything since refused — otherwise landed in one second and reported "your bot is connected" during an emergency stop.

Clock drift is the failure nobody expects

Signed requests carry a timestamp and are refused more than 10 seconds away from the exchange's clock. The rejection is recorded against the key and names the direction and size of the drift:

Request outside recvWindow: this machine's clock is 12400ms ahead of the
exchange, limit 10000ms. Sync the clock on the machine running the bot.

Being ahead is the case people do not expect a receive window to reject, which is why the direction is stated rather than an absolute difference. Enable NTP on the bot's host. Anything drifting more than five minutes is refused before the key is even looked up, so probe traffic never reaches your account records.

Where to go next