Short answer: The Alpaca API in Python runs through alpaca-py, version 0.45.0 on PyPI (5 November 2026, Python 3.10 or later), because the older alpaca-trade-api repository was archived on 17 June 2026. Paper trading uses https://paper-api.alpaca.markets with its own keys, and Alpaca's docs say anyone globally can open a paper-only account. In an offline test on 5 November 2026 the SDK resent order POSTs after HTTP 429 and 504 and set no HTTP timeout, so settle both before live use.
No Alpaca account or key was used for this guide. Requests were built offline with alpaca-py on Python 3.11.3 and run against a local mock server, on 0.44.0 and again on 0.45.0, released that day, with the same results. The only live calls carried no key or an obviously fake one, so anything needing a real key is marked as not run. Documentation was read on 5 November 2026.
This covers stocks only and is not a recommendation of Alpaca. Automated trading can lose money, and paper results say nothing about live results. REST and FIX architecture is in broker API integration. If you searched for an alpaca tradingview webhook: TradingView's Terms of Use (opens in a new tab), read on 5 November 2026, license alerts and webhooks for display-only use and prohibit automated trading, including through third-party products or services. Read those terms and take legal advice before relying on such a route; this guide does not present it as permitted.
Alpaca API Python: install alpaca-py, not the archived SDK
Install alpaca-py, because the older repository is read-only and points to the newer SDK.
| Aspect | alpaca-py | alpaca-trade-api-python |
|---|---|---|
| Status | 0.45.0, released 5 November 2026; 0.44.0 was 11 August 2026 | Archived 17 June 2026, read-only |
| Typical import | from alpaca.trading.client import TradingClient | from alpaca_trade_api.rest import REST |
| License | Apache-2.0 | Apache-2.0 |
A tutorial that imports alpaca_trade_api teaches the archived code. The old README still says maintenance runs until the end of 2022.
Pin the version: per its release notes (opens in a new tab), 0.45.0 removes TransferTiming, requires Pydantic 2.7 or newer and stops installing pytz.
Alpaca API key and paper trading API
Paper and live are separate environments, with different hosts and different keys but the same API specification.
| Item | Paper | Live |
|---|---|---|
| REST host | paper-api.alpaca.markets | api.alpaca.markets |
| Trade stream | wss://paper-api.alpaca.markets/stream | wss://api.alpaca.markets/stream |
| Stock data | Paper-only accounts get IEX data only | Depends on the data plan |
Send the key in the APCA-API-KEY-ID and APCA-API-SECRET-KEY headers; a new paper account needs newly generated keys. In alpaca-py, TradingClient defaults to paper=True, so live use needs paper=False. On 5 November 2026 GET /v2/account with no key returned HTTP 401 and {"message": "unauthorized."} from both hosts.
Paper trading starts with a default $100,000 and hides much of what costs money. Alpaca's page says it does not account for market impact, queue position of resting limit orders, price improvement, regulatory fees or dividends. Eligible orders get partial fills of random size 10% of the time, and order size is not checked against quoted size. Wash trade protection (opens in a new tab) does apply on paper, as an HTTP 403. The trap is the one described in backtesting pitfalls: simulated fills flatter a strategy.
Tested alpaca-py order code on a local mock
You can test order handling with no account by pointing url_override at a mock that replies with scripted statuses.
import json, threading, time
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from requests.adapters import HTTPAdapter
from alpaca.common.exceptions import APIError
from alpaca.trading.client import TradingClient
from alpaca.trading.enums import OrderSide, TimeInForce
from alpaca.trading.requests import MarketOrderRequest
replies, posts = [], []
class Mock(BaseHTTPRequestHandler):
def log_message(self, *a): pass
def do_POST(self):
posts.append(json.loads(self.rfile.read(int(self.headers["content-length"]))))
status, body = replies.pop(0) if replies else (200, {"status": "accepted"})
if status == "hang":
time.sleep(body)
return
data = json.dumps(body).encode()
self.send_response(status)
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
srv = ThreadingHTTPServer(("127.0.0.1", 0), Mock)
threading.Thread(target=srv.serve_forever, daemon=True).start()
URL = f"http://127.0.0.1:{srv.server_port}"
order = MarketOrderRequest(symbol="TEST", qty=1, side=OrderSide.BUY,
time_in_force=TimeInForce.DAY,
client_order_id="rule7-20261105-0001")
def attempt(client, label, script):
replies[:], posts[:] = script, []
start = time.time()
try:
result = client.submit_order(order)
except APIError as err:
result = f"APIError {err.status_code} {err.code}"
except Exception as err:
result = type(err).__name__
print(f"{label:12} POSTs={len(posts)} {time.time() - start:4.1f}s {result}")
plain = TradingClient("FAKE", "FAKE", raw_data=True, url_override=URL)
attempt(plain, "accepted", [])
attempt(plain, "429 once", [(429, {"code": 1, "message": "slow down"})])
attempt(plain, "504 once", [(504, {"code": 1, "message": "gateway"})])
attempt(plain, "403", [(403, {"code": 40310000, "message": "insufficient buying power"})])
class Timeout(HTTPAdapter):
def send(self, request, **kw):
kw["timeout"] = (3, 2)
return super().send(request, **kw)
safer = TradingClient("FAKE", "FAKE", raw_data=True, url_override=URL)
safer._session.mount("http://", Timeout()) # use https:// against Alpaca
safer._retry_codes = [429] # private: recheck on upgrade
attempt(safer, "safer 504", [(504, {"code": 1, "message": "gateway"})])
attempt(safer, "safer hang", [("hang", 5)])Output on 5 November 2026 (raw_data=True keeps the mock short):
accepted POSTs=1 0.0s {'status': 'accepted'}
429 once POSTs=2 3.0s {'status': 'accepted'}
504 once POSTs=2 3.0s {'status': 'accepted'}
403 POSTs=1 0.0s APIError 403 40310000
safer 504 POSTs=1 0.0s APIError 504 1
safer hang POSTs=1 2.0s ReadTimeoutFilling, buying power checks and real error bodies need a paper key, so they were not run.
Why alpaca-py's default retry and missing timeout matter for orders
A 504 does not say the order failed, so an automatic resend can place it twice, and Alpaca's reference does not say what a repeated client order ID returns.
| Reply from mock | POSTs | Caller sees |
|---|---|---|
| 504 once | 2, after 3 seconds | Success, with no sign of the resend |
| 504 five times | 4, over 9 seconds | APIError 504 |
| 503 once | 1 | APIError 503 |
| Never answers | 1 | Blocked until the mock closed the socket at 12 seconds: no timeout is set |
The defaults sit in the SDK's source: 3 retries, 3 seconds apart, on codes 429 and 504. TradingClient has no argument for them, and the sample changes private attributes, so recheck them on every upgrade. Without a client_order_id both POSTs carried none, and the API reference says one is generated when absent, so two attempts could become two orders. The reference allows up to 128 characters and calls the ID unique, so set one on every order and test on paper what a duplicate returns. See client order ID for the general pattern.
After an unknown outcome, ask before resending: client.get_order_by_client_id(id), which called GET /v2/orders:by_client_order_id on the mock.
Alpaca WebSocket: trade updates and market data streams
Alpaca runs two kinds of stream, and alpaca-py logs their failures instead of raising them, so watch the logs and the time of the last message.
| Stream | URL | Notes |
|---|---|---|
| Trade updates | /stream on the paper or live host | trade_updates, binary frames on paper |
| Stock data | wss://stream.data.alpaca.markets/v2/iex, /v2/sip, /v2/delayed_sip | Many plans allow only one connection per endpoint |
| Test feed | wss://stream.data.alpaca.markets/v2/test | Always on, symbol FAKEPACA; still needs a key |
Data stream errors are 402 (auth failed), 405 (symbol limit), 406 (connection limit) and 409 (insufficient subscription). A fake key on the live test and IEX endpoints got connected, then 402 auth failed.
The documents conflict on trade stream login: the docs show {"action": "auth", "key": ..., "secret": ...}, while the SDK sends {"action": "authenticate", "data": {"key_id": ..., "secret_key": ...}}. A fake key got unauthorized both ways, while a login with no secret got invalid authentication format detected, so the server appears to parse both forms; only a real key can prove either.
Against a local mock speaking those protocols:
- Dropped socket:
TradingStreamreconnected, logged in and listened again by itself. The page read describes no replay of missed updates, so readGET /v2/ordersafter any reconnect. - Exception in your handler: logged, the stream continued, and that update was not delivered again.
- Error 406:
StockDataStreamloggedconnection limit exceededand kept retrying, 4 or 5 attempts in 12 seconds across reruns.run()did not raise, so the process looks healthy with no data. The SDK's optionaldata_timeoutcovers silent sockets.
Alpaca API pricing: stock data plans and limits
Alpaca's market data page lists two plans for stocks on the Trading API, Basic at no charge and Algo Trader Plus at $99 a month, as read on 5 November 2026.
| Item | Basic | Algo Trader Plus |
|---|---|---|
| Real-time coverage | IEX | All US stock exchanges |
| WebSocket symbols | 30 | Unlimited |
| Historical data | Since 2016, not the latest 15 minutes | Since 2016, no restriction |
| Historical calls | 200 a minute | 10,000 a minute |
Hypothetical example. A bot polling 40 symbols one call at a time every 10 seconds makes 40 x 6 = 240 calls a minute, above Basic's 200, and 40 symbols also exceed Basic's 30 on the stream.
Alpaca's market data FAQ (opens in a new tab) says recent SIP data without the plan returns subscription does not permit querying recent SIP data (code 42210000). Brokerage and regulatory fees are a separate schedule, not covered here. What a data license allows you to show others is in stock market data API.
Alpaca Trading API vs Broker API
The Trading API is for your own trading, and the Broker API (opens in a new tab) is for businesses that build brokerage services for end users, which raises licensing questions the pages read do not address.
| Item | Trading API | Broker API |
|---|---|---|
| Built for | Retail, algorithmic and proprietary traders | Trading apps and brokerage services for customers |
| Login | Key headers or HTTP Basic; client credentials not yet available | OAuth client credentials, 15-minute tokens |
| Named setups | Individuals and businesses | Broker-dealer (fully disclosed, omnibus) and registered adviser |
Running other people's money through one person's Trading API keys is not a shortcut to the second column. Ask counsel in the countries involved before serving anyone else.
Margin rules, TradingView webhooks and who may use this
Check two things older tutorials get wrong: the US day-trading rule changed in 2026, and Alpaca's TradingView connection is not a webhook.
- FINRA. Regulatory Notice 26-11 says new intraday margin standards replace the day trading margin requirements, effective 4 June 2026, and FINRA's investor page says firms may phase in through 20 October 2027 and may set higher requirements. It also says the new standard has no $25,000 minimum. Alpaca's page, updated 7 July 2026, says the pattern day trader definition is gone and that margin accounts typically need $2,000 in equity. The alpaca-py 0.45.0 notes say Alpaca stopped returning
pattern_day_trader,daytrade_countanddaytrading_buying_poweron 6 July 2026, so those fields are nowNone. The account reference (opens in a new tab) no longer lists them, yet still describes multiplier 4 as a PDT account. Do not hard-code the old rule; buying power fields with a real key were not tested. - TradingView. Alpaca's page (opens in a new tab) presents TradingView as a broker connection from the chart's trading panel and does not mention webhooks. An alpaca tradingview webhook setup would instead have an alert call a receiver you run, which then calls alpaca-py; TradingView webhook in Python covers the receiver, and TradingView's terms, cited at the top, address that use. TradingView's Help Center (opens in a new tab) also says its alerts are "not designed for automated trading".
Rules depend on your country, and account types and API access vary; no broker is recommended or ranked here. For readers in Turkey, the Capital Markets Board (SPK) said on 23 February 2023 that residents can trade leveraged forex only through institutions it has authorized, and Law No. 6362 provides access blocks for online offers from abroad (Article 99(4)) and criminal penalties for unauthorized activity (Article 109(2)).
Fincode quotes custom work through algorithmic trading and claims no prior Alpaca work.
Frequently asked questions
Is alpaca-py the official Alpaca Python SDK?
Yes. It is published from Alpaca's own GitHub organization, and the older alpaca-trade-api repository, archived on 17 June 2026, points to it.
Can I use Alpaca paper trading outside the US?
Alpaca's docs say anyone globally can create a paper-only account with an email address, limited to IEX data. Eligibility for a live account is a separate question that depends on your country.
How do I get an Alpaca API key?
Generate it in the Alpaca dashboard after signing up; paper and live keys are separate. Never put either in code you share.
What is the Alpaca API rate limit?
A support page dated December 2022 gives 200 Trading API requests per minute per account, with HTTP 429 above that; it is old, so measure it on your own key. Historical data calls are 200 or 10,000 a minute by plan, as read on 5 November 2026.
Does the $25,000 pattern day trader rule still apply?
FINRA replaced it with intraday margin standards effective 4 June 2026, with firms allowed to phase in through 20 October 2027. Firms can set higher requirements, so check your own broker.
Sources
- PyPI: alpaca-py 0.45.0 (5 November 2026) (opens in a new tab)
- GitHub: alpaca-trade-api-python (archived 17 June 2026) (opens in a new tab)
- Alpaca Docs: Paper Trading (opens in a new tab)
- Alpaca Docs: Authentication (opens in a new tab)
- Alpaca Docs: About Market Data API (plans and limits) (opens in a new tab)
- Alpaca Docs: Streaming Market Data (errors, test stream) (opens in a new tab)
- Alpaca Docs: WebSocket Streaming (trade updates) (opens in a new tab)
- Alpaca API reference: Create an order (client_order_id) (opens in a new tab)
- Alpaca Support: Usage limit on API calls (December 2022) (opens in a new tab)
- Alpaca Docs: The Intraday Margin Rule (updated 7 July 2026) (opens in a new tab)
- FINRA Regulatory Notice 26-11 (19 May 2026) (opens in a new tab)
- FINRA: Understanding the New Intraday Margin Requirements (20 April 2026) (opens in a new tab)
- TradingView: Terms of Use, section 3 (display-only use, read 5 November 2026) (opens in a new tab)
- SPK (Capital Markets Board): Notice on unauthorized leveraged transactions, 23 February 2023 (Turkish) (opens in a new tab)
- Capital Markets Law No. 6362, consolidated text, Articles 99 and 109 (Turkish) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.