Government Contract and Tender Posting Alerts
Watch public procurement portals for new RFPs and tender postings matching your keywords - without daily portal logins.
The scenario
You sell into the public sector. New RFPs and tenders get posted on a handful of government procurement portals - federal, state, sometimes a specific agency. The deadlines are short and the submission process is long, so a one-day-late notification can cost you the bid.
The same problem exists for nonprofits chasing grants, vendors tracking municipal IT spending, and consultancies tracking management-consulting RFPs.
The problem
Procurement portals are notorious for poor UX. Search filters are coarse, email alerts batch overnight, and there's no machine-readable feed for most of them. Aggregators exist (BidNet, GovTribe) but are priced for big procurement teams. For a small firm watching ten keywords across three portals, those tools are overkill.
How Verid solves it
Most procurement portals expose a search URL where the results are HTML. Point Verid at that URL - already filtered for your keyword or NAICS code - and extract the first result's title and posting date. When the title changes, a new posting matched.
For portals where the results layout is too varied for CSS selectors, the prompt extractor reads the rendered page and returns the most recent posting matching your criteria as structured output.
Build the monitor
Extraction config - CSS for structured portals
{
"method": "css",
"fields": {
"latest_title": ".search-results li:first-child .opportunity-title",
"latest_posted": ".search-results li:first-child .posted-date",
"latest_url": ".search-results li:first-child a"
}
}
Extraction config - Prompt for messy portals
{
"method": "prompt",
"prompt": "From this procurement portal results page, find the most recently posted opportunity related to 'cybersecurity consulting'. Return its title, posting date (ISO), response deadline (ISO), and URL.",
"schema": {
"title": "string",
"posted": "string",
"deadline": "string",
"url": "string"
}
}
Predicate
{ "type": "field_changes", "field": "latest_title" }
A new title at the top of the search results means a new opportunity matched.
Create the monitor
curl -X POST https://api.verid.dev/v1/monitors \
-H "Authorization: Bearer vrd_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "SAM.gov - cybersecurity consulting",
"url": "https://sam.gov/search/?keywords=cybersecurity+consulting",
"schedule_interval_seconds": 14400,
"extract_config": {
"method": "css",
"fields": {
"latest_title": ".search-results li:first-child .opportunity-title",
"latest_posted": ".search-results li:first-child .posted-date",
"latest_url": ".search-results li:first-child a"
}
},
"diff_predicate": { "type": "field_changes", "field": "latest_title" },
"deliveries": [
{ "type": "slack", "webhookUrl": "https://hooks.slack.com/services/..." }
]
}'
SDK:
import { VeridClient } from '@verid.dev/sdk';
const client = new VeridClient({ apiKey: 'vrd_your_api_key' });
await client.monitors.create({
name: 'SAM.gov - cybersecurity consulting',
url: 'https://sam.gov/search/?keywords=cybersecurity+consulting',
schedule_interval_seconds: 14400,
extract_config: {
method: 'css',
fields: {
latest_title: '.search-results li:first-child .opportunity-title',
latest_posted: '.search-results li:first-child .posted-date',
latest_url: '.search-results li:first-child a',
},
},
diff_predicate: { type: 'field_changes', field: 'latest_title' },
deliveries: [
{ type: 'slack', webhookUrl: 'https://hooks.slack.com/services/...' },
],
});
What the webhook delivers
{
"id": "del_01H...",
"fired_at": "2026-05-08T12:14:00Z",
"diff": {
"fields_changed": ["latest_title", "latest_posted", "latest_url"],
"before": {
"latest_title": "Cybersecurity Risk Assessment Services - Dept of Energy",
"latest_posted": "2026-04-29",
"latest_url": "https://sam.gov/opp/abc123"
},
"after": {
"latest_title": "Cyber Threat Hunting Support - DHS CISA",
"latest_posted": "2026-05-08",
"latest_url": "https://sam.gov/opp/xyz789"
}
}
}
Caveats & tips
- Bookmark a filtered URL. The fewer results returned by the search, the lower the false-positive rate. Filter by agency, NAICS code, value range - whatever narrows it.
- One monitor per keyword. Each keyword gets its own monitor and its own Slack channel routing. Cleaner than one mega-monitor.
- Multiple portals. SAM.gov, state procurement portals, FedConnect - each is its own monitor with its own selectors or prompt. Once set up, they all flow into the same downstream alert.
- Browser mode if the portal is JS-heavy. Some portals only render results after a JavaScript-driven search call. Set
fetch_mode: 'browser'on those.
Related use cases
For job-board postings, see job listings for keywords. For grant deadlines specifically, see scholarship & grant deadlines. For regulatory pages that may affect your bid, see regulatory filings & policy pages.
Related use cases
Ship this monitor today
5 monitors free, no credit card. Set up takes about a minute.
Get started free