Federal Contracts, Grants & Lobbying API avatar

Federal Contracts, Grants & Lobbying API

Pricing

from $0.36 / 1,000 opportunity returneds

Go to Apify Store
Federal Contracts, Grants & Lobbying API

Federal Contracts, Grants & Lobbying API

Four federal money sources in one dataset: SAM.gov opportunities with contracting-officer contacts (free SAM.gov key), Grants.gov notices with award ceilings, USAspending awards and sub-awards, Senate LDA lobbying filings. Filter by keyword, agency, NAICS, set-aside, state. Three need no API key.

Pricing

from $0.36 / 1,000 opportunity returneds

Rating

0.0

(0)

Developer

Insight Solutions

Insight Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Four US federal money sources in one dataset schema: the solicitation before the award, the funding notice, the award and its sub-awards after the fact, and who was paid to lobby about it.

SourceWhat it gives youKey needed
SAM.gov contract opportunitiesSolicitations, sources-sought, award notices — deadlines, set-asides, NAICS, PSC, place of performance and the contracting officer's published contactYour own free SAM.gov key
Grants.gov funding opportunitiesNotices with award ceiling, floor, expected awards, eligibility text, ALN numbers and the attachment listNone
USAspending awardsPrime awards with recipient, UEI, obligated amount, outlays, period of performance, competition fields, sub-award totals, optional transactions and sub-awardsNone
Senate LDA lobbying filingsLD-1 and LD-2 filings with client, registrant, income or expenses, issue codes, named lobbyists and the government entities contactedNone

Same columns on every row. agency, title, postedAt, amount and naics mean the same thing whether GSA posted a solicitation, HHS posted a funding notice, Treasury paid the invoice or a law firm filed the disclosure — so "everything the federal government is buying, funding and being lobbied about in cybersecurity" is one query and one table.

No login. No cookie that identifies anyone. No headless browser. All four are public-domain US Government records.

This product uses the Grants.gov API but is not endorsed or certified by the U.S. Department of Health and Human Services.

At a glance

Input — this is the Store prefill; paste it and run, no key needed:

{
"sources": ["grants", "awards"],
"keywords": ["cybersecurity"],
"grantStatuses": ["posted", "forecasted"],
"awardTypes": ["contracts"],
"maxResults": 25
}

Add "opportunities" and "lobbying" to sources for the other two systems; opportunities needs your own free SAM.gov key in samApiKey.

Output — one row per record, same columns across all four sources; the fields you will use most are title, agency, postedAt, amount and url (full list under Output reference). Anything that could not be fetched comes back as a free diagnostic row (ok: false, errorType, error) instead of a charge, and summary / facet rows are free too.

Price — $0.60 per 1,000 opportunities, $0.40 per 1,000 awards and $0.60 per 1,000 lobbying filings on the FREE tier (+ $0.001 per run); rows your filters excluded, every detail fetch, every nested transactions[] / subawards[], and every summary, facet and diagnostic row are free. Pay-per-event, no browser, limited permissions — works over the Apify MCP server (mcp.apify.com) and with agentic (x402) payments.

From codeclient.actor("insight.solutions/federal-contracts-grants-api").call(run_input={…}) with apify-client, or POST https://api.apify.com/v2/acts/insight.solutions~federal-contracts-grants-api/run-sync-get-dataset-items.


What you get

One row per record. This is a real Grants.gov row, trimmed to the columns that carry something:

{
"ok": true,
"rowType": "opportunity",
"source": "grants.gov",
"input": "cybersecurity",
"recordId": "363843",
"url": "https://www.grants.gov/search-results-detail/363843",
"title": "Advisory Support for Establishing a National Cybersecurity Operations Center (SOC)",
"agency": "Department of State",
"subAgency": "Bureau of Emerging Threats",
"agencyCode": "DOS-ET",
"solicitationNumber": "DFOP0019791",
"postedAt": "2026-09-10T00:00:00.000Z",
"responseDeadline": "2026-10-16T04:00:00.000Z",
"daysUntilDeadline": 31,
"status": "posted",
"isActive": true,
"awardCeiling": 13912185,
"awardFloor": 13912185,
"estimatedFunding": 13912185,
"expectedAwards": 1,
"costSharing": false,
"eligibility": "Not for profit organizations, including think tanks, civil society and non governmental organizations; Public and private educational institutions; …",
"eligibilityTypes": [{ "code": "25", "description": "Others (see text field entitled \"Additional Information on Eligibility\" for clarification)" }],
"fundingInstruments": [{ "code": "CA", "description": "Cooperative Agreement" }],
"fundingCategories": [{ "code": "ST", "description": "Science and Technology and other Research and Development" }],
"alnNumbers": ["19.047"],
"opportunityCategory": "Discretionary",
"contacts": [{ "type": "agency", "fullName": "Bureau of Emerging Threats", "email": "ET-Programs@state.gov", "phone": "202-776-0446", "note": "ET-Programs@state.gov" }],
"attachments": [{ "fileName": "08262026 NOFO - … v3.docx", "fileDescription": "NOFO", "mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "sizeBytes": 138629, "id": 355006, "url": null }],
"description": "Improve Argentina's national cybersecurity posture by providing advisory support to design, establish, and operationalize a centralized, civilian led national Cybersecurity Operations Center …",
"scrapedAt": "2026-09-15T04:10:00.000Z",
"sourceUrl": "https://www.grants.gov/search-results-detail/363843"
}

A USAspending award row fills the award half of the same schema instead — awardId, generatedId, recipientName, recipientUei, amount, outlays, startDate, endDate, awardingAgency, contractAwardType, naics, psc, subawardCount, extentCompeted, and transactions[] / subawards[] when you ask for them. A Senate LDA row fills the lobbying half — client, registrant, amountReported, issueCodes, lobbyists[], governmentEntities[].

Six dataset views ship with it: Opportunities, Awards, Lobbying, Deadlines (opportunities sorted by how long you have left), Summaries and Problems.


Quick start

Keyless, and it returns rows immediately:

{
"sources": ["grants", "awards"],
"keywords": ["cybersecurity"],
"awardTypes": ["contracts"],
"maxResults": 25
}

All four sources, once you have a SAM.gov key:

{
"sources": ["opportunities", "grants", "awards", "lobbying"],
"samApiKey": "<your free SAM.gov Public API Key>",
"keywords": ["cybersecurity"],
"naicsCodes": ["541512"],
"setAsides": ["SBA"],
"lobbyingIssues": ["SCI"],
"maxResults": 100
}

A daily monitor of new small-business solicitations:

{
"sources": ["opportunities"],
"samApiKey": "<your key>",
"noticeTypes": ["o", "k", "p"],
"setAsides": ["SBA"],
"naicsCodes": ["5415"],
"incremental": true,
"maxResults": 200
}

The SAM.gov key, and why it is yours

SAM.gov's Terms of Use point automated users at its documented API rather than at the endpoints its own web page calls, so this Actor uses the official Get Opportunities Public API v2 at api.sam.gov and never scrapes sam.gov. That API takes a key, and the key belongs to you:

  1. Sign in at sam.gov.
  2. Open Account Details.
  3. Choose Request Public API Key.
  4. Paste it into samApiKey. The field is marked secret, so Apify encrypts it; the key is sent to api.sam.gov in an X-Api-Key header and never appears in a row, a log line, a status message or a sourceUrl.

A personal (non-federal) key allows 10 requests per day. Each request returns up to 1,000 notices, so ten requests is up to 10,000 notices — but it is ten requests, which is why:

  • the run asks for the largest page the API allows and takes as few pages as maxResults needs;
  • includeDescriptions is off by default — each notice's full description is a separate request, and at most five are fetched per run;
  • the run stops itself at ten requests and leaves a free cap-reached row rather than spending an allowance you may want for something else;
  • an HTTP 429 becomes a free rate-limited row that says what the daily limit is, and every row already returned stays in the dataset.

Leave samApiKey empty and the opportunities source is simply skipped, with one free diagnostic row saying where the key comes from. The other three sources need nothing at all.


Input

FieldTypeDefaultWhat it does
sourcesmulti-select["grants","awards"]opportunities (SAM.gov), grants (Grants.gov), awards (USAspending), lobbying (Senate LDA)
keywordsstring[][]Free text, applied per source
grantStatusesmulti-select["posted","forecasted"]Add closed and archived for history
awardTypesmulti-select["contracts"]contracts, idvs, grants, directPayments, loans, other
maxResultsinteger200Per source. 0 means no cap
samApiKeystring (secret)Your own free SAM.gov Public API Key. Only the opportunities source needs it
dateFrom / dateToISO date— / todayApplied per source. USAspending's own floor is 2007-10-01; SAM.gov accepts at most a one-year window
agenciesstring[][]Names or abbreviations. Resolved against each source's own agency list
statesstring[][]Two-letter codes
naicsCodesstring[][]Six digits or a prefix
pscCodesstring[][]Product or Service Codes
minAmount / maxAmountnumberAward amount, grant ceiling, or lobbying income/expenses
setAsidesstring[][]SBA, 8A, HZC, SDVOSBC, WOSB, EDWOSB, …
noticeTypesmulti-select[] (all)o solicitation, k combined synopsis, p presolicitation, r sources sought, s special notice, a award notice, g sale of surplus, i intent to bundle
recipientsstring[][]USAspending recipient search
lobbyingClients / lobbyingRegistrants / lobbyingLobbyistsstring[][]Partial-match name filters
lobbyingIssuesstring[][]LDA issue codes (SCI, TAX, DEF, …), validated against the LDA's own list
filingYearintegercurrent yearWhich year of LDA filings
activeOnlybooleantrueKeep only SAM.gov notices still reported as active
fundingCategories / eligibilities / fundingInstrumentsstring[][]Grants.gov facet codes
alnCodesstring[][]ALN / CFDA, e.g. 93.788
filingTypesstring[][]Q1Q4, RR, MM and the amendment codes
includeDetailsbooleantrueThe per-record detail fetch. Inside the row price
includeDescriptionsbooleanfalseSAM.gov full descriptions; each one costs a request against the 10/day key
includeTransactions / includeSubawardsbooleanfalseNested on award rows, never billed separately
maxTransactionsPerAward / maxSubawardsPerAwardinteger50 / 50Caps on those nested lists
includeSummarybooleantrueFree summary and facet rows
includeRawDescriptionbooleanfalseKeep the untouched HTML in descriptionHtml
incrementalbooleanfalseSkip records returned by an earlier run
stateStoreNamestringfederal-contracts-grants-stateWhich named store holds the cursor
maxConcurrencyinteger4Sources and detail fetches in flight
maxRunSecsinteger240Time budget; rows already returned are kept
proxyConfigurationobject{"useApifyProxy": true}Datacenter by default; all four APIs also answered unproxied

Filters switch sources on. Typing a set-aside turns the opportunities source on; an ALN turns grants on; a recipient turns awards on; a lobbying client turns lobbying on. It is additive only — it never removes a source you picked.


Output reference

Every row carries every column, null where it does not apply.

Envelopeok, rowType, input, source, sourceUrl, scrapedAt, error, errorType.

SharedrecordId, url, title, agency, subAgency, office, agencyCode, agencyHierarchy, postedAt, updatedAt, description, naics, psc.

opportunitynoticeId, noticeType, noticeTypeCode, solicitationNumber, parentNoticeId, responseDeadline, responseDeadlineLocal, responseTimeZone, daysUntilDeadline, archiveDate, setAside, setAsideDescription, placeOfPerformance, placeOfPerformanceState, placeOfPerformanceCountry, awardCeiling, awardFloor, estimatedFunding, expectedAwards, costSharing, eligibility, eligibilityTypes, fundingInstruments, fundingCategories, alnNumbers, opportunityCategory, contacts, attachments, isActive, isCanceled, status, modificationCount, descriptionHtml.

awardawardId, generatedId, internalId, awardType, awardTypeCode, awardCategory, contractAwardType, recipientName, recipientUei, recipientId, recipientParentName, recipientParentUei, recipientLocation, amount, outlays, baseAndAllOptions, baseExercisedOptions, startDate, endDate, potentialEndDate, dateSigned, lastModified, awardingAgency, awardingSubAgency, awardingOffice, fundingAgency, fundingSubAgency, parentAwardId, cfdaNumber, saiNumber, defCodes, extentCompeted, numberOfOffers, typeSetAside, subawardCount, subawardTotal, executiveCompensation, transactions, subawards.

lobbying-filingfilingUuid, filingType, filingTypeDisplay, filingYear, period, periodDisplay, filingDocumentUrl, postedByName, terminationDate, registrant, registrantId, registrantCity, registrantState, registrantCountry, registrantDescription, registrantContactName, registrantContactPhone, client, clientId, clientState, clientCountry, clientDescription, clientGovernmentEntity, income, expenses, expensesMethod, amountReported, issueCodes, activities, lobbyists, lobbyistCount, governmentEntities, foreignEntities, affiliatedOrganizations, convictionDisclosures.

summary / facetsummaryType, metric, label, code, value, count, rank, totalResults.

Notes on particular columns

  • daysUntilDeadline is the only derived number in the schema: whole days from that row's own scrapedAt to responseDeadline, negative once the deadline has passed. Everything else is published data, reshaped.
  • amountReported on a lobbying filing is income ?? expenses, so one numeric column sorts across both LD-2 reporting styles — a firm reports income for a client, an in-house filer reports expenses.
  • Money is null when absent, never zero. "No award ceiling published" and "a ceiling of nothing" are different facts.
  • Dates are ISO-8601 UTC instants. Four upstream formats feed them — ISO with an offset, MM/DD/YYYY, Sep 10, 2026 12:00:00 AM EDT, and 2026-06-15 07:29:54 — each parsed with an explicit month map and offset table, never handed to a permissive date constructor. USAspending's Last Modified Date publishes no time zone and is read as UTC.
  • contacts on a SAM.gov notice are the contracting officer or specialist that SAM.gov publishes so vendors can respond to the notice. Asking them about the solicitation is what they are for. They are not a marketing list.
  • attachments carries metadata and, on SAM.gov, the resource link. Nothing is ever downloaded. The Grants.gov attachment download path was not verified, so those rows carry url: null rather than a link that may not work.

Coverage, in numbers

Measured on 2026-09-15 against the live APIs:

  • SAM.gov — the opportunities API returns up to 1,000 notices per request, and a personal key gets 10 requests a day. postedFrom/postedTo are required and may be at most one year apart.
  • Grants.gov — 210 posted or forecasted opportunities matched "cybersecurity" on that date; roughly 1,200 are in posted status at any time. Adding closed and archived reaches back to at least 2015 — 18,316 hits for "water" alone.
  • USAspending — for one probe filter: 675 contracts, 564 grants, 128 IDVs, 40 direct payments, 5 other, 1 loan. Its own responses say the earliest date it will search is 2007-10-01.
  • Senate LDA56,482 filings in 2026 alone; 2,623 of them mention artificial intelligence in their issue descriptions.

Freshness, honestly

  • SAM.gov and Grants.gov are live at run time — a notice posted this morning is in this afternoon's run.
  • USAspending lags agency reporting by weeks. It is the record of what was paid, not a real-time feed.
  • Senate LDA filings appear within about a day of submission, but an LD-2 covers a calendar quarter: a Q3 report is a quarterly summary, not a signal about this week.

Running it every day

Set incremental: true and the run remembers what it has already returned, in a named key-value store that outlives the run. Four ID spaces are kept apart — SAM.gov notice IDs, Grants.gov opportunity IDs, USAspending internal IDs and LDA filing UUIDs — and the check happens before the detail fetch and before the charge, so a record you have already seen costs no request and no money. Use a different stateStoreName for each saved search.

The honest caveat: ID de-duplication also suppresses a record that has since been amended. A SAM.gov notice can be modified and a USAspending award's lastModified moves as transactions post. If you want modifications, run with incremental: false and a rolling dateFrom window instead. This is a "what's new" cursor, not a change monitor.

A quiet day — nothing new since yesterday — finishes successfully with zero paid rows and bills nothing.


What you are never charged for

  • Rows that were read and then excluded by one of your filters. Every filter runs before the row is written, so it is never billed.
  • summary rows: how many records each source matched in total, USAspending's award counts by category, and its top ten agencies, recipients and NAICS codes by obligated dollars.
  • facet rows: Grants.gov's own agency, funding-category, eligibility, funding-instrument and status counts.
  • Every diagnostic row — no-results, not-found, invalid-input, blocked, rate-limited, timeout, unavailable, cap-reached, budget-reached, notice, sam-api-key-required.
  • Nested transactions[], subawards[] and executiveCompensation[].
  • Every detail fetch: Grants.gov fetchOpportunity, USAspending's award record, SAM.gov's descriptions, the agency lists and the LDA constants.
  • A run that returns nothing. It finishes FAILED, says why, and bills nothing at all — the start fee included.

Pricing

EventFREEBRONZESILVERGOLD
Run started$0.001$0.001$0.001$0.001
Opportunity returned$0.0006$0.0006$0.00048$0.00036
Award returned$0.0004$0.0004$0.00032$0.00024
Lobbying filing returned$0.0006$0.0006$0.00048$0.00036

$0.60 per 1,000 opportunities, $0.40 per 1,000 awards, $0.60 per 1,000 lobbying filings at the free tier. A SAM.gov notice and a Grants.gov notice cost the same, because they are the same row doing the same work.

The run honours ACTOR_MAX_TOTAL_CHARGE_USD: when the ceiling is reached it stops fetching, leaves a free budget-reached row, keeps everything already delivered and finishes successfully.


Use it from an AI agent, or from code

One JSON object in, one flat array out — the shape agent runtimes want. The Actor runs with limited permissions, uses pay-per-event pricing and never enters Standby, so it works over the Apify MCP server and with x402 agentic payments. The Integrations tab pushes results to Slack, a webhook, Zapier, Make, Google Sheets, Snowflake or BigQuery.

curl -X POST "https://api.apify.com/v2/acts/insight.solutions~federal-contracts-grants-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sources":["grants","awards"],"keywords":["cybersecurity"],"maxResults":50}'
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("insight.solutions/federal-contracts-grants-api").call(run_input={
"sources": ["opportunities", "grants", "awards", "lobbying"],
"samApiKey": "<your free SAM.gov Public API Key>",
"keywords": ["cybersecurity"],
"naicsCodes": ["541512"],
"lobbyingIssues": ["SCI"],
"maxResults": 100,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if not row.get("ok"):
continue
if row["rowType"] == "opportunity":
print(row["source"], row["agency"], row["title"],
row["responseDeadline"], row["daysUntilDeadline"], row["url"], sep=" | ")
elif row["rowType"] == "award":
print("award", row["recipientName"], row["amount"], row["awardingAgency"], row["url"], sep=" | ")
elif row["rowType"] == "lobbying-filing":
print("lobbying", row["client"], row["registrant"], row["amountReported"], row["issueCodes"], sep=" | ")

Leave samApiKey out and the other three sources still work. Set incremental: true when you want a monitor rather than a backfill.


FAQ

Do I need any key at all? Only for SAM.gov contract opportunities, and that key is free and personal to you. Grants.gov, USAspending and the Senate LDA need nothing.

Why does SAM.gov need a key when the website does not? SAM.gov's Terms of Use direct automated users to its documented APIs rather than to the endpoints its own web page calls. This Actor follows that: it uses api.sam.gov/opportunities/v2/search and never scrapes sam.gov.

Can I get more than 10 SAM.gov requests a day? That is the published limit for a personal (non-federal) key. Each request returns up to 1,000 notices, so it is a limit on queries, not on volume. A federal account gets a higher allowance from GSA.

Why is my run slower than I expected? USAspending. A spending_by_award POST took between 1.2 and 14.9 seconds in testing, and the category queries that build the free summary rows took 6–13 seconds each. Raise maxRunSecs for large runs, or set includeSummary: false.

Can I filter by more than one NAICS code on SAM.gov? The API takes one NAICS per request and requests are the scarce resource, so the first one goes into the query and the rest are matched on the rows before they are written — which means they are still free to you, they just do not narrow the request.

Does it download attachments? No. It publishes the metadata — and, on SAM.gov, the resource link — so you can decide. Attachment downloading is not in this version.

Can I search SAM.gov entity or exclusion records? No, and deliberately. This Actor reads contract opportunity notices only. It never touches entity registration, exclusion or Dun & Bradstreet data.

What happens when a source is down? That source leaves a free diagnostic row saying so, and the others keep going. The run succeeds if any source produced a row, and fails — free — if none did.

Are the lobbyists' names really published? Yes. The Lobbying Disclosure Act requires registrants to name the individuals who lobbied on each issue, and the Senate Office of Public Records publishes those filings for public inspection. This Actor reproduces them as filed.


Limitations

  • SAM.gov needs your key, and a personal key is 10 requests a day. A very large SAM.gov backfill is several days of runs, not one.
  • Attachment downloads are not in v1. Metadata and links only.
  • Federal Register, FEC and SAM.gov entity data are not in v1.
  • Grants.gov has no server-side date filter. Date narrowing for that source happens on the rows, before they are written and billed, which is correct but means a wide date filter reads more pages than it returns.
  • USAspending's PSC filter takes code paths, not flat codes, so PSC narrowing for awards is done on the rows instead. Same for any filter the endpoint rejects: the query is re-sent without it and the narrowing happens here, with a free notice row telling you so.
  • The Senate LDA is 15 requests a minute for an anonymous caller, and this Actor paces itself to 14 with at least four seconds between requests. Two hundred filings is about eight requests and under a minute; twenty thousand is not a single run.
  • Incremental mode is a "what's new" cursor, not a change monitor — see the caveat above.
  • The upstream format may change. These are four independently operated government APIs. Every parser treats every field as optional and a shape it does not recognise becomes a free diagnostic row rather than a wrong value, but a column can go null if an agency changes what it publishes.

Sources, terms and attribution

All four sources are works of the United States Government and carry no copyright (17 U.S.C. §105). They are procurement, spending and lobbying-disclosure records published for public inspection. No use restriction of the kind the Ethics in Government Act places on congressional financial disclosures applies to any of this data — there is no equivalent statute here.

  • SAM.gov. Its Terms of Use state that automated data gathering and web scraping tools are prohibited and direct automated users to the APIs published at open.gsa.gov/api and sam.gov/data-services. This Actor uses exactly that: the documented Get Opportunities Public API v2, with your own key, at a polite volume, respecting the key's published allowance. A separate clause prohibiting systematic extraction is scoped to Dun & Bradstreet-supplied entity data — which this Actor never requests.
  • Grants.gov. This product uses the Grants.gov API but is not endorsed or certified by the U.S. Department of Health and Human Services. The Grants.gov API terms also forbid modifying or misrepresenting API content and reserve HHS's right to limit or terminate access.
  • USAspending. Its documentation states that endpoints do not currently require any authorization. DATA Act public data.
  • Senate LDA. Source: LDA.gov. Its terms set 15 requests per minute for an anonymous caller, require citing LDA.gov as the source, and forbid modifying or misrepresenting the content. The Senate Office of Public Records cannot vouch for data or analyses derived from these data after they have been retrieved from LDA.gov.

This Actor is independent. It is not affiliated with, endorsed by or sponsored by the U.S. General Services Administration, the Department of Health and Human Services, the Department of the Treasury or the Senate Office of Public Records. Nothing here is legal advice, and you are responsible for using the data lawfully.


Our other Actors

Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.

Video, audio & social

News, documents & the web

Business, finance & jobs

Apps & games