alpaca-data
alpaca-data is an async Rust client for the Alpaca Market Data HTTP API.
Quick links:
- crates.io: https://crates.io/crates/alpaca-data
- Documentation: https://wmzhai.github.io/alpaca-data-rs/
The crate is built around two constraints:
- The official Alpaca Market Data HTTP API is the only semantic source of truth.
- Public Rust naming is idiomatic Rust, while request and response field words use the official API terms.
Status
- Current branch baseline:
v0.11.1 - Implemented resource families:
stocks,options,crypto,news,corporate_actions - This repository does not cover Trading API, Broker API, WebSocket, or SSE
- This crate is async-only
- crates.io package:
alpaca-data - Public docs include a GitHub Pages site, generated API reference pages, rustdoc links, API coverage docs, and a tag-triggered release workflow
Release automation is intentionally tag-triggered only and follows GitHub-hosted stable. After the initial manual crates.io bootstrap release, the github-pages workflow runs the standard Rust validation steps, publishes the crate to crates.io through Trusted Publishing, deploys the documentation build, and then creates or updates the matching GitHub Release from the corresponding CHANGELOG.md section only on pushed release tags such as vX.Y.Z. The manifest intentionally omits rust-version until an audited MSRV policy exists.
Design Contract
Official HTTP API first
- Endpoint semantics follow the official Alpaca Market Data API.
- Request fields and response fields use the original official words.
- Rust-specific adaptation is kept minimal and only used where the language requires it, such as
r#type.
Idiomatic Rust public API
- Crate name:
alpaca_data - Root client:
alpaca_data::Client - Resource accessors:
stocks(),options(),crypto(),news(),corporate_actions() - Modules are lowercase, types are
PascalCase, methods and fields aresnake_case
Two API layers
The crate exposes two layers:
- Mirror layer: direct Rust wrappers for the official HTTP endpoints
- Convenience layer:
*_alland*_streamhelpers on top of official paginated endpoints
The convenience layer never changes the official payload words. It only automates pagination.
Typed numeric public API fields and request filters use exact rust_decimal::Decimal values so the client preserves API precision and trailing-zero scale with exact decimal decoding.
Request guardrails stay official-only
- The crate fails fast with
Error::InvalidRequestonly for clearly documented Alpaca request rules. - Examples include empty required symbol lists, blank required single-path identifiers such as
symbolorunderlying_symbol, documentedlimitbounds, the options symbol-list cap, and the corporate-actionsidsexclusivity rule. - The crate does not silently auto-chunk mirror requests to work around documented hard limits.
Coverage Summary
Stocks
- Historical batch:
auctions,bars,quotes,trades - Historical single-symbol:
auctions_single,bars_single,quotes_single,trades_single - Convenience:
auctions_all,auctions_stream,bars_all,bars_stream,quotes_all,quotes_stream,trades_all,trades_stream - Single-symbol convenience:
auctions_single_all,auctions_single_stream,bars_single_all,bars_single_stream,quotes_single_all,quotes_single_stream,trades_single_all,trades_single_stream - Latest:
latest_bars,latest_bar,latest_quotes,latest_quote,latest_trades,latest_trade - Snapshots and metadata:
snapshots,snapshot,condition_codes,exchange_codes
Options
- Historical:
bars,trades - Convenience:
bars_all,bars_stream,trades_all,trades_stream - Latest:
latest_quotes,latest_trades - Snapshot family:
snapshots,snapshots_all,snapshots_stream,chain,chain_all,chain_stream - Metadata:
condition_codes,exchange_codes
Crypto
- Historical:
bars,quotes,trades - Convenience:
bars_all,bars_stream,quotes_all,quotes_stream,trades_all,trades_stream - Latest:
latest_bars,latest_quotes,latest_trades,latest_orderbooks - Snapshots:
snapshots
News
list,list_all,list_stream
Corporate Actions
list,list_all,list_stream
Quick Start
Install from crates.io:
[]
= "0.11.1"
= "1"
= { = "1", = ["macros", "rt-multi-thread"] }
Build a client:
use Client;
let client = new;
let client = builder.build?;
# Ok::
ClientBuilder, Client, and the resource clients keep Debug output readable
without exposing configured credentials. If you set base_url(...) with URL
userinfo such as https://user:pass@example.test, the Debug output redacts
that userinfo and shows only the sanitized URL.
When credentials are provided explicitly or through the environment helpers,
ClientBuilder::build() rejects blank, whitespace-only, and HTTP
header-invalid api_key or secret_key values before constructing the
client.
Tune transport retries when a service integration needs stronger transient-failure handling:
use Duration;
use Client;
let client = builder
.timeout
.max_retries
.retry_on_429
.respect_retry_after
.base_backoff
.max_backoff
.max_in_flight
.build?;
# let _ = client;
# Ok::
The default retry behavior stays conservative: retrying 429 responses and honoring Retry-After remain opt-in.
When you set total_retry_budget(...), the retry loop is bounded by the remaining elapsed-time budget, and each scheduled retry wait is capped by that remaining budget, including waits derived from Retry-After and waits with jitter enabled.
Inject a custom reqwest::Client when you need to own the underlying network stack:
use Duration;
use Client;
let reqwest_client = builder
.timeout
.build?;
let client = builder
.reqwest_client
.max_retries
.retry_on_429
.respect_retry_after
.base_backoff
.max_backoff
.max_in_flight
.build?;
# let _ = client;
# Ok::
When reqwest_client(...) is used, reqwest-level settings such as timeout(...) must be configured on the injected client instead of on ClientBuilder.
Optionally load paired credentials from process environment when a service prefers env-driven wiring:
use Client;
let client = builder
.credentials_from_env?
.build?;
# let _ = client;
# Ok::
Observe successful transport completions without changing endpoint return types:
use Arc;
use ;
;
let client = builder
.observer
.build?;
# let _ = client;
# Ok::
Observers only receive successful-response metadata such as endpoint name, URL, status, request ID, retry attempt count, and elapsed time.
Fetch stock latest bars:
use ;
async
Collect all pages from a paginated endpoint:
use ;
async
Authentication
Authentication behavior follows the implemented endpoint rules:
stocks,options,news, andcorporate_actionsrequire credentials- The currently implemented
cryptoHTTP endpoints can run without credentials
The primary application path is still explicit credentials on the builder:
use Client;
let client = builder
.api_key
.secret_key
.build?;
# let _ = client;
# Ok::
credentials_from_env() and credentials_from_env_names(...) are optional ergonomics for integrations that already manage credentials through environment variables. They only load paired values; a partial pair returns Error::InvalidConfiguration.
Whenever credentials are provided, api_key and secret_key must both be
present or both be omitted. ClientBuilder::build() rejects blank,
whitespace-only, and HTTP header-invalid values before constructing the
client.
ClientBuilder, Client, and resource-client Debug output redact
configured credentials, and any base_url(...) URL userinfo is removed from
the rendered debug URL.
Live tests in this repository use:
APCA_API_KEY_IDAPCA_API_SECRET_KEYALPACA_LIVE_TESTS=1
If you keep local secrets in a .env file under different names such as ALPACA_DATA_API_KEY and ALPACA_DATA_SECRET_KEY, export them into the APCA_* names before running live tests or examples.
See docs/authentication.md for the current auth contract.
Documentation Map
- Documentation site: https://wmzhai.github.io/alpaca-data-rs/
- Primary API host after publish: https://docs.rs/alpaca-data
- Project Pages route:
https://wmzhai.github.io/alpaca-data-rs/ - Local generation:
./tools/docs/generate-doc-site - Local site install:
npm install --prefix website - Local site start:
npm run start --prefix website - Local site build:
npm run build --prefix website - API reference sections:
- Generated module references:
docs/reference/stocks.md,docs/reference/options.md,docs/reference/crypto.md,docs/reference/news.md,docs/reference/corporate-actions.md,docs/reference/common.md,docs/reference/transport.md
API Audit Script
The repository includes one local entry point for official Market Data API audit work.
Requirements:
bashcurljq
Run the read-only parity audit against the local coverage manifest and source tree:
The script accepts no command-line arguments. It prints the complete audit report directly to the terminal and exits non-zero when blocking drift is detected. The report covers mirror-path coverage, parameter signatures, response-field signatures, enum gaps, and convenience helpers that require re-validation after mirror changes.
Testing
Default checks:
Enable live tests:
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
ALPACA_LIVE_TESTS=1
Normal success-path coverage must use the real Alpaca API whenever credentials can cover the scenario. Mocks are reserved for fault injection paths such as malformed JSON, repeated pagination tokens, timeouts, and HTTP failures.
Benchmarks
Local micro-benchmark baselines currently live in:
benches/shared_core.rsbenches/stocks.rsbenches/options.rsbenches/crypto.rsbenches/news_corporate_actions.rs
Compile benchmark targets without running a full sample: