How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/alpacahq/alpaca-skills --skill alpaca-broker-trading-ordersBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Alpaca Broker API — Trading on Behalf of Accounts
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.
Readalpaca-broker-integrationfirst for base URLs and auth (client-credentials Bearer token; legacy Basic still works). (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; fractionable only for market+day per the order schema |
notional | decimal string, up to 2 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 — see
alpaca-broker-market-data), elserequested asset is not fractionable. - TIF must be `day` for fractional/notional.
- Notional is limited to
marketandlimit(day); onlylimitfor extended hours. - No shorting fractional — all fractional sells are marked long.
- Precision: 2 decimal places for `notional`, 9 for `qty` (Broker API FAQ, "What is the precision for notional and qty"; the order schema's "2 decimal points" on
qtyis stale). Eligible types: the order schema says fractionalqtyonly onmarket+day; the Fractional Trading guide also acceptslimit/stop/stop_limitat TIFday— confirm in sandbox before relying on the wider set.
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-event `event`. The order object'sstatusis the enum above. The SSE trade-update stream reports a richereventenum that adds operational events with no Broker order status —trade_bust,trade_correct,restated,order_cancel_rejected,order_replace_rejected.heldis both: a trade event, and anOrderStatusin the Trading API enum though not in the Broker one, so don't assume the two enums match. 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).
An order usually reaches new directly; accepted/pending_new are rare intermediates. 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. Re-read it after every accepted order — each one consumes buying power.
PDT/day-trade fields are gone following FINRA's intraday-margin rule change:daytrade_count,pattern_day_trader,daytrading_buying_powerandbod_dtbpare absent from the currentTradeAccountschema, as are thedtbp_check/pdt_checkconfigurations. Don't code against them.
6. Documented gotchas
- Minimum order value: every buy order needs a market value of at least $1 or it's rejected with
422; sells are exempt. - Per-asset-class rules: options and crypto go through this same endpoint, gated by
asset_class— crypto rejectstime_in_force: day(onlygtc/ioc) and allows onlymarket/limit/stop_limit; options allowday/gtconly. Check the type/TIF matrix in theOrderType/TimeInForcedescriptions athttps://docs.alpaca.markets/reference/createorderforaccountrather than assuming the equity set. - 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_stop` for 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_id` from 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, skip this run and surface it; whether to cancel a standing instruction is a product decision. 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.

