The admin console

The five Hummingbot admin screens — the platform-wide API key registry and its posture band, per-key kill switch and rate-limit overrides, the Command Center's force-cancel and flatten, and the permission each one gates on.

4 min readUpdated 3 August 2026admin, api-keys, command-center, kill-switch, audit

Everything lives under /admin/hb, behind access.hb. Five screens, each with its own permission — being able to see the Hummingbot menu no longer implies being able to open all of them.

Screen Path Opens with
API Keys /admin/hb view.hb.key
Command Center /admin/hb/command access.hb.command and view.hb.command
Bot Instances /admin/hb/instances view.hb.instance
Strategy Studio /admin/hb/strategies access.hb.strategy and view.hb.strategy
Settings /admin/hb/settings access.hb.settings, plus edit.settings to save

Super Admin bypasses permission checks entirely, so a section that opens for the owner tells you nothing about whether your staff can use it. Open each screen with a configured role after any upgrade, and grant what is missing in Admin → Roles.

API Keys — the registry

/admin/hb. Every Hummingbot-capable key on the platform, meaning every apiKey row carrying at least one hb:* scope. It is a registry of configured credentials, not a dashboard.

The page leads with one posture band splitting the fleet into Enabled and Disabled, with the operative figure stated beside it in words: how many of those can accept a signed request right now — switched on and inside their expiry. Enabled therefore reads higher than "active" ever did, because it includes keys that have since expired.

Both bands are click-to-filter, and clicking one sets the same filter the toolbar's own switch sets, so a band's number and the rows it loads are the same set by construction. A Show all keys control appears while a band is filtering.

Beneath the band is a flag row, for the states that sit across the split — a key can be enabled and expired and throttled at once:

Flag Counts
Expired (enabled) Switched on and past its expiry — being refused while its owner believes it is live
Throttled Carries a per-key rate-limit override
No secret Has no signing secret, so it can never sign a request
Auth failures (24h) Failed signatures, replay blocks, IP blocks and expiry/disabled rejections across all these keys
Used (24h) Keys that authenticated in the last day

The flags are deliberately not clickable. None of those populations can be expressed as a filter the table can send, and a control that loads a different set of rows than the number beside it is exactly the defect the band above was built to avoid.

Every figure is a platform-wide total from the same scan the table uses, never a sample of the rows on screen. The numbers carry a last-updated clock and a liveness marker; when a refresh fails the last good numbers stay on screen and the marker turns stale, rather than a green pulse over figures that stopped advancing.

What you can do to a key

Action Permission Effect
View details view.hb.key Scopes, expiry date, IP whitelist, the reason it was disabled, and when it was created — four of those appear nowhere else in the product
Audit trail view.hb.key Creation, rotation, permission changes, kill-switch events and authentication failures
Disable edit.hb.key The immediate way to stop one account's bot without touching anyone else
Re-enable edit.hb.key Restores service. Runs immediately — there is nothing to explain
Rate-limit override edit.hb.key A fresh {limit, windowSec} for the read, trade or account bucket on this key alone

Disabling a key records a reason, and that reason is returned verbatim to the bot on its next signed request: API key disabled: <your reason>, with HTTP 423. Write something the key's owner can act on. Leaving it blank records nothing rather than a placeholder sentence.

Disabling in bulk asks for confirmation, names the exact count, and carries your reason to every key. A partial failure is reported and never rolled back — stopping ten bots is ten independent decisions, and undoing the ones that worked because one failed would be worse.

An admin disable is stamped admin and a customer's own emergency stop is stamped user, so an operator block cannot be laundered: the customer's console tells them to contact support instead of offering a re-enable button that would fail.

Signing secrets are never visible to you. The secret is shown once, to the owner, at creation or rotation. Neither the console nor any API response exposes it afterwards. A user who loses theirs rotates the key.

Rate-limit overrides

A partial map keyed by bucket name. Only read, trade and account are accepted.

{ "read": { "limit": 5000, "windowSec": 60 } }
{ "trade": { "limit": 60, "windowSec": 60 } }

Send {} or null to clear all overrides and revert to the platform defaults. Give one bot an override rather than raising the default for everyone — the connector throttles itself against the same budgets, so a generous default lets every bot generate real load on your database.

Command Center

/admin/hb/command. The screen to open when something is going wrong. It carries the two global switches and a list of every account running a bot, with a drill-down into one account's live orders and positions.

The two global switches

Switch Blocks Use it for
Kill switch Every signed request — orders, cancels and account reads An emergency. Bots cannot even cancel their resting orders while it is on
Read-only mode Order placement, cancellation and position management, leaving market data and account reads working A planned wind-down or maintenance window

Read-only is the one to reach for before maintenance: bots can still see the book and their balances, they simply cannot open new risk. Both are stored as settings and both fail open — if the settings cannot be read because of a cache or database problem, trading continues rather than halting. Stopping the exchange should be a decision you made, never the side effect of an outage.

Acting on one account

Action Permission Effect
Cancel all manage.hb.command Cancels every open order for that account, spot and perpetual. Positions untouched
Flatten manage.hb.command Cancels the orders and closes every open perpetual position, realising profit and loss immediately

Both compose the same native handlers the account's own endpoints use, so wallets and margin settle correctly and the matching engine stays consistent. Per-item failures are collected rather than fatal — one stuck order cannot block the rest of a flatten — and a single action is bounded so a runaway account cannot fan out without limit.

Cancelling a market maker's orders does not stop it. Disable its key first (or switch on read-only mode), then cancel. Otherwise you are watching your own cancellation get undone on the bot's next refresh.

Reading the audit trail

A key's trail records creation, rotation, permission changes, the kill switch and every authentication rejection. Rejection rows are throttled to one per key per action per minute, so a bot hammering a disabled key writes one row a minute rather than an unbounded insert stream — a small count there can still represent a great deal of traffic.

The kill-switch entry is marked as an intervention, not a rejected signature. It used to be tinted the same red as a bad signature, a replay block and an IP block, while the "Auth failures (24h)" figure has never counted it — so a trail containing nothing but an operator's own deliberate action looked like a key under attack.

Three things on these screens are deliberately never translated, because they are machine values you copy rather than prose: the rate-limit bucket names, the audit action ids, and a key's public identifier. Pasting auth.replay_blocked into a support ticket has to produce the string the server wrote.

Where to go next