Client
The Market Data JavaScript Client handles API requests, response parsing, rate-limit tracking, retries, and logging. The SDK supports stocks, options, funds, and market status data.
Get Started Quickly with the MarketDataClient
- Review the documentation on authentication to learn how to set your API token.
- Create a
MarketDataClientinstance and use it to make requests to the Market Data API. - Make a test request and review the console output. The SDK includes logging capabilities to help you debug requests.
- Check the rate limit in the client to track credit usage and how many API credits remain.
- Configure Settings to customize output format, date format, and other universal parameters.
MarketDataClient
class MarketDataClient {
constructor(config?: MarketDataConfig);
}
interface MarketDataConfig {
token?: string;
baseUrl?: string;
apiVersion?: string;
maxRetries?: number;
retryInitialWait?: number;
retryMaxWait?: number;
retryFactor?: number;
debug?: boolean;
logger?: Logger;
}
MarketDataClient is the main client class for interacting with the Market Data API. It provides access to all resources (stocks, options, funds, markets) and handles authentication, rate limiting, and request management.
Properties
token(string, optional): The authentication token for API requests. See authentication documentation for details.rateLimits(UserRateLimits, optional): Current rate limit information. Populated after the first successful API request.baseUrl(string): The base URL for API requests (default:https://api.marketdata.app).apiVersion(string): The API version to use (default:v1).headers(Record<string, string>): HTTP headers includingAuthorizationandUser-Agent.logger(Logger): The logger instance used for diagnostic output.settings(MarketDataSettings): Resolved configuration including env-var defaults. See Settings for details.
Resources
stocks(StocksResource): Access to stocks endpoints (prices, quotes, candles, earnings, news)options(OptionsResource): Access to options endpoints (chain, expirations, quotes, lookup)funds(FundsResource): Access to funds endpoints (candles)markets(MarketsResource): Access to markets endpoints (status)
constructor
new MarketDataClient(config?: MarketDataConfig)
Creates and configures a new MarketDataClient instance. This initializes the client with the provided token (or reads it from the MARKETDATA_TOKEN environment variable), sets up HTTP headers, and prepares the resource namespaces.
Parameters
-
config(MarketDataConfig, optional)Configuration object. All properties are optional:
token(string): The authentication token. Falls back toMARKETDATA_TOKENenvironment variable if not provided.baseUrl(string): Override the API base URL. Defaults tohttps://api.marketdata.app.apiVersion(string): Override the API version. Defaults tov1.maxRetries(number): Maximum retry attempts for retriable errors. Defaults to3.retryInitialWait(number): Initial wait in seconds before the first retry. Defaults to0.5.retryMaxWait(number): Maximum wait in seconds between retries. Defaults to10.retryFactor(number): Exponential backoff factor. Defaults to2.debug(boolean): Iftrue, sets the default logger level toDEBUG. Defaults tofalse.logger(Logger): A custom logger instance. If omitted, the SDK uses its built-inDefaultLogger.
Returns
-
MarketDataClientA new
MarketDataClientinstance ready to make API requests.
Notes
- The client sets a
User-Agentheader of the formmarketdata-js-{version}(e.g.marketdata-js-0.0.1). - All authenticated requests include an
Authorization: Bearer {token}header. - The client reuses a single underlying
fetchclient, which benefits from Node's global connection pooling. - Configuration properties can also be provided via environment variables — see Settings for the full list and their resolution order.
Example
import { MarketDataClient } from "marketdata-sdk-js";
// Token will be read from MARKETDATA_TOKEN environment variable
const client = new MarketDataClient();
// Or provide the token explicitly
const clientWithToken = new MarketDataClient({ token: "your_token_here" });
// Enable debug logging for troubleshooting
const debugClient = new MarketDataClient({ debug: true });
// Provide a custom logger
import { DefaultLogger, LogLevel } from "marketdata-sdk-js";
const logger = new DefaultLogger(LogLevel.WARN);
const quietClient = new MarketDataClient({ logger });
The Result Pattern
Every resource method returns a MarketDataResult<T> — a ResultAsync from the neverthrow library. Errors are not thrown; they are represented as failed results.
This means your code never needs a try/catch around SDK calls. You handle success and failure explicitly.
Handling Results
- .match()
- .isOk() / .isErr()
- .unwrap()
- .map() / .andThen()
The idiomatic way. Pattern-match on success and error with two callbacks.
const result = await client.stocks.prices("AAPL");
result.match(
(prices) => console.log("Success:", prices),
(error) => console.error("Failed:", error.message),
);
Branch on result state and access .value or .error directly.
const result = await client.stocks.prices("AAPL");
if (result.isOk()) {
console.log("Prices:", result.value);
} else {
console.error("Error:", result.error.message);
}
Convert to a thrown exception if you prefer try/catch.
try {
const result = await client.stocks.prices("AAPL");
const prices = result._unsafeUnwrap();
console.log(prices);
} catch (error) {
console.error("Failed:", error);
}
Chain operations on the success value without unwrapping.
const result = await client.stocks.prices("AAPL")
.map((prices) => prices.filter((p) => p.mid > 100));
if (result.isOk()) {
console.log("Filtered:", result.value);
}
MarketDataResult
interface MarketDataResult<T> extends ResultAsync<T, MarketDataClientError> {
save(filename?: string): Promise<string>;
blob(): Promise<Blob>;
}
Every resource method returns a MarketDataResult<T>. In addition to the standard ResultAsync interface from neverthrow, it exposes two convenience methods:
save(filename?: string): Write the response to a file. Returns aPromise<string>resolving to the filename. Format is inferred from the extension when possible.blob(): Materialise the response as aBlob. Useful for downloading CSV responses.
Accessing Rate Limits
The client tracks rate limits from the API by reading the X-Api-Ratelimit-* headers on every response. The client.rateLimits property is populated after the first successful API call.
const client = new MarketDataClient();
// Make a request to populate rate limits
await client.stocks.prices("AAPL");
// Access current rate limits
if (client.rateLimits) {
console.log(`Limit: ${client.rateLimits.requestsLimit}`);
console.log(`Remaining: ${client.rateLimits.requestsRemaining}`);
console.log(`Consumed: ${client.rateLimits.requestsConsumed}`);
console.log(`Reset at: ${new Date(client.rateLimits.requestsReset * 1000)}`);
}
UserRateLimits
interface UserRateLimits {
requestsLimit: number; // Total API credits allowed
requestsRemaining: number; // API credits remaining
requestsConsumed: number; // API credits consumed
requestsReset: number; // Unix timestamp when the limit resets
}
Note: Rate limits are tracked via the following response headers:
x-api-ratelimit-limit: Total API credits allowedx-api-ratelimit-remaining: Number of API credits remainingx-api-ratelimit-consumed: Number of API credits consumedx-api-ratelimit-reset: Unix timestamp when the rate limit resets
If rate limits have been fetched and requestsRemaining is 0, the next resource call will fail fast with a RateLimitError rather than hitting the API.
Logging
The SDK includes a built-in logger that outputs diagnostic information. You can pass a custom logger or use the default.
import { MarketDataClient, DefaultLogger, LogLevel } from "marketdata-sdk-js";
// Default logger (INFO level)
const client1 = new MarketDataClient();
// Debug logging (more verbose — shows request URLs, response timings, token suffix)
const client2 = new MarketDataClient({ debug: true });
// Custom log level
const logger = new DefaultLogger(LogLevel.WARN);
const client3 = new MarketDataClient({ logger });
Log levels (in order of verbosity): DEBUG, INFO, WARN, ERROR.
The default logger obfuscates tokens in log output, showing only the last 4 characters.
Configuration
The SDK supports flexible configuration of universal parameters through environment variables, constructor arguments, and per-method overrides. See the Settings documentation for complete details on all available configuration options and how they interact.