Skip to main content

TypeScript SDK

@yojinhq/jintel-client

The official TypeScript SDK wraps the GraphQL API with typed queries, Zod-validated responses, and a per-request response cache. Works in Node, Bun, Deno, and browsers.

npm install @yojinhq/jintel-client

Quick start

import { JintelClient } from "@yojinhq/jintel-client";

const jintel = new JintelClient({
apiKey: process.env.JINTEL_API_KEY!,
// baseUrl defaults to https://api.jintel.ai/api
});

const quotes = await jintel.quotes(["AAPL", "MSFT"]);
const profile = await jintel.enrichEntity("AAPL");
const batch = await jintel.batchEnrich(
["AAPL", "MSFT", "NVDA"],
["market", "news", "technicals", "earnings", "periodicFilings"],
);
const screen = await jintel.sanctionsScreen("Gazprom", "RU");

// Macro
const gdp = await jintel.gdp("USA", "REAL");
const cpi = await jintel.inflation("USA");
const rates = await jintel.interestRates("USA");
const cape = await jintel.sp500Multiples("SHILLER_PE_MONTH");

All methods return JintelResult<T> — a tagged union (success: true / success: false) so errors are always explicit.

Filtering array sub-graphs

enrichEntity and batchEnrich accept an options object that threads per-field filters into the underlying GraphQL query. Most sub-graphs have a domain-specific filter input with dimensions unique to that data; the generic filter (ArrayFilterInput) covers anything that still takes plain date/limit/sort.

// Generic ArrayFilterInput — research, predictions, discussions, social,
// institutionalHoldings, earningsPressReleases, periodicFilings, and
// market.history/keyEvents/shortInterest.
await jintel.enrichEntity("AAPL", ["research", "market"], {
filter: { since: "2025-01-01", limit: 10, sort: "DESC" },
});

// NewsFilterInput — source + sentiment
await jintel.enrichEntity("AAPL", ["news"], {
newsFilter: { sources: ["CNBC", "finnhub"], minSentiment: 0, limit: 10 },
});

// ExecutivesFilterInput — top-paid officers
await jintel.enrichEntity("AAPL", ["executives"], {
executivesFilter: { minPay: 1_000_000, sortBy: "PAY_DESC", limit: 5 },
});

// InsiderTradeFilterInput — directors only, acquisitions >= $100k
await jintel.enrichEntity("AAPL", ["insiderTrades"], {
insiderTradesFilter: {
isDirector: true,
acquiredDisposed: "ACQUIRED",
minValue: 100_000,
},
});

// EarningsFilterInput — reported beats >= 5%
await jintel.enrichEntity("AAPL", ["earnings"], {
earningsFilter: { onlyReported: true, minSurprisePercent: 5 },
});

// SegmentRevenueFilterInput — product breakdown >= $1B
await jintel.enrichEntity("AAPL", ["segmentedRevenue"], {
segmentedRevenueFilter: { dimensions: ["PRODUCT"], minValue: 1_000_000_000 },
});

// TopHoldersFilterInput — paginated reverse-13F lookup (replaces old positional args)
await jintel.enrichEntity("AAPL", ["topHolders"], {
topHoldersFilter: { limit: 25, offset: 0, minValue: 50_000 },
});

// FinancialStatementFilterInput — annual only
await jintel.enrichEntity("AAPL", ["financials"], {
financialStatementsFilter: { periodTypes: ["12M"], limit: 5 },
});

// SanctionsFilterInput + CampaignFinanceFilterInput under regulatory
await jintel.enrichEntity("Gazprom", ["regulatory"], {
sanctionsFilter: { minScore: 80, programs: ["SDGT"] },
campaignFinanceFilter: { cycle: 2024, party: "DEM" },
});

// FilingsFilterInput — narrow SEC filings by form type
await jintel.enrichEntity("AAPL", ["regulatory"], {
filingsFilter: { types: ["FILING_10K", "FILING_10Q"], limit: 5 },
});

// RiskSignalFilterInput — drop low-severity noise
await jintel.enrichEntity("Gazprom", ["risk"], {
riskSignalFilter: { severities: ["HIGH", "CRITICAL"] },
});

// OptionsChainFilterInput — options chains can exceed 5 000 rows; filter aggressively
await jintel.enrichEntity("BTC", ["derivatives"], {
optionsFilter: {
optionType: "CALL",
strikeMin: 60_000,
strikeMax: 80_000,
minOpenInterest: 100,
sort: "VOLUME_DESC",
limit: 25,
},
});

// FuturesCurveFilterInput — defaults to ASC (nearest contract first)
await jintel.enrichEntity("BTC", ["derivatives"], {
futuresFilter: { limit: 10 },
});

Mix filter fields in a single request — each targets a different sub-graph:

await jintel.batchEnrich(
["AAPL", "MSFT"],
["news", "regulatory", "risk", "earnings"],
{
newsFilter: { sources: ["CNBC"], limit: 5 },
filingsFilter: { types: ["FILING_10K"], limit: 2 },
riskSignalFilter: { severities: ["HIGH", "CRITICAL"] },
earningsFilter: { onlyReported: true, limit: 4 },
},
);

Top-level macro, screen, and short-interest queries

Economics and short-interest still accept the generic filter. sanctionsScreen and campaignFinance accept their domain-specific filters:

await jintel.gdp("USA", "REAL", { since: "2010-01-01", limit: 20 });
await jintel.inflation("USA", { since: "2020-01-01" });
await jintel.interestRates("USA", { limit: 12 });
await jintel.sp500Multiples("SHILLER_PE_MONTH", { limit: 60 });
await jintel.shortInterest("GME", { limit: 5 });

await jintel.sanctionsScreen("Gazprom", "RU", { minScore: 80, listNames: ["SDN"] });
await jintel.campaignFinance("Acme PAC", 2024, { party: "DEM", minRaised: 100_000 });

Filter defaults

FilterDefault limitDefault sort
ArrayFilterInput20DESC
NewsFilterInput20DESC (by date)
ExecutivesFilterInput20PAY_DESC
InsiderTradeFilterInput20DESC (by transactionDate)
EarningsFilterInput20DESC (by reportDate)
SegmentRevenueFilterInput20DESC (by filingDate)
TopHoldersFilterInput20 (offset 0)DESC (by value)
FinancialStatementFilterInput20DESC (by periodEnding)
SanctionsFilterInput20DESC (by score)
CampaignFinanceFilterInput20DESC (by totalRaised)
FilingsFilterInput20DESC
RiskSignalFilterInput20DESC
FuturesCurveFilterInput50ASC
OptionsChainFilterInput100EXPIRATION_ASC

Omitting a filter returns the full upstream set (no defaults applied). Setting any filter field applies that input's defaults for the remaining dimensions.

Migrating from 0.20 → 0.21

  • topHolders: { limit, offset } option was removed. Use topHoldersFilter: { limit, offset, minValue, since, until, sort } instead.
  • The generic filter option no longer threads into news, insiderTrades, earnings, segmentedRevenue, or financials.*. Use the new domain-specific filter options (newsFilter, insiderTradesFilter, earningsFilter, segmentedRevenueFilter, financialStatementsFilter).
  • sanctionsScreen and campaignFinance root methods accept an optional third argument with their new filter inputs.

See Filtering & sorting for the underlying GraphQL inputs.

Response caching

Enable the in-process TTL cache to deduplicate identical calls within short windows — 30s for quotes, 5min for enrich / price history by default:

const jintel = new JintelClient({
apiKey: process.env.JINTEL_API_KEY!,
cache: { quotesTtlMs: 15_000, enrichTtlMs: 120_000 },
});

jintel.invalidateCache(["AAPL"]); // after an external signal event