@bluefin-ai/yfin
v0.2.0
Published
Lightweight TypeScript SDK for yfin: hosted Yahoo Finance quotes, history, options, fundamentals, screeners, and search.
Downloads
80
Maintainers
Readme
@bluefin-ai/yfin
Lightweight TypeScript SDK for yfin, a hosted Yahoo Finance data API for builders.
yfin gives you access to Yahoo Finance market data without running your own scraper stack: quotes, historical prices, options chains, fundamentals, screeners, symbol search, and market context through product-native namespaces. Use it for dashboards, agents, notebooks, research tools, watchlists, prototyping, and app backends.
This SDK is intentionally portable: no runtime dependencies, standard fetch,
ESM + CommonJS builds, and bundled TypeScript declarations.
Docs: https://docs.yfin.dev/typescript-sdk
npm install @bluefin-ai/yfinQuick Use
import { Client } from "@bluefin-ai/yfin";
const client = new Client();
const apple = client.ticker("AAPL");
// Current quote snapshots
const quotes = await client.quotes.batch(["AAPL", "MSFT"]);
// Historical chart data
const history = await apple.history({ range: "5d", interval: "1h" });
// Options chain data
const chain = await apple.optionChain();
console.log(quotes.data, history.data, chain.data);Common Calls
await client.quotes.batch(["AAPL", "MSFT"]);
await client.prices.history("AAPL", { range: "1mo", interval: "1d", events: "div,splits,capitalGains" });
await client.options.chain("AAPL", { date: "2026-01-16" });
await client.fundamentals.get("AAPL", { modules: ["price", "summaryDetail"] });
await client.symbols.search("apple");
await client.screeners.default({ count: 25 });
await client.screeners.run({
size: 10,
query: { operator: "EQ", operands: ["sector", "Technology"] },
});The client is organized around yfin product areas: quotes, prices,
options, fundamentals, financials, symbols, screeners, market,
calendar, events, research, and reference. Use client.ticker("AAPL")
for symbol-scoped quote, history, options, fundamentals, financials, metadata,
and research calls.
Runtime Support
The package uses the standard Fetch API. In Node, use Node 18+ or pass a custom fetch implementation:
const client = new Client({ fetch: myFetch });Configuration can come from constructor options or environment variables in Node-like runtimes:
| Option | Environment | Purpose |
| --- | --- | --- |
| baseUrl | YFIN_BASE_URL | Override https://api.yfin.dev; must be http or https |
| contact | YFIN_CONTACT | Send optional support metadata |
| apiKey | YFIN_API_KEY | Send email-verified API credentials |
| managementToken | YFIN_MANAGEMENT_TOKEN | Manage API keys after email verification |
apiKey is sent as Authorization: Bearer <key> by default. Pass
apiKeyHeader: "x-yfin-key" to use X-Yfin-Key instead.
The SDK retries transient 429, 502, 503, and 504 responses by default.
Use maxRetries, retryStatuses, backoffFactorMs, maxBackoffMs, and
backoffJitter when you need tighter control, or set maxRetries: 0.
Keep API keys on a server when you do not control the runtime.
Auth Helpers
const client = new Client();
await client.management.requestAuthOtp("[email protected]");
const verified = await client.management.verifyAuthOtp("[email protected]", "123456", {
label: "agent",
});
const verifiedData = verified.data as {
api_key?: string;
management_token?: string;
};
const authed = new Client({ apiKey: verifiedData.api_key });
await authed.management.requestLimitIncrease({
requestedRps: 25,
useCase: "production agent workload",
message: "Short traffic description.",
});
const managed = new Client({
managementToken: verifiedData.management_token,
});
const keys = await managed.management.keys.list();
const created = await managed.management.keys.create({ label: "batch job" });
const createdData = created.data as { key?: { id?: string } };
if (createdData.key?.id) {
await managed.management.keys.rotate(createdData.key.id);
}Custom-limit requests are limited to 1 per minute per API key. You can also
email [email protected].
All successful calls return the hosted yfin envelope:
type YfinEnvelope<TData = unknown> = {
data?: TData;
meta?: {
provider?: string;
generated_at?: string;
route?: string;
};
};Errors
HTTP errors throw YfinError. HTTP 429 throws YfinRateLimitError; HTTP 503
throws YfinServiceBusyError after retry exhaustion. Error objects include
retryAfterSeconds, status, code, response, and response headers.
import { Client, YfinRateLimitError, YfinServiceBusyError } from "@bluefin-ai/yfin";
try {
await new Client().quotes.get("AAPL");
} catch (error) {
if (error instanceof YfinRateLimitError) {
console.log(error.retryAfterSeconds);
} else if (error instanceof YfinServiceBusyError) {
console.log("service busy", error.retryAfterSeconds);
}
}Publishing
The package is scoped and public:
npm publish --access publicRun the release check first:
npm run check