Alpaca Broker API — Trading on Behalf of Accounts
SkillDocs & knowledgeYour AI can place and manage stock orders on Alpaca brokerage accounts. It handles orders by share count or dollar amount, including fractional shares, and tracks each order from placement through completion. It can also change or cancel open orders and check positions and buying power, which supports trading, recurring investing, and portfolio workflows.
Available today. Use it from your connected AI after setup.
No other account needed.
After adding it, connect an Alpaca brokerage account and start with a simple check like viewing buying power. Then try a small order to confirm everything works before relying on it for larger trades.
Then ask your AI: use the Alpaca Broker API — Trading on Behalf of Accounts skill
What your AI can do with it
- Place buy or sell orders by share count or dollar amount
- Buy fractional shares
- Set order types and how long each order stays active
- Track an order's status from placement to completion
- Change or cancel open orders
- Check account positions and available buying power
What this skill tells your AI
The instructions your AI receives, as published by alpacahq/alpaca-skills in skills/broker-api/trading-orders/SKILL.md and read by ahel’s review.
Place, modify, cancel, and track orders for an end-user account, and read positions & buying power. The defining feature of Broker API trading: account_id is in the path — you act for a user account, not your own.
Read
alpaca-broker-integrationfirst. Broker API + HTTP Basic auth. (The standalone Trading API uses/v2/orderswith no account in the path; everything else here transfers.)
Reference
- Guides:
https://docs.alpaca.markets/docs/orders-at-alpaca,https://docs.alpaca.markets/docs/fractional-trading - API ref:
https://docs.alpaca.markets/reference/postorder - Live schema:
alpaca-docsMCP →get-endpointtitle"Broker API"path/v1/trading/accounts/{account_id}/orders
1. Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/trading/accounts/{id}/orders | Create order |
| GET | /v1/trading/accounts/{id}/orders | List orders (filter by status, symbols, after…) |
| GET | /v1/trading/accounts/{id}/orders/{order_id} | Get order by ID |
| GET | /v1/trading/accounts/{id}/orders:by_client_order_id?client_order_id=… | Get by your client ID |
| PATCH | /v1/trading/accounts/{id}/orders/{order_id} | Replace (modify) order |
| DELETE | /v1/trading/accounts/{id}/orders/{order_id} | Cancel one order (204) |
| DELETE | /v1/trading/accounts/{id}/orders | Cancel all (207 Multi-Status) |
| POST | /v1/trading/accounts/{id}/orders/estimation | Cost-estimate an order |
| GET / DELETE | /v1/trading/accounts/{id}/positions[/{symbol_or_asset_id}] | List / close positions |
| GET | /v1/trading/accounts/{id}/account | Trading-account details (buying power etc.) |
2. Create-order request
Schema-required: type and time_in_force. Conditionally required: symbol, side, and exactly one of qty/notional.
// notional market buy (dollar-based, fractional)
{ "symbol": "AAPL", "notional": "25.00", "side": "buy", "type": "market", "time_in_force": "day",
"client_order_id": "your-own-uuid" }
// limit qty sell
{ "symbol": "AAPL", "qty": "3", "side": "sell", "type": "limit", "limit_price": "190.00", "time_in_force": "gtc" }
| Field | Values / notes |
|---|---|
symbol | required (except mleg multi-leg options) |
qty | decimal string, up to 9 dp. Fractional only for market+day |
notional | decimal string, up to 9 dp. Mutually exclusive with qty |
side | buy, sell (plus advanced: sell_short, …) |
type | market, limit, stop, stop_limit, trailing_stop |
time_in_force | day, gtc, opg, cls, ioc, fok |
limit_price / stop_price | required for limit/stop variants |
trail_price / trail_percent | one required for trailing_stop |
extended_hours | bool; only with type=limit and TIF day/gtc |
client_order_id | ≤128 chars; your idempotency key (auto-generated if omitted) |
order_class | simple (default), bracket, oco, oto, mleg |
take_profit / stop_loss | {limit_price} / {stop_price, limit_price?} for bracket/oco/oto |
position_intent | buy_to_open, sell_to_close, … |
qty XOR notional (verbatim rule): pass one or the other — supplying both → 400. In the response, whichever you didn't use comes back null.
3. Fractional / notional rules
- On by default for all accounts (live + paper).
- Asset must have
fractionable: true(check the Assets API — seealpaca-broker-market-data), elserequested asset is not fractionable. - TIF must be
dayfor fractional/notional. - Notional is limited to
marketandlimit(day); onlylimitfor extended hours. Fractionalqtyadditionally allowsstop/stop_limitper the guide. - No shorting fractional — all fractional sells are marked long.
- Precision: up to 9 decimal places for both
qtyandnotional.
4. Order status lifecycle
OrderStatus (the order object's status): new, partially_filled, filled, done_for_day, canceled, expired, replaced, pending_cancel, pending_replace, accepted, pending_new, accepted_for_bidding, stopped, rejected, suspended, calculated.
Order
status≠ trade-eventevent. The order object'sstatusis the enum above. The SSE trade-update stream reports a richereventenum that adds operational events not present as a status — includingheld(multi-leg secondary legs awaiting trigger),trade_bust,trade_correct,restated,order_cancel_rejected,order_replace_rejected. Soheldexists as a trade event but never as an order status. Seealpaca-broker-sse-events.
Terminal: filled, canceled, expired, rejected (and replaced for the original order). Everything else is in-flight.
Early-state distinctions (these trip people up):
accepted— received by Alpaca, not yet routed to a venue (common outside market hours).new— received and routed to exchanges; the usual initial live state.pending_new— routed but not yet accepted for execution (rare).
So the typical opening sequence is accepted → pending_new → new, then fills. Lesson: treat new/accepted/pending_new as "exists but not done." Persist the order on submit, then update on fill/cancel/reject events — don't block the user waiting for a terminal state synchronously.
5. Positions & trading account
Position key fields: symbol, asset_id, qty, qty_available (free of open orders), side (long/short), avg_entry_price, market_value, cost_basis, unrealized_pl, unrealized_plpc, current_price, change_today.
TradeAccount key fields:
buying_power(with marginmultiplier1–4),cash,cash_withdrawable,equity,last_equity.- Blockers:
trading_blocked,account_blocked,transfers_blocked,trade_suspended_by_user. multiplier,regt_buying_power,non_marginable_buying_power,long_market_value,initial_margin,maintenance_margin,sma.
Lesson — check buying power before notional orders. For a "spend $X" UX, read buying_power/cash first and reject/notify on insufficient funds, rather than letting Alpaca reject the order. (Cache it per account within a batch run to avoid re-fetching.)
PDT/day-trade fields are deprecated (since 2026-04-27, sunset 2026-07-06) following FINRA's intraday-margin rule change:
daytrade_count,pattern_day_trader,daytrading_buying_power,bod_dtbp, plus configdtbp_check/pdt_check. They still exist in the schema today but stop relying on them.
6. Documented gotchas
- Wash-trade rejection (403): if a user's two orders could self-cross (opposite sides, crossable prices), Alpaca rejects. Opposing market/stop pairs are always rejected; opposing limits rejected when buy-limit ≥ sell-limit. Use
bracket/oco/trailing_stopfor simultaneous take-profit + stop-loss — they're exempt. - Bracket constraints: requires both
take_profit.limit_priceandstop_loss.stop_price; TP must be above SL for a buy; no extended hours; TIFday/gtc; child legs activate only after the entry fully fills; canceling one cancels the group. - Notional orders can't be replaced — cancel and resubmit (IPO-class notional is the exception). Fractional
qtycan't be changed on replace ("full shares only"). - Replace ≠ guaranteed: a
200from PATCH can still be rejected if the original fills first; watch the trade-updates stream. Can't replace whileaccepted/pending_new/pending_cancel/pending_replace. - Cancel semantics: single cancel →
204, or422if no longer cancelable; cancel-all →207per-order results; close-all positions →207. Close-single accepts mutually-exclusiveqtyorpercentage.
7. Idempotency & recurring-invest lessons
- Always set
client_order_idfrom your own transaction record. It's your dedup key and lets you look the order up (orders:by_client_order_id) if the create response is lost. Note it dedups lookup, not necessarily replay — combine it with a local "already-submitted?" guard. - Recurring/scheduled buys (lesson): the robust pattern is — fetch pending invest instructions from your DB → check buying power → place a
notionalmarket/dayorder per instruction → record the returned order → mark the instruction done only after a successful create. On insufficient funds, cancel the instruction and notify, don't silently skip. Schedule the batch shortly before market open and respect the market clock (alpaca-broker-market-data). - Track fills via the trade events SSE stream, not by polling each order — see
alpaca-broker-sse-events.
Related skills: prices/assets/clock → alpaca-broker-market-data; fills in real time → alpaca-broker-sse-events; rate limits on bulk placement → alpaca-broker-rate-limits-resilience; money formatting → alpaca-broker-money-precision.
Signals
- GitHub stars
- 147
- Forks
- 16
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
alpaca-broker-trading-orders- Source
- github.com/alpacahq/alpaca-skills