npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alpacahq/alpaca-trade-api

v4.0.1

Published

TypeScript SDK for the Alpaca Trading and Market Data APIs.

Readme

@alpacahq/alpaca-trade-api

A single Node.js TypeScript SDK for the Alpaca Trading API and Market Data API. Both APIs live under their own namespace (trading / marketData) in one package, fronted by a unified Alpaca client with typed errors, resilience (retry / timeout / rate limiting), pagination helpers, ergonomic order builders, and real-time streaming.

Upgrading from 3.x? See the Migration guide — it maps every endpoint old → new, explains the ergonomic layer, and ships a codemod that automates most of the work. Both files are included in the published npm package.

Requirements

  • Node.js >= 20 (developed against v24) — the REST transport uses the platform-global fetch, Headers, URL, and AbortController. (Node 18 reached end-of-life in April 2025; the package declares engines.node >=20.)
  • Strict Node TypeScript projects may omit DOM libs; the REST declarations are portable and do not require "dom" in the consumer tsconfig.

Runtime compatibility

| Runtime | REST | Streaming | Notes | | --- | :---: | :---: | --- | | Node.js >= 20 | ✅ | ✅ | Primary target. | | Bun | ✅ | ✅ | Node-compatible (ws runs). | | Deno | ✅ | ❌ | Root auto-resolves to the REST build via the deno export condition. | | Cloudflare Workers / workerd | ✅ | ❌ | Root auto-resolves to the REST build (workerd / worker). | | Vercel Edge | ✅ | ❌ | Root auto-resolves to the REST build (edge-light). | | Browser | ✅ | ❌ | Resolves to the REST build (browser). Not recommended — see caveat. |

Legend: ✅ supported · ❌ not supported.

  • Streaming is Node/Bun only. The WebSocket clients use Node-compatible streaming modules, which don't run on edge or in the browser. On those targets the package's export conditions transparently resolve the root import to the streaming-free REST build, so REST works and the stream factories (stockStream, stream, ...) plus submitAndWait throw if called. For real-time streaming, run on Node or Bun.
  • Browser: technically works, but discouraged. Calling Alpaca directly from a browser ships your APCA_API_SECRET_KEY to the client. Prefer a server or proxy (see examples/marketdata-backend.ts) rather than embedding credentials in front-end code.

The same matrix plus the edge-resolution mechanics, module formats, and the REST-only entrypoint are consolidated on the docs site: Runtime & module compatibility.

Install

npm install @alpacahq/alpaca-trade-api

Migrating from 3.x? Follow the Migration guide.

Documentation

This README is the canonical, self-contained reference. There is also a Docusaurus documentation site — curated guides, a generated API reference, runtime compatibility, and the runnable examples — hosted at https://alpacahq.github.io/alpaca-trade-api-js/ and deployed from docs/ on every push to master. You can also read the whole thing locally in two commands:

npm --prefix docs install   # first time only
npm --prefix docs start     # dev server → http://localhost:3000/alpaca-trade-api-js/

Prefer the exact production build? Run npm --prefix docs run build (which regenerates the API reference, examples, and migration page first), then npm --prefix docs run serve. The guides are hand-written under docs/docs/; the API reference and examples pages are generated at build time from the SDK's capability maps and examples/; the site migration page is derived from the canonical MIGRATION.md.

Install the agent skill

Building on this SDK with an AI coding agent? This repo ships an Agent Skill that teaches agents the SDK's mental model, idioms, and where to look. Install it with the open skills CLI — it auto-detects your agent (Claude Code, Cursor, Codex, …) and installs there:

npx skills add alpacahq/alpaca-trade-api-js

The skill lives at skills/alpaca-trade-api-sdk/SKILL.md.

Quick start: the Alpaca client

The SDK ships ~16 trading and ~11 market-data Api classes. The Alpaca client bundles all of them (plus the real-time streams) behind a single constructor: pass credentials once and reach everything through the .trading and .marketData namespaces. Sub-APIs are created lazily and memoized.

import { Alpaca } from "@alpacahq/alpaca-trade-api";

const alpaca = new Alpaca({
  keyId: process.env.APCA_API_KEY_ID,
  secret: process.env.APCA_API_SECRET_KEY,
  paper: true, // default; set false for live trading
});

// REST — no manual Configuration / Api wiring
const account = await alpaca.trading.account.getAccount();
const positions = await alpaca.trading.positions.getAllOpenPositions();

// Ergonomic order placement (see "Placing orders")
await alpaca.trading.orders.market({
  symbol: "AAPL",
  qty: 1,
  side: "buy",
  clientOrderId: `quickstart-${crypto.randomUUID()}`,
});

// Streaming — shares the same credentials (market data ignores paper/live)
const bars = alpaca.marketData.stockStream({ feed: "iex" });
bars.onBar((b) => console.log(b.symbol, b.close));
bars.onConnect(() => bars.subscribeForBars(["AAPL", "MSFT"]));
bars.connect();

The paper flag controls the trading REST host (paper-api vs api) and the default trading-updates stream endpoint; market data always uses data.alpaca.markets. The trading / marketData namespaces remain available if you prefer to construct Api classes yourself:

import { trading, marketData } from "@alpacahq/alpaca-trade-api";

const orders = new trading.OrdersApi(new trading.Configuration({ keyId, secret }));
const stocks = new marketData.StockApi(new marketData.Configuration({ keyId, secret }));

How the facade is organized

The Alpaca client is two layers, and knowing the rule is the whole mental model:

  1. Generated (always present, uniform). Every generated REST method is reachable raw at alpaca.<group>.<resource>.<method>(...) — e.g. alpaca.trading.assets.getV2Assets() or alpaca.marketData.stocks.stockBars(...). Nothing is ever hidden or removed.
  2. Ergonomic (additive, never replaces layer 1). A curated set of hand-written conveniences sits on top: order builders, normalized market-data accessors, pagination, and workflow helpers. They are additions — the raw method each one builds on is still there.

So the rule you can rely on: if there's no ergonomic helper for what you need, the raw generated method is always available. You never have to guess whether a resource is "ergonomic" or "raw" — it's both.

Three maps make this queryable (each also has a lookup):

| Layer | Map | Lookup | | --- | --- | --- | | Generated methods | capabilities | findCapabilities("getAccount") | | Ergonomic helpers | ergonomicCapabilities | findErgonomic("market") | | Real-time streams | streamingCapabilities | — |

The ergonomic layer follows predictable naming conventions, so helpers are guessable:

  • Order builders: one verb method per kind on trading.orders (market, limit, stop, stopLimit, trailingStop, bracket, oco, oto), plus a generic submit escape hatch.
  • Normalized REST: get<Asset><Thing> returns canonical, symbol-keyed shapes (getStockBars, getCryptoTrades, ...); get<Asset>Candles returns the chart-ready columnar form. Each has a single-symbol get<Asset><Thing>For(symbol) variant (getStockBarsFor, getStockCandlesFor, ...) that returns the unwrapped value instead of a { [symbol]: ... } map. It reads only the exact requested key: if that key is absent, it returns [] (or empty Candles) and never substitutes another symbol.
  • Pagination: iterate<X> lazily yields across pages; collect<X> / collect<X>BySymbol eagerly returns them.
  • Workflow: verb-named one-offs (submitAndWait, closeAllPositions, getLatestPrice).

Authentication

Alpaca authenticates with two distinct headers (APCA-API-KEY-ID and APCA-API-SECRET-KEY). Pass keyId and secret directly.

const alpaca = new Alpaca({ keyId, secret });

Environment variables

Credentials may be resolved from the standard Alpaca environment variables. Scheme selection is deterministic:

  1. A non-empty explicit accessToken selects OAuth.
  2. Otherwise, any non-empty explicit keyId or secret selects key authentication; only the missing half is read from its matching key environment variable.
  3. With no explicit scheme, APCA_API_OAUTH_TOKEN takes precedence over an environment key pair.

Empty explicit strings are treated as absent.

This means a process-level OAuth token cannot silently replace an explicitly selected key account, while OAuth remains available explicitly or entirely through the environment.

| Option | Environment variable | | ------------- | ----------------------- | | keyId | APCA_API_KEY_ID | | secret | APCA_API_SECRET_KEY | | accessToken | APCA_API_OAUTH_TOKEN |

// With APCA_API_KEY_ID and APCA_API_SECRET_KEY set in the environment:
const alpaca = new Alpaca();

OAuth

Pass an accessToken to authenticate via OAuth2; it is sent as Authorization: Bearer <token>. An explicitly passed token takes precedence if key fields are also present.

const alpaca = new Alpaca({ accessToken });

Real-time streaming authenticates with a key/secret pair, so OAuth-only clients cannot open WebSocket streams.

Do not pass apiKey as a plain string — it would send the same value for both headers and Alpaca would reject it. The SDK throws a guided error if you try. To compute credentials lazily (e.g. from a vault), use the helper:

import { trading, auth } from "@alpacahq/alpaca-trade-api";
const config = new trading.Configuration({ apiKey: auth.apiKeyAuth({ keyId, secret }) });

Paper vs live

Trading defaults to paper. Switching to live is a deliberate flag, never an accidental missing host:

const live = new Alpaca({ keyId, secret, paper: false });

Named hosts are exported too: trading.TRADING_PAPER_HOST, trading.TRADING_LIVE_HOST, marketData.MARKET_DATA_HOST.

Resilience & configuration

All options below are optional and conservative by default. On the Alpaca client they are passed at the top level; on a raw Configuration they are identical fields.

const alpaca = new Alpaca({
  keyId,
  secret,

  // Abort a stalled request after N ms (default: 30000; set 0 to disable).
  timeoutMs: 10_000,

  // Use the market-data sandbox host for stock/option data (default false).
  // Crypto and news streams are production-only, so this flag isn't applied there.
  sandbox: false,

  // Automatic retry. The Alpaca client enables this by default (3 attempts);
  // pass a config to tune it or `retry: false` to disable.
  retry: {
    maxRetries: 2,            // 1 initial + 2 retries = 3 attempts (default)
    retryDelayMs: 250,        // base for exponential backoff (default 250)
    maxDelayMs: 5_000,        // cap per delay (default 5000)
    retryableStatuses: [408, 425, 429, 500, 502, 503, 504], // default
    respectRetryAfter: true,  // honor a Retry-After header (default true)
    onRetry: (e) => console.warn(`retry ${e.attempt}/${e.maxRetries} in ${e.delayMs}ms`, e.status ?? e.error),
    onGiveUp: (e) => console.error(`gave up after ${e.attempt} retries`, e.status ?? e.error),
  },

  // Proactive client-side rate limiting (the Alpaca client enables a safe
  // default; pass a config to tune or `false` to disable). See below.
  rateLimit: { maxRequests: 200, intervalMs: 60_000, maxConcurrent: 16 },

  userAgent: "my-app/1.0", // default `APCA-NODE/<sdk-version> <Runtime>/<runtime-version>`; "" disables

  redirect: "error", // default: reject 3xx so the APCA-API-* secret can't follow an off-host redirect ("follow" to opt out)
});

The default identifies both the SDK family/version and the execution runtime, for example APCA-NODE/4.0.0 Node/22.4.0. Runtime detection prefers Bun and Deno before Node so their npm-compatibility globals are not mislabeled.

Retry semantics

  • On by default on the Alpaca client (3 attempts = 1 initial + 2 retries); pass a retry config to tune it or retry: false to disable. Raw Api classes built from a bare Configuration are off unless you set retry (same opt-in model as the rate limiter).
  • The retryableStatuses (408, 425, 429, 500, 502, 503, 504 by default) are retried only for safe/idempotent verbs (GET/HEAD/OPTIONS/TRACE). A non-idempotent POST/PUT/PATCH/DELETE is never auto-retried (even on 429). In particular, order-placement POSTs are issued once and are never replayed by the transport.
  • Transient network failures (DNS, connection reset, TLS — surfaced as a FetchError) are also retried, again only for the safe verbs. A deliberate abort (caller AbortSignal or the timeoutMs deadline) is not retried.
  • Backoff is exponential (doubling per attempt) from retryDelayMs (250ms) up to maxDelayMs (5s), with ±20% jitter. A Retry-After header (seconds or HTTP-date) is honored over the computed delay when present.
  • Observability. Pass onRetry to be notified before each delayed retry and onGiveUp when a retryable failure exhausts all attempts. Each fires with a RetryEvent ({ method, url, attempt, maxRetries, delayMs, status?, error? }): status is set for status-based retries, error for network-error retries. These are pure observability hooks — exceptions thrown from them are swallowed so they can never break a request.

Order-submission safety

Give every order a stable, unique clientOrderId in the request body. It makes the order auditable and gives you a key for recovery, but it is not response replay: Alpaca rejects another order that reuses the same ID.

const clientOrderId = `mean-reversion-${crypto.randomUUID()}`;
const order = await alpaca.trading.orders.market({
  symbol: "AAPL",
  qty: 1,
  side: "buy",
  clientOrderId,
});

The SDK never auto-retries the placement POST. If a FetchError leaves the outcome ambiguous, query getOrderByClientOrderId({ clientOrderId }) before any further submission. Do not treat a lookup miss as proof that the first request was not accepted, and do not assume the order will eventually become visible; apply your application's reconciliation policy before deciding what to do next.

Timeouts

timeoutMs is a fresh per-attempt deadline and defaults to 30000 (30s); pass 0 to disable it. Each attempt budget includes the client-side rate-limit wait, pre middleware, fetch, error/post middleware, and successful or error response-body consumption. Retry backoff sits outside the completed attempt budget, and every retry starts with a new deadline.

A per-call AbortSignal (passed via initOverrides) spans the whole operation, including retry backoff. Cancellation in any phase rejects with FetchError whose cause is an AbortError (caller cancellation) or TimeoutError (timeoutMs). Cancellation is never retried, and POST remains excluded from automatic retry.

Redirects

Requests default to redirect: "error", so any 3xx redirect fails fast instead of being followed. Alpaca's APIs never redirect, and following one off-host would forward the APCA-API-KEY-ID/APCA-API-SECRET-KEY headers to the redirect target — unlike Authorization, custom headers are not stripped on a cross-origin redirect, so this prevents leaking your secret. Set redirect: "follow" (client option or per-call initOverrides) to opt back into the platform default if you front the API with a redirecting proxy.

Rate limiting

Alpaca enforces roughly 200 requests/minute per host. The Alpaca client enables a safe default token bucket (~200/min, applied independently to the trading and market-data hosts) so burst workloads self-throttle instead of tripping 429s. Tune it with a rateLimit config or pass rateLimit: false to opt out. When constructing raw Api classes the limiter is off unless you set rateLimit on the Configuration.

Typed errors

Non-2xx responses reject with an ApiError (a ResponseError subclass) exposing status, code, and message parsed from Alpaca's { code, message } error envelope; the raw Response stays on .response. Branch on the status-specific subclasses instead of magic numbers:

import { RateLimitError, NotFoundError, ApiError } from "@alpacahq/alpaca-trade-api";

try {
  await alpaca.trading.orders.getOrderByOrderID({ orderId });
} catch (err) {
  if (err instanceof RateLimitError) {
    console.warn(`rate limited; retry in ${err.retryAfterMs}ms`, err.rateLimit);
  } else if (err instanceof NotFoundError) {
    console.warn("no such order");
  } else if (err instanceof ApiError) {
    console.error(err.status, err.code, err.message);
  }
}

Subclasses: AuthError (401), PermissionError (403), NotFoundError (404), ValidationError (400/422), RateLimitError (429). Every ApiError also surfaces rateLimit (X-RateLimit-*), retryAfterMs, and requestId — Alpaca's X-Request-ID for the failed call. That id can't be looked up after the fact, so log it (or include it in a support ticket) when something fails:

catch (err) {
  if (err instanceof ApiError) {
    console.error(`request ${err.requestId} failed`, err.status, err.message);
  }
}

A failed fetch itself (network/abort) rejects with FetchError.

Response headers (withResponse)

The client methods return just the deserialized body. When you also need the HTTP status, response headers, or X-RateLimit-* metadata of a successful call, wrap the generated *Raw sibling (every method has one) with withResponse. It returns a typed AlpacaApiResponse<T>{ data, status, headers, rateLimit }:

import { withResponse } from "@alpacahq/alpaca-trade-api";

const res = await withResponse(alpaca.trading.account.getAccountRaw());
res.data;                    // typed Account (same as getAccount())
res.status;                  // 200
res.headers.get("X-Request-ID");
res.rateLimit?.remaining;    // parsed X-RateLimit-Remaining, when present

The body stream is read once, so use res.data rather than re-reading the underlying response.

Placing orders

alpaca.trading.orders is the generated OrdersApi plus one ergonomic method per common order kind that drops the postOrder({ postOrderRequest }) wrapper, accepts number | string amounts, and enforces the required fields per kind at compile time. Each returns the created Order; timeInForce defaults to "day". Supply a stable, unique clientOrderId for every live order so logs and recovery can correlate the submission with Alpaca.

await alpaca.trading.orders.market({
  symbol: "AAPL", qty: 1, side: "buy",
  clientOrderId: `market-${crypto.randomUUID()}`,
});
await alpaca.trading.orders.limit({
  symbol: "AAPL", qty: 1, side: "buy", limitPrice: 150,
  clientOrderId: `limit-${crypto.randomUUID()}`,
});
await alpaca.trading.orders.stop({ symbol: "AAPL", qty: 1, side: "sell", stopPrice: 140 });
await alpaca.trading.orders.stopLimit({ symbol: "AAPL", qty: 1, side: "sell", stopPrice: 140, limitPrice: 139.5 });
await alpaca.trading.orders.trailingStop({ symbol: "AAPL", qty: 1, side: "sell", trailPercent: 5 });

await alpaca.trading.orders.bracket({
  symbol: "AAPL", qty: 10, side: "buy", limitPrice: 150,
  takeProfit: { limitPrice: 155 },
  stopLoss: { stopPrice: 145, limitPrice: 144.5 },
});

For shapes the typed methods don't cover (e.g. multi-leg mleg), use alpaca.trading.orders.submit(input) or the raw postOrder. The pure builders are also exported under the orders namespace.

Workflow helpers

A few high-level flows that would otherwise be boilerplate:

// Verify credentials/connectivity without throwing (startup health check).
const check = await alpaca.trading.validateConnection();
if (!check.ok) throw new Error(`Alpaca auth failed (${check.status ?? "network"}): ${check.message}`);

// Latest trade price as a number (undefined if unavailable).
const price = await alpaca.marketData.getLatestPrice("AAPL");

// Close every open position (optionally cancelling open orders first).
await alpaca.trading.closeAllPositions({ cancelOrders: true });

// Wait for server acknowledgement of the trade-updates subscription, place
// once, then await a terminal state without placing again on stream reconnect.
const filled = await alpaca.trading.submitAndWait(
  {
    type: "market",
    symbol: "AAPL",
    qty: 1,
    side: "buy",
    clientOrderId: `workflow-${crypto.randomUUID()}`,
  },
  { timeoutMs: 30_000 },
);
console.log(filled.status, filled.filledAvgPrice);

submitAndWait preserves a supplied client ID or creates one once, and issues one placement request per invocation. It waits for Alpaca's server-side listening acknowledgement before placement and never re-places after a stream reconnect. One deadline covers stream connect, authentication, subscription, the REST placement, and the terminal-event wait. If placement fails with an ambiguous FetchError, the helper makes one getOrderByClientOrderId reconciliation request and continues waiting when appropriate; the generic order builders do not do this for you. A timeout can still leave the placement outcome ambiguous, so this helper does not promise exactly-once execution or eventual lookup visibility. Post-placement workflow failures reject with SubmitAndWaitError; inspect its clientOrderId, optional confirmed orderId, phase, placementAmbiguous, and cause. Reconcile the client ID before resubmitting when the placement remains ambiguous.

Pagination

Every paginated endpoint is iterable out of the box on the Alpaca client — you never thread page tokens or merge per-symbol arrays. iterate* lazily yields items across all pages; collect* eagerly returns them.

for await (const { symbol, value } of alpaca.marketData.iterateStockBars({
  symbols: ["AAPL", "MSFT"],
  timeframe: TimeFrame.Day,
  start: new Date("2024-01-01"),
})) {
  // value is a StockBar for symbol
}

const bars = await alpaca.marketData.collectStockBarsBySymbol({
  symbols: "AAPL,MSFT",
  timeframe: TimeFrame.Day,
  start: new Date("2024-01-01"),
});
bars.AAPL; // StockBar[]

const articles = await alpaca.marketData.collectNews({ symbols: "AAPL" });

for await (const activity of alpaca.trading.iterateActivities({ activityTypes: ["FILL"] })) {
  // ...
}

The same pattern exists for stock/crypto/option trades, quotes, bars and auctions, indexValues, forex rates, option snapshots/chain, iterateOptionsContracts, and collectCorporateActions. For custom cases the lower-level pagination namespace exposes the building blocks: paginate/ collect, paginateSymbolMap/collectBySymbol, paginateSymbolObjects/ collectSymbolObjects, and paginateCursor/collectCursor.

All token/cursor helpers track every visited value, not only the immediately previous one. A repeated token in a longer cycle such as A → B → A stops pagination before refetching A, after preserving all valid items or corporate action pages fetched so far.

Bounding large fetches

A multi-symbol collect*BySymbol (and the normalized get* accessors) accept a SymbolCollectOptions to keep big back-fills cheap. By default every symbol is multiplexed into one request whose page token is followed to exhaustion; pass options to bound memory and parallelize:

// Cap each symbol's history (stops paging once every symbol is full).
const recent = await alpaca.marketData.getStockBars(
  { symbols: ["AAPL", "MSFT"], timeframe: TimeFrame.Minute, start },
  { maxPerSymbol: 1_000 },
);

// Fetch a large basket in parallel: split into one request per symbol,
// up to 4 in flight. The client-side rate limiter still applies.
const basket = await alpaca.marketData.getStockBars(
  { symbols: bigList, timeframe: TimeFrame.Day, start },
  { concurrency: 4, chunkSize: 1, maxPerSymbol: 5_000 },
);

concurrency defaults to 1 (the single combined request); chunkSize (default 1) controls how many symbols share each parallel request. The generic pagination.collect/collectCursor take a maxItems cap, and pagination.collectBySymbol takes maxPerSymbol; pagination.mapConcurrent and pagination.chunk are exposed for custom fan-out.

Values & types

Money/quantities are wire-truthful numeric strings (no float64 precision loss). Parse or format with the values helpers; for exact arithmetic keep the string and feed a decimal library (big.js/decimal.js, not bundled).

import { values } from "@alpacahq/alpaca-trade-api";

values.toNumber(account.buyingPower);          // number | undefined
values.toNumberOr(account.cash, 0);            // number with fallback
values.formatMoney(account.equity);            // "$12,345.67" (display only)

Build timeframes with the validated builders instead of hand-writing strings like "1minute" (which the API rejects); the facade bar methods require the branded TimeFrameString these return:

import { TimeFrame, TimeFrameUnit, timeFrame } from "@alpacahq/alpaca-trade-api";

timeFrame(15, TimeFrameUnit.Minute); // "15Min"
TimeFrame.Day;                       // preset "1Day"

Multi-symbol market-data methods accept a comma-separated string or a string[]. Time fields: trading models parse timestamps to Date, and market-data models also type them as Date. Note that the multi-symbol/list responses deserialize their symbol-keyed maps verbatim, so nested timestamps can still arrive as ISO strings at runtime despite that type. The fix is to prefer the normalized accessors below (getStockBars, the single-symbol getStockBarsFor, etc.), which always hand back real Dates; only the raw generated map responses (e.g. alpaca.marketData.stocks.stockBars) carry the caveat, and there you can normalize with values.toDate / values.toISO. The same raw map responses also surface large 64-bit ids (crypto trade .i) as strings at runtime — see the id note under Values & types.

For nanosecond precision, every market-data Bar/Trade/Quote (both the REST canonical accessors and the live stream) also carries timestampRaw?: string — the original RFC-3339 timestamp with full sub-millisecond digits (e.g. "2024-01-02T03:04:05.678099211Z"). timestamp stays a convenient millisecond Date; reach for timestampRaw when you need the exact instant Alpaca reported. The canonical getIndexValues and getStockAuctions accessors carry the same timestampRaw.

For 64-bit ids, both the live stream and the REST canonical trade accessors (getStockTrades/getCryptoTrades) expose an exact string next to the numeric field — idRaw on trades, plus (stream-only) cancel-errors, news, and originalIdRaw/correctedIdRaw on corrections. Reach for idRaw whenever you compare, store, or key on an id: crypto trade ids run past 2^53, where a number silently loses precision. id stays a number (unchanged) for convenience, and other numeric fields stay plain numbers.

Low-level/raw models: the market-data transport parses JSON losslessly, so integer fields whose value exceeds 2^53 — in practice crypto trade ids — arrive as a string at runtime on the raw generated models (e.g. alpaca.marketData.crypto.cryptoTrades(...).trades[sym][i].i) even though the generated type says number. Prefer the canonical accessors (which give you both id and idRaw), or read the raw .i as the exact string. Stock/option ids, news ids, sizes, volumes, and counts stay plain numbers.

Normalized market-data shapes (REST + streaming unified)

The generated REST models keep Alpaca's compact wire keys (StockBar is { o, h, l, c, v, vw, n, t }), while the real-time stream surfaces readable camelCase. The marketDataShapes namespace bridges them onto one canonical Bar / Trade / Quote shape — the same type the streaming clients emit — so you can backfill history over REST and append live updates over the WebSocket without reconciling two shapes.

The Alpaca client exposes normalized accessors (auto-paginated, keyed by symbol) alongside the raw collect*/iterate* ones:

import { Alpaca, marketDataShapes, TimeFrame } from "@alpacahq/alpaca-trade-api";

const alpaca = new Alpaca({ keyId, secret });

// REST history as canonical Bars: { [symbol]: Bar[] }
const history = await alpaca.marketData.getStockBars({
  symbols: ["AAPL"], timeframe: TimeFrame.Day, start: new Date("2024-01-01"),
});

// Live bars arrive in the SAME shape - just append them.
const stream = alpaca.marketData.stockStream({ feed: "iex" });
stream.onBar((bar) => history.AAPL?.push(bar)); // bar is a Bar
stream.onConnect(() => stream.subscribeForBars(["AAPL"]));
stream.connect();

Normalized accessors: getStockBars/getCryptoBars/getOptionBars, getStockTrades/getCryptoTrades, getStockQuotes/getCryptoQuotes, and the chart-ready getStockCandles/getCryptoCandles. Each returns a { [symbol]: T } map; for a single symbol, the *For(symbol) variants (getStockBarsFor, getStockCandlesFor, ... one per accessor) return the unwrapped value directly so you skip the result[symbol] step. They use only the exact requested map key; an absent key returns [] or empty Candles instead of another symbol's data. For any other endpoint, normalize a raw response yourself with the pure mappers: marketDataShapes.toBar, toStockTrade/toCryptoTrade/toOptionTrade, toStockQuote/toCryptoQuote/toOptionQuote, and the *BySymbol helpers.

Chart-ready helpers

Reshape a Bar[] into the forms plotting libraries expect:

import { toCandles, toCandlestickSeries, toLineSeries } from "@alpacahq/alpaca-trade-api";

toCandles(history.AAPL);              // { time[], open[], high[], low[], close[], volume[] }
toCandles(history.AAPL, { time: "seconds" }); // unix seconds instead of epoch ms
toCandlestickSeries(history.AAPL);    // [{ time, open, high, low, close }]
toLineSeries(history.AAPL, "close");  // [{ time, value }]

These live in the marketDataShapes namespace too and are re-exported at the top level. Everything here is REST-only (no ws/msgpack), so it is available from the @alpacahq/alpaca-trade-api/rest entrypoint as well.

Data feeds & the free-tier 15-minute delay

A few market-data gotchas are worth knowing before your first request — they come from Alpaca's data plans, not the SDK:

  • Feeds. US-equity endpoints take a feed parameter: iex (free), sip (all US exchanges, paid), plus otc/boats. The SDK does not force a default for REST — when you omit feed, Alpaca picks the best feed your subscription allows (iex on the free plan), so a free key won't 403 on a default request. The streaming helpers default to feed: "iex" so a free key connects out of the box; pass { feed: "sip" } explicitly once you have a subscription.

  • The 15-minute rule. On the free plan, SIP data for the last 15 minutes is restricted. Two consequences:

    • Explicitly requesting feed: "sip" with end defaulting to now fails with 403 subscription does not permit querying recent SIP data. The SDK detects this 403 and appends guidance to the error message (pass { feed: "iex" }, move end back ≥15 min, or upgrade).
    • With iex, recent bars exist but the trailing ~15 minutes can be sparse or empty, so end: new Date() may look like it "returns nothing". If you need a guaranteed-populated window on the free tier, set end ~15 minutes in the past yourself.

    The SDK deliberately does not clamp end for you — doing so silently would hide data that paid subscribers are entitled to.

  • paper is irrelevant to market data. The paper flag only switches the trading host (paper-api vs api); every market-data REST/stream call goes to data.alpaca.markets regardless. Free vs paid data is governed by your subscription and the feed parameter, not by paper.

Real-time streaming

WebSocket clients for a market-data stream (stocks, crypto, options, news) and a trading stream (order/account updates). Both authenticate automatically, reconnect with backoff, dispatch current subscriptions after reconnect authentication, and ping/pong. The API is a typed EventEmitter: register listeners, then connect().

const stocks = alpaca.marketData.stockStream({ feed: "iex" }); // "iex" | "sip" | "delayed_sip"
stocks.onBar((bar) => pushToClients(bar)); // typed StreamBar
stocks.onError((msg) => console.error("stream error:", msg));
stocks.onConnect(() => stocks.subscribeForBars(["AAPL", "MSFT"]));
stocks.connect();

const updates = alpaca.trading.stream();
updates.onTradeUpdate((u) => console.log(u.event, u.order.symbol, u.order.clientOrderId));
updates.onConnect(() => updates.subscribeTradeUpdates());
updates.connect();

cryptoStream(), optionStream(), and newsStream() share the same surface.

Every stream also exposes:

  • Awaitable authenticationwhenAuthenticated() resolves with a typed StreamAuthResult (never rejects), or waitForAuthentication(timeoutMs?) for a boolean. Failures carry a STREAM_AUTH_STATUS (server_rejected with the server code, closed, timeout).
  • Reconnect lifecycleonReconnecting((attempt) => …) (1-based) and onReconnected(() => …) after re-authentication and re-subscription dispatch, distinct from the first onConnect. It does not promise server acknowledgement of those subscriptions.
  • A custom url on any stream (market-data included) to route through a proxy/gateway, plus a callbackExecutor to offload listener work — a throwing listener is logged and can never break the stream.
const stocks = alpaca.marketData.stockStream({
  feed: "iex",
  url: "wss://proxy.internal/v2/iex", // optional: override the derived endpoint
  callbackExecutor: (task) => queueMicrotask(task), // optional: offload listeners
});
stocks.onReconnecting((attempt) => console.warn(`reconnecting (attempt ${attempt})`));
stocks.onReconnected(() => console.info("reconnected; subscriptions dispatched"));
stocks.connect();

const result = await stocks.whenAuthenticated();
if (!result.authenticated) {
  console.error(`stream auth failed: ${result.status} ${result.code ?? ""} ${result.message}`);
}

Crypto and news streams are production-only (no sandbox endpoint): pass an explicit url if you must point them elsewhere; otherwise sandbox: true throws.

Shared stream lifecycle (all streams)

Every stream — trading and market-data — shares this lifecycle surface in addition to its data handlers:

| Member | Description | | --- | --- | | connect() / disconnect() | Open / close the socket (disconnect suppresses auto-reconnect). | | onConnect / onDisconnect / onStateChange / onError | Lifecycle + error listeners. | | onReconnecting((attempt) => …) | Fires before each automatic reconnect (1-based attempt). | | onReconnected(() => …) | Fires after reconnect authentication and re-subscription dispatch (not server acknowledgement). | | whenAuthenticated(): Promise<StreamAuthResult> | Resolves with the first-auth outcome; never rejects. | | waitForAuthentication(timeoutMs?): Promise<boolean> | true on auth, false on failure/close/timeout. | | waitForAuthenticationResult(timeoutMs?) | Typed result; a caller-side timeout doesn't settle the real outcome. |

StreamAuthResult is { status, authenticated, code?, message } where status is a STREAM_AUTH_STATUS (authenticated, server_rejected, closed, timeout). Server rejections (bad credentials, etc.) include the numeric code.

Common stream options (in addition to feed/paper/sandbox): reconnect, maxReconnectAttempts (UNLIMITED_RECONNECT_ATTEMPTS to retry forever), backoff, initialReconnectMs, maxReconnectMs, reconnectJitter, pingIntervalMs, pongWaitMs, url (override the endpoint), and callbackExecutor (offload + isolate listener callbacks).

Stream state is scoped to the socket generation that created it: stale socket callbacks and timers cannot mutate a newer connection, pings start only while open, and manual disconnect() emits disconnect exactly once. Malformed payloads, decode/mapper failures, trading action: "error" frames, and listener failures surface through onError / CLIENT_ERROR without escaping callbacks or crashing the process.

Capability map (which method lives where)

The capabilities namespace maps each generated facade accessor to its underlying Api class and common methods; findCapabilities(name) answers "where does this method live?":

import { capabilities, findCapabilities } from "@alpacahq/alpaca-trade-api";

findCapabilities("getAccount");
// [{ accessor: "trading.account", api: "AccountsApi", group: "trading", ... }]

The ergonomic (layer 2) helpers have their own map, ergonomicCapabilities, with a matching findErgonomic(name) lookup — so "is there a helper for this, and where?" is answerable the same way:

import { ergonomicCapabilities, findErgonomic } from "@alpacahq/alpaca-trade-api";

findErgonomic("market");
// [{ accessor: "trading.orders", kind: "orderBuilder", wraps: "OrdersApi.postOrder", ... }]
findErgonomic("getStockBars");
// [{ accessor: "marketData", kind: "normalized", ... }]

For the full, per-method listing of both layers (description + example for every method), see the generated API reference below.

Observability

Built-in middleware for logging and metrics, layered on the transport's pre/post/onError hooks. Pass them via middleware; they observe only (never alter the request), so they compose with retries and with each other.

import { Alpaca, middleware } from "@alpacahq/alpaca-trade-api";

const alpaca = new Alpaca({
  keyId,
  secret,
  middleware: [
    // One log line per request attempt: method, url, status, duration, requestId.
    middleware.loggingMiddleware({ logger: console, level: "info" }),
    // A metric per request attempt for Prometheus / StatsD / OpenTelemetry.
    middleware.metricsMiddleware({
      onRequest: (m) =>
        statsd.timing("alpaca.request", m.durationMs, { method: m.method, status: m.status }),
    }),
  ],
});

loggingMiddleware redacts the APCA-* and Authorization headers by default (and only includes headers at all when logHeaders: true). Both accept a genRequestId to supply your own correlation ids.

Dependencies

The REST client needs nothing beyond the Node platform globals. The streaming clients (WebSockets) pull in two small runtime dependencies — ws and @msgpack/msgpack. At runtime the Alpaca facade only constructs them when you actually open a stream, but the root entrypoint's module graph statically includes them (it re-exports the streaming namespace), so a bundler resolving @alpacahq/alpaca-trade-api will see ws / @msgpack/msgpack. If you only use REST — or you target an edge/browser runtime where ws cannot run — import from the @alpacahq/alpaca-trade-api/rest subpath (or rely on the automatic edge resolution described in Module formats) and they are never pulled in.

REST-only entrypoint

If you never open a stream, import from @alpacahq/alpaca-trade-api/rest to keep the ws / @msgpack/msgpack dependencies out of your module graph (smaller bundles, faster cold starts). It re-exports everything except the streaming namespace. The Alpaca facade is the same class, so all REST methods work unchanged; the stream factories (stockStream, stream, ...) and submitAndWait throw if called from this entrypoint — import from @alpacahq/alpaca-trade-api when you need streams. The REST runtime graph and published declarations contain no Node, ws, or msgpack requirements, supporting strict Node projects without DOM libraries and edge consumers with the same facade.

import { Alpaca } from "@alpacahq/alpaca-trade-api/rest";

On edge and browser runtimes you usually don't need to reach for this subpath explicitly — the root entrypoint resolves here automatically (see Module formats).

Testing your integration

@alpacahq/alpaca-trade-api/testing provides a network-free harness so your unit tests don't hit Alpaca. mockFetch answers canned responses by method + path; createMockAlpaca wires one into a ready Alpaca client (dummy credentials, rate limiting off).

import { createMockAlpaca } from "@alpacahq/alpaca-trade-api/testing";

const alpaca = createMockAlpaca([
  { method: "GET", path: "/v2/account", body: { account_number: "PA42", status: "ACTIVE" } },
  { path: /\/v2\/stocks\/[A-Z]+\/trades\/latest$/, respond: ({ url }) => ({
      symbol: url.pathname.split("/")[3],
      trade: { p: 99.5 },
    }) },
]);

const account = await alpaca.trading.account.getAccount(); // { accountNumber: "PA42", ... }
const price = await alpaca.marketData.getLatestPrice("AAPL"); // 99.5

Routes match the first entry whose path (exact string or RegExp) and optional method match; unmatched requests get your fallback or a descriptive 404. A route's body is JSON-encoded automatically (objects) or sent verbatim (strings); respond is the dynamic escape hatch.

Module formats (ESM & CJS)

The package ships both native ESM (dist/index.mjs) and CommonJS (dist/index.js), selected via conditional exports, with per-format type declarations and sideEffects: false for tree-shaking.

import { Alpaca } from "@alpacahq/alpaca-trade-api";       // ESM
const { Alpaca } = require("@alpacahq/alpaca-trade-api");  // CJS

Dual-package caveat: don't load the SDK through both import and require in the same process if you rely on instanceof against its exported classes (e.g. ApiError), or you may compare against two copies.

Edge & browser runtimes

The streaming clients use Node-compatible WebSocket/EventEmitter modules, which don't run on edge runtimes (Cloudflare Workers / workerd, Vercel Edge, Deno) or in the browser. To keep the root import working there, the package exports map declares workerd, worker, edge-light, deno, and browser conditions that resolve @alpacahq/alpaca-trade-api to the streaming-free REST-only build automatically — so a plain import { Alpaca } from "@alpacahq/alpaca-trade-api" builds and runs on those targets without loading the streaming implementation.

The trade-off is the same as importing /rest directly: REST works unchanged, but the stream factories (stockStream, stream, ...) and submitAndWait throw. For real-time streaming, run on Node and import the root entry there.

Development

npm install      # also builds via the `prepare` script
npm run build    # tsup (esbuild) -> dual ESM+CJS + types in dist/
npm run typecheck # tsc --noEmit (type authority; does not emit)
npm test         # vitest
npm run generate:offline # reproduce generated REST trees from pinned specs

dist/ is git-ignored and produced by the build (and automatically on npm publish / npm pack via prepare). Runnable end-to-end examples live in examples/.

OpenAPI Generator reproducibly derives the REST clients/models under src/trading/{apis,models} and src/market-data/{apis,models} from the committed pinned specs. Never hand-edit those trees; customization belongs in tooling/ templates/overlays, while facade, pagination, streaming, and shared transport behavior stays in hand-written modules.

Generated API docs describe only that committed snapshot. A live npm run generate -- --dry-run --yes preview is not adoption. Real non-interactive adoption refuses removed schemas/operations unless an owner explicitly supplies --allow-breaking-spec-removals; see tooling/GENERATION.md.

Background

  • One package, two namespaces. The Trading and Market Data APIs are exposed as the trading and marketData namespaces of a single package. This avoids collisions between the two specs, which both define a CorporateActionsApi and overlapping model names.

API reference

Every method on the facade — all generated REST methods, the real-time streaming factories, and the ergonomic helpers — with a one-line description and a short example. This section is generated from src/capabilities.ts plus a hand-maintained examples map; run npm run docs:api to regenerate it (a test fails the build if it drifts out of sync). Headings are the real facade call paths, so every entry is individually anchor-linkable.

Trading API

alpaca.trading.account — AccountsApi

Account details, balances, buying power and status.

alpaca.trading.account.getAccount

Account details, balances, buying power and status.

await alpaca.trading.account.getAccount();

alpaca.trading.accountActivities — AccountActivitiesApi

Account activity history (fills, fees, dividends, transfers).

alpaca.trading.accountActivities.getAccountActivities

List account activities (fills, fees, dividends, transfers), newest first.

await alpaca.trading.accountActivities.getAccountActivities({
  activityTypes: ["FILL"],
  pageSize: 50,
});
alpaca.trading.accountActivities.getAccountActivitiesByActivityType

List activities of a single type (e.g. only fills).

await alpaca.trading.accountActivities.getAccountActivitiesByActivityType({
  activityType: "FILL",
});

alpaca.trading.accountConfigurations — AccountConfigurationsApi

Read and update trading account configuration.

alpaca.trading.accountConfigurations.getAccountConfig

Read the account's trading configuration.

await alpaca.trading.accountConfigurations.getAccountConfig();
alpaca.trading.accountConfigurations.patchAccountConfig

Update trading configuration (e.g. block short selling).

await alpaca.trading.accountConfigurations.patchAccountConfig({
  accountConfigurations: { noShorting: true },
});

alpaca.trading.assets — AssetsApi

Tradable assets, option contracts and instrument reference data.

alpaca.trading.assets.getV2Assets

List tradable assets, filterable by class, status and exchange.

await alpaca.trading.assets.getV2Assets({
  status: "active",
  assetClass: "us_equity",
});
alpaca.trading.assets.getV2AssetsSymbolOrAssetId

Fetch a single asset by symbol or asset id.

await alpaca.trading.assets.getV2AssetsSymbolOrAssetId({
  symbolOrAssetId: "AAPL",
});
alpaca.trading.assets.getOptionsContracts

List option contracts for underlying symbols (paginated).

await alpaca.trading.assets.getOptionsContracts({
  underlyingSymbols: "AAPL",
  limit: 100,
});
alpaca.trading.assets.getOptionContractSymbolOrId

Fetch a single option contract by symbol or id.

await alpaca.trading.assets.getOptionContractSymbolOrId({
  symbolOrId: "AAPL250117C00150000",
});

alpaca.trading.calendar — CalendarApi

Market calendar (trading days, open/close sessions).

alpaca.trading.calendar.calendar

Market calendar (sessions) for a market and date range.

await alpaca.trading.calendar.calendar({
  market: "us_equity",
  start: new Date("2024-01-01"),
  end: new Date("2024-01-31"),
});
alpaca.trading.calendar.legacyCalendar

Legacy market-calendar endpoint (prefer calendar).

await alpaca.trading.calendar.legacyCalendar({
  start: new Date("2024-01-01"),
  end: new Date("2024-01-31"),
});

alpaca.trading.clock — ClockApi

Market clock (current time, next open/close).

alpaca.trading.clock.clock

Current market clock: open/closed and next open/close.

await alpaca.trading.clock.clock();
alpaca.trading.clock.legacyClock

Legacy market-clock endpoint (prefer clock).

await alpaca.trading.clock.legacyClock();

alpaca.trading.corporateActions — CorporateActionsApi

Corporate-action announcements (splits, dividends, mergers).

alpaca.trading.corporateActions.getV2CorporateActionsAnnouncements

Deprecated: corporate-action announcements over a date range.

await alpaca.trading.corporateActions.getV2CorporateActionsAnnouncements({
  caTypes: "dividend",
  since: "2024-01-01",
  until: "2024-01-31",
});
alpaca.trading.corporateActions.getV2CorporateActionsAnnouncementsId

Deprecated: a single corporate-action announcement by id.

await alpaca.trading.corporateActions.getV2CorporateActionsAnnouncementsId({
  id: "be3c368a-4c7c-4384-808e-f02c9f5a8afe",
});

alpaca.trading.cryptoFunding — CryptoFundingApi

Crypto wallets, transfers and whitelisted withdrawal addresses.

alpaca.trading.cryptoFunding.createCryptoTransferForAccount

Initiate a crypto withdrawal/transfer for the account.

await alpaca.trading.cryptoFunding.createCryptoTransferForAccount({
  createCryptoTransferRequest: {
    amount: "0.5",
    address: "0xabc...",
    asset: "ETH",
  },
});
alpaca.trading.cryptoFunding.getCryptoFundingTransfer

Fetch a single crypto transfer by id.

await alpaca.trading.cryptoFunding.getCryptoFundingTransfer({
  transferId: "f1...e9",
});
alpaca.trading.cryptoFunding.listCryptoFundingTransfers

List crypto transfers for the account.

await alpaca.trading.cryptoFunding.listCryptoFundingTransfers();
alpaca.trading.cryptoFunding.getCryptoTransferEstimate

Estimate fees for a crypto transfer.

await alpaca.trading.cryptoFunding.getCryptoTransferEstimate({
  asset: "ETH",
  fromAddress: "0xabc...",
  toAddress: "0xdef...",
  amount: "0.5",
});
alpaca.trading.cryptoFunding.listCryptoFundingWallets

List the account's crypto wallets.

await alpaca.trading.cryptoFunding.listCryptoFundingWallets({
  asset: "ETH",
});
alpaca.trading.cryptoFunding.createWhitelistedAddress

Whitelist a crypto withdrawal address.

await alpaca.trading.cryptoFunding.createWhitelistedAddress({
  createWhitelistedAddressRequest: { address: "0xabc...", asset: "ETH" },
});
alpaca.trading.cryptoFunding.deleteWhitelistedAddress

Remove a whitelisted crypto address.

await alpaca.trading.cryptoFunding.deleteWhitelistedAddress({
  whitelistedAddressId: "a1...c2",
});
alpaca.trading.cryptoFunding.listWhitelistedAddress

List whitelisted crypto withdrawal addresses.

await alpaca.trading.cryptoFunding.listWhitelistedAddress();

alpaca.trading.events — EventsApi

Server-sent event streams for account activity.

alpaca.trading.events.subscribeToActivitiesSSE

Server-sent event stream of account activities.

await alpaca.trading.events.subscribeToActivitiesSSE({
  sinceId: "20240101000000000::...",
});

alpaca.trading.locates — LocatesApi

Easy-to-borrow locate requests, listings and quotes.

alpaca.trading.locates.createLocates

Create an easy-to-borrow locate request for a short sale.

await alpaca.trading.locates.createLocates({
  createLocateRequest: { symbol: "AAPL", qty: 100 },
  idempotencyKey: crypto.randomUUID(),
});
alpaca.trading.locates.getLocate

Fetch a single locate request by id.

await alpaca.trading.locates.getLocate({ locateId: "loc_123" });
alpaca.trading.locates.listLocateQuotes

Locate availability and pricing for one or more symbols.

await alpaca.trading.locates.listLocateQuotes({ symbols: "AAPL,TSLA" });
alpaca.trading.locates.listLocates

List locate requests, filtered by status, symbol or date range.

await alpaca.trading.locates.listLocates({ status: "active" });

alpaca.trading.orders — OrdersApi

Place, read, replace and cancel orders.

alpaca.trading.orders.getAllOrders

List orders, filterable by status, side and symbol.

await alpaca.trading.orders.getAllOrders({ status: "open", limit: 100 });
alpaca.trading.orders.postOrder

Place one order (raw); include a stable, unique client ID for audit and recovery.

const clientOrderId = crypto.randomUUID();
await alpaca.trading.orders.postOrder({ postOrderRequest: { symbol: "AAPL", qty: "1", side: "buy", type: "market", timeInForce: "day", clientOrderId } });
alpaca.trading.orders.getOrderByOrderID

Fetch a single order by its order id.

await alpaca.trading.orders.getOrderByOrderID({ orderId: "f1...e9" });
alpaca.trading.orders.getOrderByClientOrderId

Look up an order by its client ID, including to reconcile an ambiguous placement before submitting again.

const clientOrderId = "the-id-recorded-before-placement";
const order = await alpaca.trading.orders.getOrderByClientOrderId({ clientOrderId });
alpaca.trading.orders.patchOrderByOrderId

Replace (amend) an open order.

await alpaca.trading.orders.patchOrderByOrderId({
  orderId: "f1...e9",
  patchOrderRequest: { qty: "2" },
});
alpaca.trading.orders.deleteOrderByOrderID

Cancel a single open order.

await alpaca.trading.orders.deleteOrderByOrderID({ orderId: "f1...e9" });
alpaca.trading.orders.deleteAllOrders

Cancel all open orders.

await alpaca.trading.orders.deleteAllOrders();

alpaca.trading.portfolioHistory — PortfolioHistoryApi

Time series of account equity / P&L.

alpaca.trading.portfolioHistory.getAccountPortfolioHistory

Time series of account equity and profit/loss.

await alpaca.trading.portfolioHistory.getAccountPortfolioHistory({
  period: "1M",
  timeframe: "1D",
});

alpaca.trading.positions — PositionsApi

Open positions; close positions; exercise options.

alpaca.trading.positions.getAllOpenPositions

List all open positions.

await alpaca.trading.positions.getAllOpenPositions();
alpaca.trading.positions.getOpenPosition

Fetch a single open position by symbol or asset id.

await alpaca.trading.positions.getOpenPosition({ symbolOrAssetId: "AAPL" });
alpaca.trading.positions.deleteAllOpenPositions

Liquidate every open position (optionally cancel orders first).

await alpaca.trading.positions.deleteAllOpenPositions({
  cancelOrders: true,
});
alpaca.trading.positions.deleteOpenPosition

Close a position: whole, partial qty, or a percentage.

await alpaca.trading.positions.deleteOpenPosition({
  symbolOrAssetId: "AAPL",
  percentage: 50,
});
alpaca.trading.positions.optionExercise

Exercise a held option position.

await alpaca.trading.positions.optionExercise({
  symbolOrContractId: "AAPL250117C00150000",
});
alpaca.trading.positions.optionDoNotExercise

Submit a do-not-exercise instruction for an option position.

await alpaca.trading.positions.optionDoNotExercise({
  symbolOrContractId: "AAPL250117C00150000",
});

alpaca.trading.tokenization — TokenizationApi

Tokenization requests and minting.

alpaca.trading.tokenization.getTokenizationRequest

Fetch a tokenization request by its Alpaca request id.

await alpaca.trading.tokenization.getTokenizationRequest({
  tokenizationRequestId: "req_123",
});
alpaca.trading.tokenization.getTokenizationRequestByClientRequestID

Fetch the latest tokenization request carrying a client-supplied request id.

await alpaca.trading.tokenization.getTokenizationRequestByClientRequestID({
  clientRequestId: "mint-2026-001",
});
alpaca.trading.tokenization.getTokenizationRequests

List tokenization (mint/redeem) requests.

await alpaca.trading.tokenization.getTokenizationRequests({
  status: "completed",
});
alpaca.trading.tokenization.postTokenizationMint

Submit a tokenization mint request.

await alpaca.trading.tokenization.postTokenizationMint({
  tokenizationMintRequest: { underlyingSymbol: "AAPL", quantity: "1" },
});

alpaca.trading.watchlists — WatchlistsApi

Create and manage watchlists and their assets.

alpaca.trading.watchlists.getWatchlists

List all watchlists.

await alpaca.trading.watchlists.getWatchlists();
alpaca.trading.watchlists.getWatchlistById

Fetch a single watchlist by id.

await alpaca.trading.watchlists.getWatchlistById({
  watchlistId: "f1...e9",
});
alpaca.trading.watchlists.getWatchlistByName

Fetch a single watchlist by name.

await alpaca.trading.watchlists.getWatchlistByName({ name: "My List" });
alpaca.trading.watchlists.postWatchlist

Create a watchlist with an initial set of symbols.

await alpaca.trading.watchlists.postWatchlist({
  createWatchlistRequest: { name: "Tech", symbols: ["AAPL", "MSFT"] },
});
alpaca.trading.watchlists.updateWatchlistById

Update a watchlist (name and/or symbols) by id.

await alpaca.trading.watchlists.updateWatchlistById({
  watchlistId: "f1...e9",
  updateWatchlistRequest: { name: "Renamed" },
});
alpaca.trading.watchlists.updateWatchlistByName

Update a watchlist (name and/or symbols) by name.

await alpaca.trading.watchlists.updateWatchlistByName({
  name: "Tech",
  updateWatchlistRequest: { symbols: ["AAPL"] },
});
alpaca.trading.watchlists.addAssetToWatchlist

Add an asset to a watchlist by id.

await alpaca.trading.watchlists.addAssetToWatchlist({
  watchlistId: "f1...e9",
  addAssetToWatchlistRequest: { symbol: "NVDA" },
});
alpaca.trading.watchlists.addAssetToWatchlistByName

Add an asset to a watchlist by name.

await alpaca.trading.watchlists.addAssetToWatchlistByName({
  name: "Tech",
  addAssetToWatchlistRequest: { symbol: "NVDA" },
});
alpaca.trading.watchlists.removeAssetFromWatchlist

Remove an asset from a watchlist by id.

await alpaca.trading.watchlists.removeAssetFromWatchlist({
  watchlistId: "f1...e9",
  symbol: "NVDA",
});
alpaca.trading.watchlists.deleteWatchlistById

Delete a watchlist by id.

await alpaca.trading.watchlists.deleteWatchlistById({
  watchlistId: "f1...e9",
});
alpaca.trading.watchlists.deleteWatchlistByName

Delete a watchlist by name.

await alpaca.trading.watchlists.deleteWatchlistByName({ name: "Tech" });

Market Data API