← back to Ventura Claw
server/connectors/usaspending.js
47 lines
// USAspending.gov — federal awards / contracts / grants. No key.
// https://api.usaspending.gov/
const BASE = "https://api.usaspending.gov/api/v2";
async function call(method, path, body) {
const r = await fetch(`${BASE}${path}`, {
method, headers: { "Content-Type": "application/json", Accept: "application/json", "User-Agent": "VenturaClaw/1.0" },
body: body ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(25_000),
});
if (!r.ok) throw new Error(`usaspending ${r.status}: ${await r.text().then(t => t.slice(0, 180)).catch(()=>"")}`);
return r.json();
}
module.exports = {
meta: { id: "usaspending", name: "USAspending", category: "data", docsUrl: "https://api.usaspending.gov/", auth: "none", realImpl: true },
fields: [],
configured() { return true; },
async health() {
// Use a small, known-stable POST endpoint that doesn't require complex filters
try {
const d = await call("POST", "/search/spending_by_award_count/", {
filters: { award_type_codes: ["A", "B", "C", "D"] },
});
return { ok: true, label: "live · federal awards/contracts/grants data" };
} catch (e) { return { ok: false, reason: e.message }; }
},
actions: {
async "search_awards"({ keyword, recipient, award_type, fiscal_year, limit }) {
const filters = {};
if (keyword) filters.keywords = [keyword];
if (recipient) filters.recipient_search_text = [recipient];
if (award_type) filters.award_type_codes = Array.isArray(award_type) ? award_type : [award_type];
if (fiscal_year) filters.time_period = [{ start_date: `${fiscal_year}-10-01`, end_date: `${fiscal_year + 1}-09-30` }];
const d = await call("POST", "/search/spending_by_award/", {
filters,
fields: ["Award ID", "Recipient Name", "Award Amount", "Award Type", "Awarding Agency", "Description", "Start Date", "End Date"],
page: 1, limit: Math.min(limit || 25, 100),
});
return { total: d.results?.length || 0, awards: d.results || [] };
},
async "recipient_summary"({ duns_or_uei }) {
if (!duns_or_uei) throw new Error("duns_or_uei required");
const d = await call("GET", `/recipient/duns/${encodeURIComponent(duns_or_uei)}/`);
return d;
},
},
};