← back to Ventura Claw
server/connectors/sec.js
59 lines
// SEC EDGAR — public-company filings & financial data. No key.
// https://www.sec.gov/edgar/sec-api-documentation
// SEC requires a descriptive User-Agent on every request.
const UA = "VenturaClaw/1.0 (steve@venturaclaw.com)";
async function call(url) {
const r = await fetch(url, {
headers: { "User-Agent": UA, Accept: "application/json" },
signal: AbortSignal.timeout(20_000),
});
if (!r.ok) throw new Error(`sec ${r.status}`);
return r.json();
}
function pad10(cik) { return String(cik).replace(/^0+/, "").padStart(10, "0"); }
module.exports = {
meta: { id: "sec", name: "SEC EDGAR", category: "data", docsUrl: "https://www.sec.gov/edgar/sec-api-documentation", auth: "none", realImpl: true },
fields: [],
configured() { return true; },
async health() {
try {
const r = await fetch("https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=0000320193&type=10-K&dateb=&owner=include&count=1", {
headers: { "User-Agent": UA }, signal: AbortSignal.timeout(15_000),
});
return { ok: r.ok, label: r.ok ? "live · public-company filings" : `http ${r.status}` };
} catch (e) { return { ok: false, reason: e.message }; }
},
actions: {
// Look up a company by ticker, returns CIK + name
async "ticker_lookup"({ ticker }) {
if (!ticker) throw new Error("ticker required");
const d = await call("https://www.sec.gov/files/company_tickers.json");
const t = String(ticker).toUpperCase();
for (const v of Object.values(d || {})) {
if (v.ticker === t) return { cik: pad10(v.cik_str), ticker: v.ticker, name: v.title };
}
return { error: "not_found" };
},
async "submissions"({ cik }) {
if (!cik) throw new Error("cik required");
const d = await call(`https://data.sec.gov/submissions/CIK${pad10(cik)}.json`);
return {
cik: d.cik, name: d.name, sic: d.sic, sicDescription: d.sicDescription,
tickers: d.tickers, exchanges: d.exchanges,
recent_filings: (d.filings?.recent?.form || []).slice(0, 20).map((form, i) => ({
form,
filingDate: d.filings.recent.filingDate[i],
accessionNumber: d.filings.recent.accessionNumber[i],
primaryDocument: d.filings.recent.primaryDocument[i],
})),
};
},
async "company_concept"({ cik, taxonomy, tag }) {
if (!cik || !tag) throw new Error("cik + tag required");
const t = taxonomy || "us-gaap";
const d = await call(`https://data.sec.gov/api/xbrl/companyconcept/CIK${pad10(cik)}/${t}/${tag}.json`);
return d;
},
},
};