Learn / Exchange APIs

Read-only vs trade permission on an API key

Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs before acting on a number.

A key that cannot trade cannot be talked into trading — not by a bug, not by a prompt, not by a mislabeled tool. It is the only boundary in the stack enforced by someone other than your own software.

Which is why it is worth knowing how each venue actually implements it, because they are not the same and one of them works backwards from the rest.

Short answer by venue

VenueRead-only mechanismSafe by default?
BinancePermission flags on the key; enableReading aloneNo — you choose at creation
BybitPermission scopes on the keyNo
AlpacaAccess Controls: Read only / Full access / Custom per scopeNo
IBKR (TWS)Application setting, not a credentialYes — Read-Only API is on by default
HyperliquidNo API key at all; agent wallets signStructurally, mostly

Binance

Permissions are flags on the key, readable programmatically via GET /sapi/v1/account/apiRestrictions, which returns ipRestrict, enableReading, enableWithdrawals, enableMargin, enableFutures and others.

Two Binance-specific behaviours matter more than the flags themselves:

Withdrawals require IP restriction. The filter is a precondition for the permission, not an option beside it. A key with no IP whitelist structurally cannot withdraw.

Trading permission expires on unrestricted keys. A key with no IP whitelist has “Enable Spot & Margin Trading” automatically unchecked 90 days after activation. Keys with a whitelist do not expire this way.

The practical effect is that Binance nudges you toward IP-restricted keys whether or not you were planning to bother.

Bybit

Scopes are set on the key. IP binding exists and is enforced — error 10010, “Unmatched IP, please check your API key’s bound IP addresses”, is its signature. Permission refusals surface as 10005, “Permission denied, please check your API key permissions.”

Worth distinguishing from the codes that look similar but are not permission problems: 10003 is session count on classic accounts and an expired key under UTA, and 110028 / 100028 are unified-account eligibility rather than scope.

Alpaca

Alpaca sets permissions at key-generation time through Access Controls, with three levels:

  • Read only — view data across all API scopes
  • Full access — view and modify across all scopes
  • Custom — per-scope choice of Read & Write or Read only

Custom is the useful one: you can leave watchlists writable while trading stays read-only.

OAuth is a separate mechanism with its own scopes, requested in the authorization URL (scope=account:write trading) and echoed in the token response. A read-only OAuth integration is achieved by omitting the write scopes rather than by requesting a read-only one. Alpaca additionally requires OAuth apps to be approved before they can trade on users’ behalf.

IBKR — the one that works backwards

IBKR does not attach permissions to a credential, because the TWS API does not use one: it is a socket to a logged-in desktop application. The permission is an application setting.

TWS 950 and above has a Read-Only API mode that “allows viewing of market data and account information, but blocks any type of trading activity” — and it is enabled by default.

Find it at Global Configuration → API → Settings. In TWS Classic that is Edit → Global Configuration; in Mosaic, File → Global Configuration or the cog wheel. In IB Gateway: Configure → Settings → API → Settings.

Two consequences worth internalising:

The most common “my orders are being rejected” cause on TWS is this checkbox, not your code. If API orders are failing and everything else works, look here first.

IBKR is the only venue in this comparison where doing nothing leaves you safe. Everywhere else a freshly created trading key is armed the moment it exists. Here the default blocks orders and you must deliberately unblock them.

One related default: “Enable ActiveX and Socket Clients” is off by default in TWS, though IB Gateway accepts socket connections by default. So a fresh TWS install refuses API connections entirely until you enable it.

Hyperliquid — no key to set permissions on

Hyperliquid has no API key. A master account approves an API wallet (agent wallet) to sign on its behalf. The documentation states plainly that “API wallets are only used to sign”, and that querying account data requires passing the master or sub-account’s actual address — the agent’s own address owns nothing.

Can an agent wallet move funds? Hyperliquid does not say, and there is no prohibition to quote. What its official Python SDK shows is structural: the fund-moving actions (withdraw3, usdSend, spotSend) are user-signed and take no account or vault address, while trading actions go through the L1 signing path that does. That address field is how an agent’s signature gets attributed to the master. Without it, there is no way to express “move the master account’s funds” in the payload at all.

So the practical answer is that the signing scheme gives an agent wallet no way to express a withdrawal of the master’s funds — a structural property rather than a permission flag, and arguably stronger than a checkbox. But Hyperliquid has not stated it, so verify it against your own setup before relying on it as a boundary.

What to actually do

Start read-only. Most of what people want from programmatic access — reading positions, computing exposure, monitoring — needs no write permission at all.

Separate keys by purpose. One key per consumer means a leak is revocable without collateral damage, and an error tells you which component caused it.

Verify rather than remember. Binance exposes the key’s state over the API. On IBKR, look at the checkbox. On Alpaca, look at the key’s Access Controls. What you configured six months ago is not reliably what is running.

Do not treat a server’s read-only mode as the permission. Some MCP servers and client libraries offer read-only modes, and the good ones are well built. But that is a control inside the component you are bounding. The key permission holds regardless of what your software does.

FAQ

Which venue is safest by default?

IBKR, by a clear margin and somewhat by accident of architecture. Its Read-Only API setting blocks all API trading and is enabled by default, so a fresh setup cannot place orders until you deliberately allow it. Every other venue here issues a key with whatever permissions you selected, active immediately.

Can I make an Alpaca key read-only?

Yes. Generate it with Read only access, or use Custom and set the trading scope to Read only while leaving other scopes as needed. For OAuth integrations, the equivalent is omitting trading and account:write from the requested scope.

Why does my Binance key work for reading but not for trading?

If it has no IP whitelist, the likely cause is the 90-day expiry: Binance automatically unchecks “Enable Spot & Margin Trading” 90 days after activation for keys without IP restriction. Reads keep working, so the symptom is specifically that orders start being refused. Re-enable it and add a whitelist.

How does this work on Hyperliquid, which has no API keys?

Through delegation rather than permissions: a master account approves an agent wallet that can sign on its behalf. The signing scheme means fund-moving actions carry no account address and so cannot be expressed for the master by an agent signature. It behaves like trade-only in practice, but it is a structural property that Hyperliquid has not documented as a guarantee — check it on your own setup.