USAspending.gov publishes every US federal contract and grant award, and it has a good public API. It also has quirks: one search can only cover one award group, agency names must match exactly, and results are paged 100 at a time. This guide skips those and goes straight to the answer, using the USAspending Federal Awards Actor on Apify.
The question
"Which companies won the largest federal IT security contracts in Virginia in the last year?"
1. Translate it into filters
-
Industry: NAICS
541512(computer systems design services). -
Topic: keyword
cybersecurity. -
Place: place of performance
VA. - Period: the last 365 days.
- Order: largest first.
2. Run it
import os
from collections import defaultdict
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("studded_lantana/usaspending-awards").call(run_input={
"awardTypes": ["contracts"],
"daysBack": 365,
"keywords": ["cybersecurity"],
"naicsCodes": ["541512"],
"states": ["VA"],
"sortBy": "amount",
"maxItems": 200,
})
awards = list(client.dataset(run.default_dataset_id).iterate_items())
Each award is one flat record: recipient_name, amount, awarding_agency, naics_code, start_date, end_date and a url to the award page.
3. Rank the winners
totals = defaultdict(float)
for a in awards:
if not a["recipient_withheld"]:
totals[a["recipient_name"]] += a["amount"] or 0
for name, total in sorted(totals.items(), key=lambda kv: -kv[1])[:10]:
print(f"${total:>16,.0f} {name}")
Note that amount is the award's total obligation, not just what was spent in your period. maxItems caps the run at the 200 largest matches; when I ran this in October 2026 there were 34.
4. Variations
-
One company's wins: set
"recipient": "Lockheed Martin"and drop the other filters. -
One agency: set
"agency": "Department of Homeland Security". Use the full top-tier name;DHSreturns nothing. -
Grants instead of contracts: set
"awardTypes": ["grants"]and filter with"assistanceListings": ["93.778"]. NAICS and PSC filters do not apply to grants.
What you won't get
Recipients that may be individuals are not named: recipient_withheld is true and the name is empty. The award page in url has the full record. Open solicitations are not here either; this is awards already made.
Cost
$0.005 per run plus $0.002 per award returned, so a run that returns 34 awards costs about 7 cents, and one that hits the 200 cap costs about 40.
The data is US government work in the public domain. The Actor is not affiliated with the US Treasury or USAspending.gov.
Top comments (0)