Build With Tango: A solicitation pipeline, not a rear-view mirror
Third in the budget endpoint series. The first two posts looked at money that's already been spent. This one looks forward, at money that's been appropriated but hasn't become a contract yet — and shows how to surface a ranked watchlist of those accounts with one query.
The problem
Award data is a rear-view mirror. By the time work shows up in USASpending, it's won. If you want to position before a solicitation drops, you need a leading indicator, and the budget gives you two: money that's been appropriated but not yet obligated, and money the agency is requesting more of next year. The hard part isn't finding growth; it's knowing whether that growth is genuinely new work or just a renewal of what an incumbent already holds.
The query
Every numeric field on the budget endpoint is filterable with __gte / __lte, so the watchlist is a single call. Three filters do most of the work:
- Contract-heavy —
contract_share_of_obligated_capped__gte=0.6(at least 60% of dollars flow as contracts) - Growing —
ba_growth_next_year_pct__gte=0.15(next-year request up ≥15%) - Appropriated headroom —
unobligated_balance__gte=200_000_000($200M+ teed up but not yet on contract)
Order by largest headroom first and you have a ranked list:
from tango import TangoClient
client = TangoClient()
watchlist = client.list_budget_accounts(
fiscal_year=2024,
contract_share_of_obligated_capped_gte=0.6,
ba_growth_next_year_pct_gte=0.15,
unobligated_balance_gte=200_000_000,
ordering="-unobligated_balance",
shape=(
"federal_account_symbol,account_title,agency_name,"
"unobligated_balance,ba_growth_next_year_pct,next_year_requested_ba"
),
)
(Requires tango-python ≥ 1.2.0, which exposes the full range-filter surface as explicit kwargs.)
What comes back
Eight FY2024 accounts:
| Symbol | Agency / account | Unobligated | Next-yr growth |
|---|---|---|---|
| 075-0511 | HHS — CMS Program Management | $7.6B | +421% |
| 014-1039 | Interior — NPS Construction | $1.85B | +64% |
| 015-0203 | DOJ — FBI Construction | $1.18B | +107% |
| 075-1000 | HHS — ASPR (BARDA) | $568M | +20% |
| 080-0130 | NASA — Construction & Environmental | $511M | +30% |
| 021-2086 | DoD — Military Construction, Army Reserve | $294M | +46% |
| 014-1612 | Interior — Fish & Wildlife Construction | $263M | +66% |
| 020-1855 | Treasury — Cybersecurity Enhancement | $221M | +311% |
Eight accounts, eight different agencies and missions. The point isn't this specific list — it's that you can vary the filters (drop the contract-share cutoff to pull in mixed contract/grants accounts, raise the growth bar, scope to a single agency_code) and the same shape works.
Drilling into one row
The forward-looking number tells you an account is about to buy. To tell net-new scope from a recompete, look at who's already there. Pick HHS's Administration for Strategic Preparedness and Response (075-1000) — the BARDA account that buys vaccines, antivirals, and medical countermeasures:
| Field | FY2024 |
|---|---|
| Enacted / apportioned | $3.14B |
| Obligated | $2.57B |
| Appropriated but not yet on contract | ~$568M |
| Contract share | 84% |
| Next-year request | $3.77B (+20%) |
So roughly $568M sitting un-obligated, and the agency asked for ~$633M more the following year. That's over $1.2B of potential buying in a heavily-contracted account. The question is whether it's net-new.
Pull the recipients:
aspr = next(
r for r in watchlist.results if r["federal_account_symbol"] == "075-1000"
)
for r in client.get_budget_account_recipients(aspr["id"], limit=6).results:
name = (r.get("recipient") or {}).get("legal_business_name")
print(f"{name:42} ${r.get('contract_obligated'):,.0f}")
The top BARDA recipients cluster tightly: Merck ~$147M, Emergent ~$147M, Amgen ~$129M, SIGA ~$113M, ATI ~$112M. None hold more than ~$150M, and the forward-looking headroom is over $1.2B. When the pipeline dwarfs what any one incumbent could absorb, the growth is unlikely to be just a like-for-like renewal — that's a signal of net-new scope.
Contrast with the construction-heavy rows in the same watchlist. NPS Construction (014-1039) carries $1.85B unobligated with +64% next-year growth; FBI Construction (015-0203) carries $1.18B with +107% growth. Different mission, same play — except here the recipient analysis matters less, because construction money naturally fragments into discrete project RFPs. Appropriated-but-unspent dollars are the pipeline.
What you'd build with it
- A pre-solicitation watchlist. The query above is the watchlist. Schedule it weekly; diff against the prior run; alert on new entries.
- A net-new vs. recompete classifier. For each account on the watchlist, compare forward-looking dollars against the incumbent base from
recipients/. Headroom much larger than any incumbent's hold → likely new scope; headroom roughly equal to an expiring award → likely a recompete. - A trigger for the rest of Tango. When an account lights up, cross-reference opportunities and forecasts for the same agency to catch the solicitation as it posts.
This is the leading edge the announcement promised: reasoning about money before it becomes an award. Field definitions and the full filter surface are in the Budget API reference. If you carry an account list in a CRM, the free tier covers what you'd need to build a watchlist in an afternoon, and the same queries run through the Tango MCP server at govcon.dev/mcp.
Ready to get started with Tango?
If you're working with federal procurement data, Tango provides a unified API that combines federal procurement data sets and improves on them with a developer-friendly approach. Skip the complexity of scraping and joining multiple government APIs yourself.