Skip to content

Forecast pipeline — monitor upcoming agency opportunities

Get a webhook when new procurement forecasts post that match your industry / agency / fiscal-year window. Forecasts are agency-published lists of opportunities they plan to release — useful for capture planning months ahead of the actual solicitation.

Tango ingests forecasts from HHS, DHS, GSA, COMMERCE, DOE, TREASURY, DOI, DOL, DOT, VA, and NRC. See the Forecasts data dictionary for the current list.

The 1-line answer

Create a filter alert on query_type=forecast. Filters are the same query parameters you'd pass to /api/forecasts/.

curl -X POST -H "X-API-KEY: $TANGO_API_KEY" \
  -H "Content-Type: application/json" \
  "https://tango.makegov.com/api/webhooks/alerts/" \
  -d '{
    "name": "VA IT services forecast — FY26",
    "query_type": "forecast",
    "filters": {
      "agency": "VA",
      "naics_starts_with": "5415",
      "fiscal_year": "2026"
    },
    "frequency": "weekly"
  }'

That's it. Tango re-evaluates weekly and POSTs alerts.forecast.match events when new forecasts match.

Step 1 — Verify the filter against the forecasts API

curl -H "X-API-KEY: $TANGO_API_KEY" \
  "https://tango.makegov.com/api/forecasts/?agency=VA&naics_starts_with=5415&fiscal_year=2026&ordering=anticipated_award_date&limit=5"

If this returns the forecasts you expect, the alert will fire when new ones land.

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": "VA + DHS — IT consulting forecasts FY26",
    "query_type": "forecast",
    "filters": {
      "agency": "VA",
      "naics_starts_with": "5415",
      "fiscal_year": "2026",
      "award_date_after": "2026-04-01",
      "award_date_before": "2026-12-31"
    },
    "frequency": "weekly"
  }'
import os
from tango import TangoClient

client = TangoClient(api_key=os.environ["TANGO_API_KEY"])

alert = client.create_webhook_alert(
    name="VA — IT consulting forecasts FY26",
    query_type="forecast",
    filters={
        "agency": "VA",
        "naics_starts_with": "5415",       # NAICS prefix — matches 541511, 541512, 541519, etc.
        "fiscal_year": "2026",
        "award_date_after": "2026-04-01",
        "award_date_before": "2026-12-31",
    },
    frequency="weekly",
)
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: "VA — IT consulting forecasts FY26",
  query_type: "forecast",
  filters: {
    agency: "VA",
    naics_starts_with: "5415",          // NAICS prefix
    fiscal_year: "2026",
    award_date_after: "2026-04-01",
    award_date_before: "2026-12-31",
  },
  frequency: "weekly",
});
console.log(alert.alert_id, alert.status);

Step 3 — Available forecast filters

These are the keys accepted by /api/forecasts/ and therefore by query_type=forecast alerts.

Filter Notes
agency Agency acronym (e.g. VA, DHS, HHS, GSA).
source_system Source system identifier — useful when an agency publishes forecasts via multiple feeds.
naics_code Exact NAICS match.
naics_starts_with NAICS prefix match (e.g. 5415 for any 5415xx).
fiscal_year Exact fiscal year.
fiscal_year_gte / fiscal_year_lte Fiscal year range.
award_date_after / award_date_before Anticipated award date range (YYYY-MM-DD).
modified_after / modified_before Date the forecast was last modified in Tango.
status Forecast status (case-insensitive partial match).
title Substring match on title.
search Full-text search over title/description (vector-backed).

Filter names matter

NAICS filtering uses naics_code (exact) or naics_starts_with (prefix) — there is no plain naics filter on /api/forecasts/. There is also no set_aside filter on forecasts — that's a SAM/FPDS-side concept not present in agency forecast publications.

For full filter docs, see the Forecasts API reference.

Step 4 — Receive alerts.forecast.match events

{
  "timestamp": "2026-05-12T08:00:14Z",
  "delivery_id": "8c5e3f6a-...-9b21",
  "events": [
    {
      "event_type": "alerts.forecast.match",
      "alert_id": "e4c4...-...-...",
      "query_type": "forecast",
      "filters": {
        "agency": "VA",
        "naics_starts_with": "5415",
        "fiscal_year": "2026"
      },
      "matches": {
        "new_count": 2,
        "modified_count": 0,
        "new": [
          {"id": "...", "external_id": "VA-2026-PRE-08712", "title": "VistA Modernization Phase IV", "agency": "VA", "naics_code": "541512", "anticipated_award_date": "2026-09-30"},
          {"id": "...", "external_id": "VA-2026-PRE-08813", "title": "Health Data Lake Refresh", "agency": "VA", "naics_code": "541511", "anticipated_award_date": "2026-08-15"}
        ],
        "modified": []
      },
      "checked_at": "2026-05-12T08:00:12.000Z"
    }
  ]
}

Pull full forecast details from /api/forecasts/{id}/ (or via client.get_forecast(id) / client.getForecast(id)) when you need more than the summary fields.

Limitations

  • No set_aside filter on forecasts. Forecasts don't expose a set-aside dimension; that's an FPDS/SAM concept that only shows up downstream when the actual opportunity / award posts.
  • Forecast cadences are slow. Most agencies refresh forecasts monthly or quarterly. weekly is typically the right cadence; realtime works but won't actually fire more often than the underlying refresh.
  • Coverage varies by agency. Only the 11 source agencies listed above are ingested today. Filtering on agency=DOJ returns nothing because Tango doesn't ingest DOJ forecasts.
  • Tier caps apply. Free 1 / Micro 3 / Small 5 / Medium 10 / Large 25 simultaneous alerts.