Documentation
¶
Overview ¶
Package marketdata provides the official Go SDK for the Market Data API, offering type-safe access to real-time and historical financial data, including stock quotes and candles, options chains, mutual fund prices, and market status. The full API reference is available at https://www.marketdata.app/docs/api/intro.
Quick Start ¶
With an API token in the MARKETDATA_TOKEN environment variable, fetching a quote takes three lines:
client, err := marketdata.NewClient()
defer client.Close()
quote, err := client.Stocks.GetQuote("AAPL")
Resource Services ¶
The Client groups API endpoints into one service per resource:
- Client.Stocks: quotes, bulk quotes, candles, bulk prices, earnings, and news
- Client.Options: option chains, expiration dates, option quotes, and symbol lookup
- Client.Funds: mutual fund candles
- Client.Markets: market status (open or closed) and status history
- Client.Utilities: API status, response headers, and account details
Every service method has two forms: a context-first form such as Quote(ctx, "AAPL", opts...) that also returns per-request Response metadata, and a Get-prefixed convenience form such as GetQuote("AAPL") that uses a background context and returns only the decoded data.
Authentication and Configuration ¶
NewClient resolves the API token from, in order of priority, the WithToken option and the MARKETDATA_TOKEN environment variable. Before reading the environment, NewClient loads a .env file from the working directory if one exists; values from .env never override variables that are already set in the process environment. Configuration follows the same cascade throughout the SDK: .env file values, then environment variables, then client options passed to NewClient, then per-method options, with later tiers taking precedence.
If no token is found anywhere, the client starts in demo mode: it logs a warning, skips token validation and rate limit initialization, and can access only the limited set of endpoints the API exposes without authentication. When a token is present, NewClient validates it against the API synchronously at startup unless WithoutStartupValidation is used.
Error Handling ¶
All failures are reported as typed errors that support the standard errors.Is and errors.As idioms. Each HTTP failure maps to a specific type, such as AuthenticationError (401), RateLimitError (429), or ServerError (501-599), and each type has a matching sentinel value, such as ErrAuthentication or ErrRateLimited, for quick errors.Is checks. API-produced errors embed a SupportContext whose SupportInfo method formats the request ID, URL, status code, and timestamp into a block suitable for pasting into a Market Data support ticket:
var rlErr *marketdata.RateLimitError
if errors.As(err, &rlErr) {
fmt.Println(rlErr.SupportInfo())
}
Missing Data and Unknown Symbols ¶
The API answers two different situations with HTTP 404, and the SDK reports them differently.
A question the API rejects — a symbol that does not exist, an OCC symbol matching no contract — comes back with an errmsg naming the problem. The SDK maps it to a NotFoundError, so a typo fails loudly rather than reading as an empty result:
_, _, err := client.Stocks.Quote(ctx, "ZZZZQQ")
if errors.Is(err, marketdata.ErrNotFound) {
// the symbol does not exist
}
A valid question whose answer is empty — a filter matching no contracts, a date window with no candles — comes back without that marker. It is not an error: the method returns a nil error and a Response whose NoData field is true, and the result itself is empty rather than absent wherever an empty value exists. Methods returning a slice return an empty slice, and the collection-shaped results (options.OptionsChain, options.Expirations, utilities.Headers) return an empty value that is safe to range:
chain, resp, err := client.Options.Chain(ctx, "AAPL", ...)
if err != nil {
return err
}
for _, contract := range chain.Options { // zero iterations when resp.NoData
...
}
The five results that describe a single thing rather than a collection — stocks.Quote, options.OptionQuote, markets.MarketStatus, utilities.APIStatus and utilities.UserInfo — have no meaningful empty value, since every field of a zero-valued one would read as real data (a price of zero, a closed market, an account with no credits). Those return a nil pointer, and callers should check it:
quote, resp, err := client.Stocks.Quote(ctx, "AAPL")
if err != nil {
return err
}
if quote == nil { // resp.NoData is true
return nil
}
Not every endpoint supplies the marker: options/expirations and stocks/candles answer an unknown symbol with an unmarked 404, indistinguishable on the wire from an empty answer, so those report no data rather than an error.
Rate Limiting ¶
Rate limit information is available in two places. Every context-first method returns a Response whose RateLimit field carries the exact, request-scoped values from that response's headers. Separately, Client.RateLimits returns the client's running snapshot of the most recently observed state; it is convenient for monitoring but may lag behind when requests run concurrently.
Retries, Timeouts, and Concurrency ¶
Failed requests are retried with exponential backoff, but only for 501-599 status codes and transient network errors; 4xx responses and 500 are never retried. The default is 3 retries with a 1s, 2s, 4s backoff schedule, configurable via WithMaxRetries. Before each retry the SDK consults the API status endpoint and aborts early if the service is reported offline.
Timeouts are fixed and not configurable: 99 seconds per request and 2 seconds for the TCP connection dial. The client also limits itself to at most 50 concurrent in-flight requests through an internal pool; calls beyond that block until a slot frees, so the client is safe to share across many goroutines.
Example ¶
This example shows the shortest path to market data: with an API token in the MARKETDATA_TOKEN environment variable, three lines create a client and fetch a stock quote.
package main
import (
"fmt"
"log"
"github.com/MarketDataApp/sdk-go/v2/marketdata"
)
func main() {
client, err := marketdata.NewClient()
if err != nil {
log.Fatal(err)
}
defer func() { _ = client.Close() }()
quote, err := client.Stocks.GetQuote("AAPL")
if err != nil {
log.Fatal(err)
}
fmt.Printf("AAPL last: $%.2f\n", quote.Last)
}
Output:
Example (ErrorHandling) ¶
This example distinguishes failures with the typed error hierarchy: errors.Is against a sentinel when only the category matters, and errors.As against a concrete type when the error's fields are needed. SupportInfo formats the request details for a support ticket.
package main
import (
"context"
"errors"
"fmt"
"log"
"github.com/MarketDataApp/sdk-go/v2/marketdata"
)
func main() {
client, err := marketdata.NewClient()
if err != nil {
log.Fatal(err)
}
defer func() { _ = client.Close() }()
_, _, err = client.Stocks.Quote(context.Background(), "AAPL")
if err != nil {
// Sentinel check: is this any kind of not-found error?
if errors.Is(err, marketdata.ErrNotFound) {
fmt.Println("symbol not found")
return
}
// Typed check: pull the reset time and support details off the error.
var rateErr *marketdata.RateLimitError
if errors.As(err, &rateErr) {
fmt.Printf("rate limited; safe to retry in %s\n", rateErr.WaitDuration())
fmt.Println(rateErr.SupportInfo())
return
}
log.Fatal(err)
}
}
Output:
Index ¶
- Variables
- func Version() string
- type APIError
- type AuthenticationError
- type BadRequestError
- type CSVResponse
- type Client
- type Config
- type Environment
- type Error
- type ForbiddenError
- type HTMLResponse
- type InsecureTokenError
- type InternalError
- type Mode
- type NetworkError
- type NotFoundError
- type Option
- func WithAPIKey(key string) Optiondeprecated
- func WithAPIVersion(version string) Option
- func WithAddHeaders(enabled bool) Option
- func WithBaseURL(url string) Option
- func WithColumns(columns ...string) Option
- func WithDateFormat(format string) Option
- func WithDebug(enabled bool) Option
- func WithEnvironment(env Environment) Option
- func WithHTTPClient(client *http.Client) Option
- func WithHumanReadable(enabled bool) Option
- func WithLimit(n int) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMaxAge(maxAge string) Option
- func WithMaxRetries(n int) Option
- func WithMode(mode Mode) Option
- func WithOffset(n int) Option
- func WithToken(token string) Option
- func WithoutDotEnv() Option
- func WithoutStartupValidation() Option
- type ParseError
- type PayloadTooLargeError
- type PaymentRequiredError
- type RateLimitError
- type RateLimitMeta
- type RateLimitState
- type Response
- type ResponseTooLargeError
- type ServerError
- type SupportContext
- type ValidationError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrAuthentication matches [AuthenticationError]: the API token is // invalid or missing (HTTP 401). ErrAuthentication = sdkerrors.ErrAuthentication // ErrPaymentRequired matches [PaymentRequiredError]: the request needs // a higher plan (HTTP 402). ErrPaymentRequired = sdkerrors.ErrPaymentRequired // ErrForbidden matches [ForbiddenError]: access was denied due to an IP // policy violation (HTTP 403). ErrForbidden = sdkerrors.ErrForbidden // ErrBadRequest matches [BadRequestError]: the request parameters were // invalid (HTTP 400). ErrBadRequest = sdkerrors.ErrBadRequest // ErrNotFound matches [NotFoundError]. In practice this SDK never // returns it: every HTTP 404 is treated as "no data" and reported // through the NoData field of the returned [Response], never as an // error. See [NotFoundError] for why the type exists anyway. ErrNotFound = sdkerrors.ErrNotFound // ErrPayloadTooLarge matches [PayloadTooLargeError]: the request spans // too much data (HTTP 413). ErrPayloadTooLarge = sdkerrors.ErrPayloadTooLarge // ErrRateLimited matches [RateLimitError]: the rate limit has been // exceeded (HTTP 429). ErrRateLimited = sdkerrors.ErrRateLimited // ErrResponseTooLarge matches [ResponseTooLargeError]: the response body // exceeded the SDK's safety cap and was refused before being buffered. ErrResponseTooLarge = sdkerrors.ErrResponseTooLarge // ErrInsecureToken matches [InsecureTokenError]: the SDK refused to send // the API token over a connection that is neither HTTPS nor loopback. ErrInsecureToken = sdkerrors.ErrInsecureToken // ErrInternal matches [InternalError]: an internal server error // (HTTP 500). Not retried by the SDK. ErrInternal = sdkerrors.ErrInternal // ErrServer matches [ServerError]: a temporary server error // (HTTP 501-599). Retried automatically by the SDK. ErrServer = sdkerrors.ErrServer // ErrInvalidRequest matches [ValidationError]: the SDK rejected the // input client-side before any request was made. ErrInvalidRequest = sdkerrors.ErrInvalidRequest )
Sentinel errors for quick classification with errors.Is. Each sentinel matches the corresponding typed error, so errors.Is(err, marketdata.ErrRateLimited) is true whenever err wraps a RateLimitError. Use errors.As with the typed errors instead when the error's fields (such as reset times or support context) are needed.
Functions ¶
func Version ¶
func Version() string
Version reports the SDK's own version as recorded in the caller's build info (ADR-015): the module version when this SDK is a dependency, or "unknown" when built from source without a stamped main-module version (e.g. a plain "go build" with no VCS info) or when build info is unavailable at all. It matches the version sent in the User-Agent header of every request.
Types ¶
type APIError ¶
APIError represents an unexpected API response where the HTTP status reported success but the response body indicated an error (for example, a status field other than "ok").
type AuthenticationError ¶
type AuthenticationError = sdkerrors.AuthenticationError
AuthenticationError is returned for an HTTP 401 response: the API token is invalid, expired, or missing. It embeds SupportContext, matches ErrAuthentication with errors.Is, and is not retryable.
type BadRequestError ¶
type BadRequestError = sdkerrors.BadRequestError
BadRequestError is returned for an HTTP 400 response: the request parameters were invalid. It embeds SupportContext, matches ErrBadRequest with errors.Is, and is not retryable.
type CSVResponse ¶
type CSVResponse = response.CSVResponse
CSVResponse carries a raw CSV response body — see the AsCSV() facet on each service (e.g. github.com/MarketDataApp/sdk-go/v2/marketdata/stocks.Service.AsCSV) and ADR-018 for the design rationale.
type Client ¶
type Client struct {
// Stocks provides stock quotes, candles, bulk prices, earnings, and news.
Stocks *stocks.Service
// Options provides option chains, expiration dates, option quotes, and
// option symbol lookup.
Options *options.Service
// Funds provides mutual fund candles.
Funds *funds.Service
// Markets provides market status (open or closed) and status history.
Markets *markets.Service
// Utilities provides API status, response header echo, and account
// details for the authenticated user.
Utilities *utilities.Service
// contains filtered or unexported fields
}
Client is the entry point to the Market Data API. It holds the configuration, the underlying HTTP client with retry and rate limit tracking, and one service per API resource. Create a Client with NewClient and release its resources with Client.Close when done.
A Client is safe for concurrent use across goroutines and limits itself to at most 50 concurrent in-flight requests; additional calls block until a slot frees.
func NewClient ¶
NewClient creates a new Market Data client configured by the given options.
NewClient first loads a .env file from the working directory if one exists; values from .env never override variables already set in the process environment. The API token is then resolved in priority order: the WithToken option if provided, otherwise the MARKETDATA_TOKEN environment variable. If no token is found, the client starts in demo mode with access limited to unauthenticated endpoints, and a warning is logged.
When a token is present, NewClient validates it against the API with a synchronous request and returns an error if the token is rejected; use WithoutStartupValidation to skip this check. Rate limit state is then initialized in the background without blocking the caller.
Timeouts are fixed and cannot be overridden: 99 seconds per request and 2 seconds for the TCP connection dial. Failed requests are retried up to 3 times by default (configurable with WithMaxRetries) with exponential backoff starting at 1 second and doubling each attempt; only 501-599 status codes and transient network errors are retried.
Example:
// Using environment variable (recommended)
client, err := marketdata.NewClient()
// Using explicit token
client, err := marketdata.NewClient(
marketdata.WithToken("your-token"),
)
Example ¶
This example creates a client with an explicit token instead of the environment variable and raises the retry budget from the default of 3.
package main
import (
"context"
"fmt"
"log"
"github.com/MarketDataApp/sdk-go/v2/marketdata"
)
func main() {
client, err := marketdata.NewClient(
marketdata.WithToken("your-token"),
marketdata.WithMaxRetries(5),
)
if err != nil {
log.Fatal(err)
}
defer func() { _ = client.Close() }()
quote, _, err := client.Stocks.Quote(context.Background(), "SPY")
if err != nil {
log.Fatal(err)
}
fmt.Printf("SPY last: $%.2f\n", quote.Last)
}
Output:
func (*Client) Close ¶
Close releases resources held by the client by closing idle HTTP connections. After Close is called, the client must not be reused. Close is safe to call multiple times; subsequent calls are no-ops. It always returns nil; the error result exists to satisfy io.Closer.
func (*Client) Debug ¶
Debug enables or disables debug logging at runtime. It is a convenience method equivalent to having passed WithDebug to NewClient, useful for turning verbose request logging on temporarily while diagnosing an issue. On the SDK's default logger it also adjusts the log level (to DEBUG, and back to the configured base level when disabled); a logger injected with WithLogger keeps its own level.
func (*Client) DemoMode ¶
DemoMode reports whether the client is running in demo mode because no API token was provided. In demo mode access is limited to unauthenticated endpoints and sample data; applications can use this to display a demo banner or constrain their feature set.
func (*Client) RateLimits ¶
func (c *Client) RateLimits() RateLimitState
RateLimits returns the client's snapshot of the rate limit state as of the most recently completed request. The snapshot is convenient for monitoring credit consumption, but when requests run concurrently it may lag behind the true server-side state; for exact, request-scoped values use the RateLimit field of the Response returned by each context-first method instead. Before any request has completed (or in demo mode) the returned state is zero-valued.
Example ¶
This example reads the client-level rate limit snapshot. The snapshot reflects the most recently completed request; for exact per-request values, use the RateLimit field of the Response returned by each context-first method.
package main
import (
"fmt"
"log"
"time"
"github.com/MarketDataApp/sdk-go/v2/marketdata"
)
func main() {
client, err := marketdata.NewClient()
if err != nil {
log.Fatal(err)
}
defer func() { _ = client.Close() }()
state := client.RateLimits()
// Consumed is the cost of the most recent request, not a window total;
// the window total is Limit - Remaining.
fmt.Printf("last request cost %d credit(s); %d of %d used this window, resets at %s\n",
state.Consumed, state.Limit-state.Remaining, state.Limit, state.ResetAt.Format(time.RFC3339))
if state.Remaining < 100 {
fmt.Println("running low on API credits")
}
}
Output:
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config holds the client configuration assembled by NewClient from defaults, environment variables, and Option values. It is unexported field by field and immutable after client creation; use the With* functional options to influence it.
type Environment ¶
type Environment string
Environment selects which Market Data API deployment the client talks to. Pass one of the predefined values to WithEnvironment; each maps to a base URL that can be further overridden with WithBaseURL.
const ( // Production is the live API environment at https://api.marketdata.app. // It is the default. Production Environment = "production" // Test is the test/sandbox API environment at // https://test.api.marketdata.app. Test Environment = "test" // Development is the local development environment at // http://localhost:8080. Development Environment = "development" )
type Error ¶
Error is the interface implemented by all SDK errors. Beyond the standard error and Unwrap methods, it reports whether the failed operation is safe to retry and exposes SupportInfo, which formats the request details for a Market Data support ticket.
type ForbiddenError ¶
type ForbiddenError = sdkerrors.ForbiddenError
ForbiddenError is returned for an HTTP 403 response, which typically occurs when the account's IP address changes and access is temporarily blocked. The AuthorizedIP and BlockedIP fields identify the addresses involved and TroubleshootingGuide links to the relevant documentation. It embeds SupportContext, matches ErrForbidden with errors.Is, and is not retryable.
type HTMLResponse ¶
type HTMLResponse = response.HTMLResponse
HTMLResponse carries a raw HTML response body. Reserved: no service exposes a facet returning this type yet, since the API does not serve HTML for data endpoints today. See ADR-018.
type InsecureTokenError ¶
type InsecureTokenError = sdkerrors.InsecureTokenError
InsecureTokenError is returned when the SDK refuses to transmit the API token over a connection that is neither HTTPS nor a loopback host. It is raised before the request is sent, so the token never leaves the process.
type InternalError ¶
type InternalError = sdkerrors.InternalError
InternalError is returned for an HTTP 500 response: a permanent server failure that the SDK does not retry. Include the request ID (via SupportInfo) when opening a support ticket. It embeds SupportContext and matches ErrInternal with errors.Is.
type Mode ¶
type Mode string
Mode selects how the API fulfills every request, trading data freshness against credit cost (the API's universal "mode" parameter). It is a premium parameter: free and trial plans always receive delayed data.
const ( // ModeLive returns real-time data. It is the default for paid plans. ModeLive Mode = "live" // ModeCached returns recently cached data at reduced credit cost. On a // cache miss the API returns HTTP 204, which the SDK surfaces as a no-data // response (nil result, Response.NoData true, nil error). ModeCached Mode = "cached" // ModeDelayed returns data delayed at least 15 minutes. It is the default // for free and trial plans. ModeDelayed Mode = "delayed" )
type NetworkError ¶
type NetworkError = sdkerrors.NetworkError
NetworkError represents a connection failure or timeout. It covers both failures before an HTTP response was received — where StatusCode is 0 — and a body that failed or timed out mid-read, where StatusCode is taken from the interrupted response. The Timeout and Temporary fields classify the failure, and Retryable reports true because network errors are transient; the SDK retries them automatically.
type NotFoundError ¶
type NotFoundError = sdkerrors.NotFoundError
NotFoundError represents an HTTP 404 response in the cross-SDK error taxonomy (SDK requirements §6.1), which every Market Data SDK defines. In practice this SDK never returns it: the API answers 404 for "no data matched the request" — including unknown symbols — and the SDK reports that through the NoData field of the returned Response with a nil error, never as an error value. Branching on ErrNotFound therefore never fires; check Response.NoData (or a nil result from the Get* convenience methods) instead. NotFoundError embeds SupportContext, matches ErrNotFound with errors.Is, and is not retryable.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option configures the client during NewClient. Options are applied in the order given, after defaults and environment variables, so an explicit option always wins over the environment and a later option wins over an earlier one.
func WithAPIKey
deprecated
func WithAPIVersion ¶
WithAPIVersion sets the API version segment used in request paths (default "v1"). It overrides the MARKETDATA_API_VERSION environment variable, completing the configuration cascade for this setting. An empty value is ignored.
func WithAddHeaders ¶
WithAddHeaders sets the API's universal "headers" parameter, which controls whether a header row is included in CSV output. It has no effect on the JSON responses the SDK decodes and is provided for completeness.
func WithBaseURL ¶
WithBaseURL sets a custom base URL for the API, such as a proxy or a mock server in tests. The URL must be a valid http or https URL with a host, or NewClient returns a ValidationError.
Like all options, WithBaseURL and WithEnvironment are applied in the order passed to NewClient: whichever runs last wins. Pass WithBaseURL after WithEnvironment — the common case — to override an environment's default URL with an arbitrary one.
func WithColumns ¶
WithColumns restricts responses to the named columns (the API's universal "columns" parameter), which can reduce payload size. Missing columns simply decode as zero values, so filtering never causes a decode error. Passing no columns is a no-op.
On the typed JSON methods the SDK also requests the two kinds of column a decode cannot do without and a caller does not think to name: the "s" envelope, which every typed method checks, and the array each response keys its row count off (symbol, t, optionSymbol, date, depending on the endpoint). The API drops both whenever a column filter is set, and without them a present row decodes to nothing and the method reports not-found for data that is there. The formatted facets get exactly the columns asked for, since there the column list is the output.
func WithDateFormat ¶
WithDateFormat sets the API's universal "dateformat" parameter for every request ("timestamp", "unix", or "spreadsheet").
Advanced use only. The SDK decodes dates from the API's default numeric (unix) representation; overriding the format globally can change the wire representation of date fields and cause typed responses (candles, quotes, earnings) to fail decoding. Endpoints that require a specific format for correct decoding set it themselves at the method level, which takes precedence over this default.
func WithDebug ¶
WithDebug enables debug logging of requests and responses on the configured logger. Setting the MARKETDATA_LOGGING_LEVEL environment variable to DEBUG has the same effect. The API token never appears in debug output; it is redacted to its last four characters.
func WithEnvironment ¶
func WithEnvironment(env Environment) Option
WithEnvironment selects the API environment (Production, Test, or Development) and sets the corresponding base URL. The default is Production. To point the client at an arbitrary URL instead, use WithBaseURL.
Like all options, WithEnvironment and WithBaseURL are applied in the order passed to NewClient: whichever runs last wins the base URL. Pass WithBaseURL after WithEnvironment to override an environment's default URL (the common case — an arbitrary override); the reverse order lets WithEnvironment override an earlier WithBaseURL.
func WithHTTPClient ¶
WithHTTPClient supplies a custom *http.Client for the SDK to send requests through, which is useful for custom transports, proxies, or instrumentation. The SDK operates on its own shallow copy of the supplied client — the caller's object is never modified — sharing its Transport. On that copy the SDK's fixed 99-second request timeout and secure redirect policy apply; dial-level settings (such as the SDK's default 2-second connect timeout) are the supplied Transport's own responsibility.
func WithHumanReadable ¶
WithHumanReadable sets the API's universal "human" parameter, which requests human-readable field names and values.
It applies to the CSV and HTML facets only (stocks.Service.AsCSV and its siblings) and is never sent on a typed JSON request. This is not a policy choice: the parameter renames every key in the response — "askSize" becomes "Ask Size", "changepct" becomes "Change %", and the "s" envelope field disappears — so a typed method receiving it fails outright. Unlike WithColumns, which the SDK can repair by also requesting the envelope, there is nothing to salvage here.
func WithLimit ¶
WithLimit sets the API's universal "limit" parameter, capping the number of results (overriding an endpoint's default). Values less than or equal to zero are ignored.
"Universal" describes the parameter, not its reach: it is honored per endpoint. options/chain, options/expirations, stocks/news and markets/status apply it; the candles endpoints ignore it (verified live 2026-08-20 — a 13-candle range requested with limit=3 still returned 13). Tracked in integration/discrepancy_test.go.
func WithLogger ¶
WithLogger sets the *slog.Logger the SDK logs through, replacing slog.Default(). The SDK never logs the full API token: in debug output the token is redacted to its last four characters.
func WithMaxAge ¶
WithMaxAge sets the API's universal "maxage" parameter, the maximum age of cached data accepted when ModeCached is in effect. It accepts an absolute datetime or a relative duration such as "5min" or "1h"; if no cached data is within the window, the API returns a no-data response at no credit cost. It has no effect unless the mode is cached.
func WithMaxRetries ¶
WithMaxRetries sets the maximum number of retry attempts for failed requests, replacing the default of 3. Set it to 0 to disable retries entirely; negative values are treated as 0.
Only the retry count is configurable. The retry conditions and backoff are fixed: a request is retried only on 501-599 status codes and transient network errors (never on 4xx or 500), with exponential backoff starting at 1 second and doubling each attempt, so the default schedule waits 1s, 2s, and 4s. A server-supplied Retry-After header takes precedence over the calculated backoff, and retries stop early if the API status endpoint reports the service offline.
func WithMode ¶
WithMode sets the API's universal "mode" parameter (ModeLive, ModeCached, or ModeDelayed) for every request. Because it is a client-level default, callers that need different modes per request should use separate clients (for example a cached client for bulk quotes and a live client for time-sensitive calls). See docs/RESIDUALS.md.
func WithOffset ¶
WithOffset sets the API's universal "offset" parameter for pagination, used together with WithLimit. Values less than or equal to zero are ignored (offset zero is the default first page).
Like WithLimit it is ignored by the candles endpoints, which makes paging over candles unsafe rather than merely ineffective: every page returns the identical full set instead of advancing, so a loop either duplicates every row indefinitely or stops on a condition that was never true. Tracked in integration/discrepancy_test.go.
func WithToken ¶
WithToken sets the API token used to authenticate every request. An explicit token has the highest priority in the configuration cascade: it overrides the MARKETDATA_TOKEN environment variable and any value loaded from a .env file. When neither WithToken nor the environment supplies a token, the client runs in demo mode with access limited to unauthenticated endpoints.
func WithoutDotEnv ¶
func WithoutDotEnv() Option
WithoutDotEnv disables loading a .env file from the working directory (ADR-012), for controlled environments — tests, containers, CI — where implicit file-based configuration is unwanted. Real environment variables and the other With* options are unaffected. The SDK never modifies the process environment either way; .env values only feed its own configuration cascade.
func WithoutStartupValidation ¶
func WithoutStartupValidation() Option
WithoutStartupValidation skips the synchronous token validation call that NewClient normally makes during client creation. This saves one round trip when startup latency matters, but an invalid token then goes undetected until the first API call fails with an AuthenticationError.
type ParseError ¶
type ParseError = sdkerrors.ParseError
ParseError is returned when an API response is received but its body cannot be decoded into the expected type. It embeds SupportContext and is not retryable.
type PayloadTooLargeError ¶
type PayloadTooLargeError = sdkerrors.PayloadTooLargeError
PayloadTooLargeError is returned for an HTTP 413 response: the request spans too much data, typically an intraday candle request covering more than one year. It embeds SupportContext, matches ErrPayloadTooLarge with errors.Is, and is not retryable.
type PaymentRequiredError ¶
type PaymentRequiredError = sdkerrors.PaymentRequiredError
PaymentRequiredError is returned for an HTTP 402 response: the request was valid but the account's plan does not include the requested feature or data. It embeds SupportContext, matches ErrPaymentRequired with errors.Is, and is not retryable.
type RateLimitError ¶
type RateLimitError = sdkerrors.RateLimitError
RateLimitError is returned for an HTTP 429 response: the account's rate limit has been exceeded. The Limit, Remaining, and ResetAt fields describe the current window, and WaitDuration reports how long to wait before trying again. It embeds SupportContext, matches ErrRateLimited with errors.Is, and is not retried automatically by the SDK.
type RateLimitMeta ¶
type RateLimitMeta = response.RateLimitMeta
RateLimitMeta contains per-response rate limit information. This is request-scoped and deterministic, unlike client-level rate limits.
type RateLimitState ¶
type RateLimitState struct {
// Limit is the maximum number of requests allowed in the current window.
Limit int
// Remaining is the number of requests remaining in the current window.
Remaining int
// Consumed is the number of requests consumed in the current window.
Consumed int
// ResetAt is when the current rate limit window resets.
ResetAt time.Time
}
RateLimitState is the client-level snapshot of rate limit information returned by Client.RateLimits. It reflects the headers of the most recently completed request, not necessarily the request the caller just made.
type Response ¶
Response carries per-request metadata returned alongside typed data. It embeds *http.Response for raw access to headers, status, etc.
type ResponseTooLargeError ¶
type ResponseTooLargeError = sdkerrors.ResponseTooLargeError
ResponseTooLargeError is returned when an API response body exceeds the SDK's size cap. The body is refused rather than buffered, so a hostile or malfunctioning server cannot exhaust the caller's memory. It embeds SupportContext and is not retryable.
type ServerError ¶
type ServerError = sdkerrors.ServerError
ServerError is returned for an HTTP 501-599 response: a temporary server failure. These are the only status codes the SDK retries automatically with exponential backoff, so a ServerError surfaces only after the retry budget is exhausted. It embeds SupportContext and matches ErrServer with errors.Is.
type SupportContext ¶
type SupportContext = sdkerrors.SupportContext
SupportContext carries the request details embedded in every API error: the request ID (the cf-ray header), request URL, HTTP status code, timestamp, message, and exception type. Its SupportInfo method formats these fields as a ready-to-paste block for Market Data support tickets, so any API error can produce one directly:
var apiErr *marketdata.AuthenticationError
if errors.As(err, &apiErr) {
fmt.Println(apiErr.SupportInfo())
}
type ValidationError ¶
type ValidationError = sdkerrors.ValidationError
ValidationError is returned when the SDK rejects input client-side, such as an empty symbol or a malformed base URL, before any request is made. The Field and Message fields identify the offending parameter. It matches ErrInvalidRequest with errors.Is, is not retryable, and, since no request occurred, its SupportInfo returns an empty string.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package funds provides types and methods for mutual fund data from the Market Data API's /v1/funds/candles/ endpoint.
|
Package funds provides types and methods for mutual fund data from the Market Data API's /v1/funds/candles/ endpoint. |
|
Package markets provides market status information from the Market Data API's /v1/markets/status/ endpoint.
|
Package markets provides market status information from the Market Data API's /v1/markets/status/ endpoint. |
|
Package options provides access to the Market Data options endpoints: option chains (Chain), expiration dates (Expirations), single and bulk contract quotes (Quote and Quotes), and OCC option symbol lookup (Lookup).
|
Package options provides access to the Market Data options endpoints: option chains (Chain), expiration dates (Expirations), single and bulk contract quotes (Quote and Quotes), and OCC option symbol lookup (Lookup). |
|
Package stocks provides access to the Market Data stocks endpoints: real-time quotes and bulk quotes, historical candles, bulk candles, SmartMid prices, earnings, and news.
|
Package stocks provides access to the Market Data stocks endpoints: real-time quotes and bulk quotes, historical candles, bulk candles, SmartMid prices, earnings, and news. |
|
Package utilities provides access to the Market Data API's utility endpoints, which report on the API itself rather than on market data.
|
Package utilities provides access to the Market Data API's utility endpoints, which report on the API itself rather than on market data. |