Quick Start
This page builds a company feed, reads its diagnostics, runs a topic feed over a date window, and turns the same query into a watcher. Install the package first (Installation); every example is an ES module that uses top-level await.
1. Build a company feed
import { buildCompanyNewsFeedResult } from "@xbbg/xnews";
const result = await buildCompanyNewsFeedResult({
ticker: "JPM",
companyName: "JPMorgan Chase",
// Required for sec.gov. Identify your application and a real contact address.
secUserAgent: "my-app/1.0 ops@example.com",
limit: 25,
});
for (const item of result.items.slice(0, 5)) {
console.log(`${item.publishedAt ?? "undated"} [${item.provider}] ${item.title}`);
console.log(` ${item.url}`);
}Without sources, a company feed queries sec-edgar, yahoo-finance, google-news, and finviz concurrently, merges duplicates, sorts newest first, and keeps the first limit items.
2. Read the diagnostics
buildCompanyNewsFeedResult returns a NewsFeedResult:
| Field | Meaning |
|---|---|
subject | The normalized subject: kind, key, displayName, plus ticker, companyName, cik, or query |
items | Merged NewsItem[], newest first, capped by limit |
providers | One ProviderResult per requested provider: status, itemCount, items, warnings, requestUrls, fetchedAt, durationMs, undatedExcluded, and error |
warnings | Every provider warning, flattened |
partial | true when any provider finished error, unsupported, partial, or disabled |
fetchedAt | ISO timestamp of the request |
import { buildCompanyNewsFeedResult } from "@xbbg/xnews";
const result = await buildCompanyNewsFeedResult({
ticker: "JPM",
companyName: "JPMorgan Chase",
secUserAgent: "my-app/1.0 ops@example.com",
});
console.table(
result.providers.map(({ provider, status, itemCount, durationMs, error }) => ({
provider,
status,
itemCount,
durationMs,
error: error ? `${error.code}: ${error.message}` : "",
})),
);
if (result.partial) {
console.warn("Incomplete feed:", result.warnings);
}A provider that fails does not fail the call. For example, leaving out secUserAgent makes sec-edgar report status: "disabled" with an error.code of "config" and a warning that names the missing setting, while the other providers still return items. See Errors & Statuses for every status and code.
Fail loudly instead
The array-returning builders (buildCompanyNewsFeed, buildTopicNewsFeed, buildNewsFeed, buildWatchlistNewsFeed) accept strict: true, which throws if any provider produced a warning.
3. Query a topic over a date window
import { buildTopicNewsFeedResult } from "@xbbg/xnews";
const lastWeek = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const topic = await buildTopicNewsFeedResult({
query: "bank capital requirements",
sources: ["google-news", "federal-register", "federal-reserve", "fdic", "occ"],
since: lastWeek,
limit: 30,
});
for (const item of topic.items) {
console.log(item.publishedAt, item.source, item.title);
}Topic feeds default to google-news only; pass sources to fan out. federal-register queries its API, while federal-reserve, fdic, and occ are fixed feeds that are fetched whole and filtered locally: every query token must appear in the title or summary. since and until are inclusive, accept ISO strings or Date objects, and drop undated items (counted in ProviderResult.undatedExcluded).
4. Watch for new items
Every feed has a watcher: an async generator that polls on an interval and yields only items it has not seen before.
import { createNewsWatcher } from "@xbbg/xnews";
const controller = new AbortController();
process.once("SIGINT", () => controller.abort());
try {
for await (const fresh of createNewsWatcher({
ticker: "JPM",
companyName: "JPMorgan Chase",
secUserAgent: "my-app/1.0 ops@example.com",
intervalMs: 5 * 60_000,
signal: controller.signal,
})) {
for (const item of fresh) console.log("new:", item.publishedAt, item.title);
}
} catch (error) {
// Aborting during the sleep between polls rejects with the abort reason.
if (!controller.signal.aborted) throw error;
}The first poll yields everything currently in the feed; later polls yield only unseen items. A watcher throws if every provider fails on a poll, so an outage cannot look like a quiet feed. To survive restarts, persist the ids you have processed and pass them back as seenIds (Watchlists & Watchers).
Where to go next
- Company Feeds: CIKs, SEC forms, and which providers need which identifiers.
- Topic Feeds & Subjects: the general subject API and how fixed feeds are matched.
- Source Catalog: every provider, its capabilities, and its options.
- Data Model: every
NewsItemfield.
