Skip to content

Learn

Exchange APIs

Alpaca vs IBKR API: REST keys vs the TWS socket

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

Alpaca and Interactive Brokers both let you trade stocks from code, with paper accounts to test against. The choice is hard because their APIs are not two versions of one design. Alpaca is an HTTPS API you call with a key; IBKR’s TWS API is a socket to a desktop application a human has logged into. Almost every other difference follows from that.

This page is for developers choosing one or adding the second. It covers mechanism only — no commissions, no quotas — and does not recommend a broker. Account eligibility differs by country; check each broker’s own pages.

Short answer

  • You want to run on a server with nothing else installed → Alpaca. The TWS API needs TWS or IB Gateway running and logged in.
  • You want API orders blocked until you deliberately allow them → IBKR’s Read-Only API setting is on by default. On Alpaca, a read-only key is available, but you choose it at creation.
  • You want official SDKs from a package manager → Alpaca publishes its SDKs as normal packages. IBKR distributes its official client only through its own installer.
  • Your design is event-driven over one long-lived connection → the TWS API delivers everything, errors included, through callbacks on one socket.

What they have in common

  • A paper environment that runs the same API as live, so the same code can target either.
  • Official clients in Python, Java and C#/.NET.
  • A read-only option — at key level on Alpaca, at application level on IBKR.
  • A documented throttling mechanism, with the actual figure kept on the broker’s own page.

Where they actually differ

Transport and architecture

Alpaca Trading APIIBKR TWS API
ShapeHTTPS REST, plus WebSocket and SSE streamsTCP socket to a local TWS or IB Gateway
Hostsapi.alpaca.markets, paper-api.alpaca.markets, data.alpaca.markets127.0.0.1 (same machine) on the configured socket port
Request/responseRequest and response per call, under /v2Requests through EClient, responses through EWrapper callbacks
Needs runningNothingTWS or IB Gateway, logged in

IBKR also has a separate product, the Client Portal Web API: REST against a local gateway at https://localhost:5000, needing Java and a funded IBKR Pro account, re-authenticated in a browser daily, with no supported automated authentication. Code for it does not port to the TWS API, which is what the rest of this page compares. See IBKR TWS API setup and WebSocket vs REST for trading.

Authentication

Alpaca sends a key ID and secret in two headers, APCA-API-KEY-ID and APCA-API-SECRET-KEY, or as HTTP Basic credentials. There is no request signature, so signature construction and clock skew are simply not failure modes. Alpaca now labels this the “Legacy” flow; its OAuth client-credentials flow is not yet available for the Trading API. The secret is shown once, at creation.

IBKR’s TWS API has no API key. A human logs into TWS or IB Gateway; your program opens a socket to it. By default TWS asks for confirmation before accepting an API connection, denies untrusted remote IPs without prompting, and can be set to auto-accept trusted IPs. Each client identifies itself with a client ID — up to 32 can connect to one session — and reusing an ID in use returns 326 “Unable to connect as the client id is already in use.”

Paper trading

Alpaca puts paper on its own host, paper-api.alpaca.markets, with its own keys and the same API spec, though some endpoints, such as Locates, are unavailable in paper. A paper key on the live host fails with 401 or 403 — Alpaca names both.

IBKR makes paper a separate login. The paper session listens on its own port: by default 7497 for TWS and 4002 for IB Gateway, against 7496 and 4001 for live. The defaults can be changed, and your connect() call must match the configured port.

Either way, the risk is pointing tested code at live by changing one value — a host on Alpaca, a port on IBKR. See the Alpaca paper trading API and what paper trading is.

Permissions and safe defaults

Alpaca scopes the key at creation through Access Controls: Read only, Full access, or Custom, with Read & Write or Read only per scope. Keys can also be given an expiry. For OAuth apps, leaving out the trading and account:write scopes yields a read-only integration.

IBKR has an application-level switch. The Read-Only API setting, under Global Configuration → API → Settings, is enabled by default and blocks all API orders until unchecked. The same panel holds “Enable ActiveX and Socket Clients”, which must be on for socket connections.

IBKR is where doing nothing gives you the safe configuration; on Alpaca the safe configuration is a choice you make when you create the key. Users report error 321 with the text “The API interface is currently in Read-Only mode”; IBKR’s own table lists 321 only as a generic validation error. See read-only vs trade permission.

Rate-limit mechanism

Alpaca uses a per-minute request window and reports it on responses: X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (the Unix time the quota changes). Exceeding it returns 429.

IBKR’s TWS API caps the rate of messages per second from client to TWS. Exceeding it produces error 100 “Max rate of messages per second has been exceeded.”, and IBKR notes TWS will likely disconnect the client. The Client Portal Web API is different again: 10 requests per second per authenticated username, 429 on breach.

The practical difference is what a breach costs. On Alpaca you get a 429 and headers to pace by; on the TWS API you may lose the connection. See rate-limit models compared.

Official SDKs

Alpaca provides and supports alpaca-py (Python), Alpaca.Markets (.NET), @alpacahq/alpaca-trade-api (Node), alpaca-trade-api-go and alpaca-java, and publishes OpenAPI specs for client generation. Rust and other wrappers are listed separately as community-made.

IBKR ships Python, Java, C++, C# and VB.NET clients, plus Excel integrations, only through its own MSI or ZIP installer. IBKR states that packages on pip, NuGet or other online repositories are not hosted, endorsed or supported by it, and recommends keeping the API version in step with TWS. Popular wrappers such as ib_insync and ib_async are third-party; a reply on an IBKR Campus lesson says IBKR does not support ib_insync.

How errors reach your code

Alpaca errors come back on the request that caused them: an HTTP status and a JSON body with code and message, for example 42210000 with a sub-penny limit_price message. 403 is overloaded — on POST /v2/orders it means buying power or shares are insufficient, wash-trade protection also returns it, and Alpaca says invalid credentials can sometimes produce 403 instead of 401.

IBKR delivers errors asynchronously through EWrapper.error(), with the originating request ID (or order ID), a numeric code and a description. The same callback carries warnings and informational messages: 2104 “Market data farm connection is OK” arrives on every healthy connect. And 502 “Couldn’t connect to TWS” is raised by the operating system on the client side, so it never appears in TWS’s logs.

An Alpaca client handles errors inline; an IBKR client needs a dispatcher that correlates by request ID and filters informational codes. See auth errors across exchanges.

Which to pick

Your situationLean towardWhy
Headless deployment, nothing else runningAlpacaPlain HTTPS; the TWS API needs a logged-in desktop app
You want orders blocked by defaultIBKRRead-Only API is on until you turn it off
You want per-scope key permissionsAlpacaCustom Access Controls per scope
You install dependencies from pip/npm/NuGetAlpacaIBKR’s official client comes only from its installer
You want one persistent, callback-driven connectionIBKREClient out, EWrapper in
You want unattended REST access at IBKRPlan for a human stepThe Client Portal Web API needs daily re-authentication

Can you use both

Yes, behind a thin common interface — submit order, get positions, get account. Do not share error handling (synchronous HTTP vs an asynchronous callback stream), and keep paper and live as separate configuration slots on both: one wrong host or port is all it takes.

FAQ

Does IBKR have API keys like Alpaca?

Not for the TWS API. A person logs into TWS or IB Gateway, and your program connects to it over a local socket, identified by a client ID. Alpaca uses a key ID and secret in request headers, with no desktop application involved.

Why are my API orders rejected on a fresh IBKR install?

Often it is the Read-Only API setting, which IBKR enables by default and which blocks all API orders. Uncheck it under Global Configuration → API → Settings. Users report error 321 with “The API interface is currently in Read-Only mode” when this happens.

Is ib_insync the official IBKR Python API?

No. IBKR distributes its official Python client only through its own installer and says packages on pip and other repositories are not hosted, endorsed or supported by it. ib_insync and ib_async are third-party wrappers around the TWS API.

How do Alpaca and IBKR paper trading differ?

Alpaca paper runs on a separate host, paper-api.alpaca.markets, with separate keys and the same API spec. IBKR paper is a separate login to TWS or IB Gateway, listening by default on port 7497 (TWS) or 4002 (Gateway) instead of the live 7496 or 4001.