Awards by NAICS — stream new contracts in your industry codes¶
Get a webhook whenever new contracts land in one or more NAICS codes you care about. Optionally narrow by agency, set-aside, or dollar floor.
The 1-line answer¶
Create a single filter alert on query_type=contract with the NAICS codes you want — use | to OR multiple codes into one alert.
curl -X POST -H "X-API-KEY: $TANGO_API_KEY" \
-H "Content-Type: application/json" \
"https://tango.makegov.com/api/webhooks/alerts/" \
-d '{
"name": "IT consulting NAICS — 541511 / 541512 / 541519",
"query_type": "contract",
"filters": { "naics": "541511|541512|541519" },
"frequency": "realtime"
}'
That's it. One alert covers any number of NAICS codes.
Step 1 — Verify the filter against the contracts API¶
curl -H "X-API-KEY: $TANGO_API_KEY" \
"https://tango.makegov.com/api/contracts/?naics=541511|541512|541519&ordering=-award_date&limit=5"
If this returns recent contracts in your codes, you're good.
Step 2 — Create the alert¶
curl -X POST -H "X-API-KEY: $TANGO_API_KEY" \
-H "Content-Type: application/json" \
"https://tango.makegov.com/api/webhooks/alerts/" \
-d '{
"name": "IT consulting NAICS",
"query_type": "contract",
"filters": {
"naics": "541511|541512|541519",
"obligated_gte": "100000"
},
"frequency": "realtime"
}'
import os
from tango import TangoClient
client = TangoClient(api_key=os.environ["TANGO_API_KEY"])
alert = client.create_webhook_alert(
name="IT consulting NAICS",
query_type="contract",
filters={
"naics": "541511|541512|541519",
"obligated_gte": "100000",
},
frequency="realtime",
)
print(alert.alert_id, alert.status)
import { TangoClient } from "@makegov/tango-node";
const client = new TangoClient({ apiKey: process.env.TANGO_API_KEY! });
const alert = await client.createWebhookAlert({
name: "IT consulting NAICS",
query_type: "contract",
filters: {
naics: "541511|541512|541519",
obligated_gte: "100000",
},
frequency: "realtime",
});
console.log(alert.alert_id, alert.status);
Step 3 — Refine with optional filters¶
Stack any of these on top of naics to narrow the alert. All filters are AND-combined.
| Filter | Notes |
|---|---|
funding_agency / awarding_agency | Vector-backed agency match — "DOD", "Navy", "NAVSEA" all work. Pick the role you actually care about. |
psc | Six-digit PSC code; same \| multi-value syntax as naics. |
set_aside | SBA, 8A, WOSB, SDVOSB, etc. Multi-value via \|. |
obligated_gte / obligated_lte | Dollar thresholds. |
recipient_state / place_of_performance | Geographic filters. |
ordering | Doesn't apply to alerts (the evaluator processes new matches as they arrive). |
Example with all the dials turned:
{
"name": "DOD IT services > $1M, small business",
"query_type": "contract",
"filters": {
"funding_agency": "DOD",
"naics": "541511|541512|541519",
"obligated_gte": "1000000",
"set_aside": "SBA|8A|WOSB|SDVOSB"
},
"frequency": "realtime"
}
Step 4 — Receive alerts.contract.match events¶
{
"timestamp": "2026-05-12T18:20:14Z",
"delivery_id": "8c5e3f6a-...-9b21",
"events": [
{
"event_type": "alerts.contract.match",
"alert_id": "e4c4...-...-...",
"query_type": "contract",
"filters": {
"naics": "541511|541512|541519",
"obligated_gte": "100000"
},
"matches": {
"new_count": 3,
"modified_count": 0,
"new": [
{"id": "CONT_AWD_...", "piid": "W15QKN24C1234", "obligated": 1450000, "recipient_uei": "ABC123..."},
{"id": "CONT_AWD_...", "piid": "FA8773-24-C-...", "obligated": 230000, "recipient_uei": "DEF456..."},
{"id": "CONT_AWD_...", "piid": "N00033-24-D-...", "obligated": 5400000, "recipient_uei": "GHI789..."}
],
"modified": []
},
"checked_at": "2026-05-12T18:20:12.000Z"
}
]
}
For the full receiver implementation (signature verification, idempotency, fast 2xx), see Stream contract awards in real time.
Limitations¶
- One alert per saved query. If you want different downstream routing per NAICS, create separate alerts and dispatch on
alert_idin your receiver. - Tier caps apply. Free 1 / Micro 3 / Small 5 / Medium 10 / Large 25 simultaneous alerts.
- Realtime is "after each ingestion cycle" — FPDS ingest runs roughly twice daily. Realtime delivers within minutes of each refresh, not within minutes of upstream FPDS publication.
naics_starts_withis not a contracts filter. Contracts only support exactnaics. If you need a NAICS prefix, list the codes explicitly with|.
Related¶
- Webhooks user guide — protocol reference
- Stream contract awards in real time — full how-to including receiver code
- Contracts API reference — full filter list