Settings
Every hb* setting key — the kill switch and read-only mode, the per-user key cap, the KYC requirement, the three default rate-limit budgets and the fill-detection cadence — with defaults, what reads each one, and what breaks if you get it wrong.
Admin → Hummingbot → Settings at /admin/hb/settings, behind
access.hb.settings. The screen writes through the platform's own settings
endpoint, so saving also needs edit.settings — a role that can open this
page but not save it is a real and confusing combination.
Every value takes effect immediately. There is no restart. They are read through an in-memory cache that is cleared on save, so a busy exchange does not pay a database hit per request.
If these settings cannot be read — a cache miss, a database hiccup — trading continues on the built-in defaults rather than halting. The kill switch simply does not engage and budgets fall back to code defaults. Stopping the exchange must be something you chose, not the side effect of an outage.
Controls
This is the emergency stop, not a maintenance mode. Bots cannot even cancel their resting orders while it is on, so a market you halt this way keeps whatever quotes were already resting until you turn it off or cancel them yourself from the Command Center.
This is the one to use before maintenance. Bots can still see the book and their
balances; they just cannot open new risk. A scope is treated as read-only only if
it begins hb:read: — everything else is a state-changing write and is refused
with 503 while this is on.
Lowering it does not revoke keys anyone already has — it only prevents new ones once they are at the cap.
Off by default, deliberately: key creation is ungated today, so defaulting it on would revoke the ability from every existing user the moment it shipped. It gates creation and rotation only — existing keys keep working.
Three switches must all be satisfied before anything is enforced: this one, the platform-wide KYC master switch, and the platform's per-feature enforcement switch. With platform KYC off there are no levels for anyone to hold, so the requirement stays dormant rather than locking every user out.
What it checks is that the user's approved level carries the api_keys
feature, which is what the admin level builder actually decides. While
per-feature enforcement is off it falls back to the level number below, so an
operator already running with this on has their configured bar honoured.
A user's highest approved level counts, so someone verified at level 3 satisfies a requirement of 2.
The view_hb KYC feature guards the strategy presets, the preset download, the
connector kit download, the setup page and the bot console. It is configured per
level under Admin → CRM → KYC, not here, and it is separate from this addon's
own key-creation requirement. The public /hb landing page stays open to
everyone either way.
Rate limits
Requests are billed to one of three budgets. These are the platform defaults; a per-key override set on the API Keys page always wins.
| Budget | Covers | Default |
|---|---|---|
| Trade | Placing, cancelling and amending orders | 600 per 60s |
| Market data | Order book, trades, ticker, exchange info | 1200 per 60s |
| Account | Balances, order status, positions | 240 per 60s |
Windows are fixed and aligned to wall-clock boundaries, not sliding, so a client can burst up to twice the limit across a boundary. That is acceptable for venue protection, and Hummingbot's own client-side throttler does the smoothing at its end.
The connector throttles itself against the same budgets it is told about, so a generous default lets every bot generate real load on your database. If one bot legitimately needs more, give that key an override rather than raising the default for everyone.
A malformed override falls back to "no override" — the platform default applies, never an unlimited budget.
There is a second cap you cannot set here
The platform applies a per-IP limit to every mutating request. Market-data and account reads are GETs and are never counted against it.
| Bucket | Env var | Default |
|---|---|---|
| Ordinary session traffic | RATE_LIMIT |
100 per window |
Signed bot traffic on /api/hb bot paths |
HB_RATE_LIMIT |
1200 per window |
| Window length | RATE_LIMIT_EXPIRE |
60 seconds |
A request that presents the full set of signing headers on a bot path is moved to
the bot-sized bucket, under its own key prefix, so bots and browsers behind one
NAT cannot exhaust each other. That is a substitution, not an exemption: an IP
that keeps failing signature verification loses the larger bucket for the rest of
the window and drops back to RATE_LIMIT. Forged credentials therefore buy
nothing, while a co-located legitimate bot degrades rather than dying.
If you raise the Trade budget above HB_RATE_LIMIT, the per-IP cap is what a bot
will actually meet.
Every response carries its own budget
Signed and public endpoints alike return X-RateLimit-Bucket (which of the three
governed the call), X-RateLimit-Limit, X-RateLimit-Remaining and
X-RateLimit-Reset (seconds until the window rolls). A refusal adds
Retry-After. A client that reads these paces itself instead of discovering the
ceiling by being refused.
A Redis hiccup on the counter fails open — a transient error must not 429 every legitimate request.
Streaming
Lower means tighter XEMM hedging and more engine load. Changes apply within about one cycle; no restart is needed.
Leave it alone unless you are running XEMM and measuring hedge slippage. For pure market making the default is comfortably fast enough.
The full key list
For reading logs or the settings table directly. Note that settings are stored
as text: a switch that is off holds the string "false", and the addon reads
true, 1, "true", "1" and "on" as on.
| Key | Default |
|---|---|
hbKillSwitch |
false |
hbReadOnly |
false |
hbMaxKeysPerUser |
10 |
hbRequireKyc |
false |
hbRequiredKycLevel |
2 |
hbBudgetTradeLimit / hbBudgetTradeWindow |
600 / 60 |
hbBudgetReadLimit / hbBudgetReadWindow |
1200 / 60 |
hbBudgetAccountLimit / hbBudgetAccountWindow |
240 / 60 |
hbWsUserTradesMs |
1000 |
A non-numeric or non-positive value in any of the numeric fields is ignored and the code default applies, so a typo degrades to the shipped behaviour rather than to zero.