Search procurement forecasts
Every other dataset here records what already happened or what is open now. Forecasts are the forward-looking layer: an agency's own projection of a planned requirement, published months to years before a solicitation exists. That is the window where teaming, capability positioning and incumbent displacement happen, before the RFP locks the field.
Forecasting is a legal requirement. Under the Small Business Act and FAR Part 19, each agency's Office
of Small and Disadvantaged Business Utilization publishes an annual projection of upcoming
opportunities. This resource assembles three of those publications into one shape: the government-wide
GSA Forecast of Contracting Opportunities (fco), DHS APFS (dhs) and HHS SBCX (hhs).
Search and every filter are open on all plans, and the requirement owner's name is on every record.
The direct contact lines (email, phone, contracting officer, small-business specialist) and the
incumbent_award block on recompetes are Pro. Check
Data status for the current record count and freshness.
Search takes no required filter, so the smallest call that proves it works is one row, shown here trimmed to four of the record's fields:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://govconapi.com/api/v1/forecasts/search?limit=1"
{ "title": "Benefits Enterprise Services - New Task Order",
"agency": "Department of Veterans Affairs",
"est_award_fy": 2026,
"status": "Solicitation Issued" }
One planned requirement: a Veterans Affairs task order the department expects to award in fiscal
2026, whose status of Solicitation Issued says this particular plan has already reached the
street.
Endpoints
GET /api/v1/forecasts/search, search planned requirements by source, agency, NAICS, set-aside, place, award year, value, status, recompete flag or keyword
A forecast is a plan, not a commitment
Every record is an agency projection, subject to revision, delay or cancellation. Dollar figures are published as ranges, award dates are estimates, and a planned requirement may slip a year, change scope or never solicit at all. Treat a row as a lead with a named person attached, not as a pipeline entry you can weight like an open solicitation.
This is also the boundary of the resource. A forecast tells you what an agency intends to buy and who owns the requirement. It does not tell you that a solicitation will issue, when it will really issue, or what the award will be worth. Pair it with Search opportunities to see whether the plan has actually reached the street.
What the default query has already dropped, and what it keeps
active_only is on by default, and it applies two clauses at once.
It drops records whose lifecycle status says the plan is finished: Awarded, Cancelled and
Option Ended-Closed Out. A record whose status is null is kept, which matters because a large
share of GSA records publish no status at all.
It drops records whose estimated award fiscal year is older than the current one. A record whose
est_award_fy is null is kept, so a null year is never treated as a past year.
Only the GSA feed carries a moving lifecycle status, so on the DHS and HHS records the fiscal-year
floor is what does the work. Pass active_only=false to read the same data as competitive history:
what an agency planned, and what it then awarded.
The fiscal year itself is passthrough, and the feeds publish malformed ones. Two-digit years, years
carrying a stray extra digit, and years a century or more outside a plausible window all appear
straight from the source. We never rewrite a published value, and the active_only floor only removes
the malformed years that happen to read as past: a malformed year that reads as far-future survives
the default filter and sorts to the front of a descending est_award_fy page. Bound both ends of any
range scan over est_award_fy to a plausible four-digit window rather than trusting the default to
have removed the noise for you.
One shape, three feeds, and a filter that can silently exclude a whole source
The three publications are normalised into one record, but they do not publish the same things, and a filter that matches nothing in one feed returns a quietly partial market read rather than an error.
- Place of performance. The GSA and DHS feeds publish it; the HHS feed publishes none, so a
statefilter returns no HHS records at all.statematchespop_stateexactly and case-insensitively, notpop_city. A large block of GSA records publishes the literal stringCannot be disclosedinpop_state,pop_cityandpop_countrytogether, which is the agency's published value rather than a null, sostate=VAand every other two-letter query silently drops all of them. Read that block withstate=Cannot be disclosed, and treat any state-scoped market size as a floor. Some DHS records publishNAinpop_statefor the same reason. - Lifecycle status. Only the GSA feed moves
statusthrough a lifecycle:Acquisition Planning,Market Research,Drafting Solicitation,Solicitation Issued,Evaluation Stage,Exercise of Option,AwardedandCancelled. The DHS feed publishesPublishedon every row and the HHS feed publishesPUBLISHEDon every row, and those are the only values either carries. The filter is one case-insensitive substring match over all three, sostatus=Acquisition Planningreturns GSA records and nothing else, whilestatus=Publishedreturns the whole DHS and HHS feeds and no GSA record at all. A lifecycle-status filter is a GSA filter; passsource=fcoalongside it so that is explicit rather than accidental. -
Estimated quarter. The three feeds spell it three ways, and
est_award_quarteris a case-insensitive substring match against the whole published string. Filter with the token that belongs to the feed you are reading:fcowrites an ordinal with the calendar span. The full vocabulary is1st (October 1 - December 31),2nd (January 1 - March 31),3rd (April 1 - June 30),4th (July 1 - September 30)andTo Be Determined. Filter on the ordinal:est_award_quarter=4th.dhswrites the quarter joined to the fiscal year, spelledQ4 2026,Q1 2027and so on, and never leaves it empty. Filter onQ4for every fourth-quarter row in the feed, or onQ4 2026for one quarter of one year.hhspublishes no quarter at all, so anyest_award_quartervalue returns zero HHS records.
A bare digit is the one input that does not select a quarter. It matches the calendar span on the GSA spelling and the year on the DHS spelling. Measured 2026-09-20 with
active_only=false,source=dhs&est_award_quarter=0returns the entire DHS feed, because every value carries a20xxyear;source=fco&est_award_quarter=1returns more than half the GSA feed, becauseOctober 1,January 1,April 1,July 1,December 31andMarch 31all contain a1; andsource=fco&est_award_quarter=1streturns the first-quarter rows and nothing else. -
Set-aside. Three vocabularies, matched by one case-insensitive substring filter.
fcopublishes a descriptive program name on nearly every record:To Be Determined,Small Business,Other Than Small Business,Small Business Set Aside - Total,Set-Aside Small Business - Partial,Set-Aside - Veteran,8(a) Competitive,8(a) Sole Source,Set-aside - Service Disabled Veteran Owned Small Business,Indian Small Business Economic Enterprise (ISBEE),Women-owned Small Business (WOSB),HUBZone,Mandatory Source,Indian Economic Enterprise (IEE),Small Disadvantaged Business (SDB),SDVOSB Sole Source,Unrestricted,Buy Indian,HUBZone Sole Source,Veteran Sole Source,Economically Disadvantaged Women-owned Small Business (EDWOSB)and8(a) with HUB Zone Preference. The most common of these isTo Be Determined, a published GSA value meaning the decision is open.dhspublishes a short code on a little over half its records:SB,8(a),HUBZone,WOSB,SDVOSBandAbilityOne.hhspublishes a coarse two-value flag on a minority of records,Small BusinessorFull and Open, and nothing on the rest. There is no program granularity in that feed, so a specific-program filter returns no HHS records.
Substring matching is what lets one term reach across the three spellings, and it is also what over-matches.
set_aside=SBscoped todhsreturns theWOSBandSDVOSBrows too, becauseSBis a substring of both.set_aside=Small Businessscoped tofcoreturns theOther Than Small Businessrows, which carry the opposite meaning. Anchor on the longest fragment that appears only inside its own program family:8(a),HUBZone,WOSBandSole Sourceeach reach every variant of their family and nothing outside it, soWOSBalso returns theEDWOSBrow and8(a)also returns the competitive and sole-source variants. Passsourcewhenever you need the vocabulary itself to be uniform. -
Product or service code. No feed publishes one.
pscis present in the shape and null on every record, so a PSC-based market model has to come from the awards side instead.
Read the value range from the numbers, not the text. value_range_text is the source's own label
and each feed formats it differently. value_low and value_high are parsed from that label into
numbers for you, and amount_min / amount_max match on overlap rather than containment:
amount_max returns every forecast whose low bound sits at or below your ceiling, and amount_min
every forecast whose high bound sits at or above your floor. A forecast whose published range
straddles your bound is therefore returned, not excluded.
The incumbent award is the contract we could resolve, not always the one expiring
When a forecast replaces an existing contract, the GSA, DHS and HHS feeds name the incumbent and,
usually, the contract number. On Pro, that number is resolved against the federal award record and the
row gains an incumbent_award block: who holds it, the current value, when it expires, and the date
of the last action on it. That is the displacement view, and it is the reason to filter
is_recompete=true. A minority of records name an incumbent, so the recompete slice is worth
filtering to rather than scanning for.
Three things to check before you act on the block. First, the forecast's own incumbent_name is the
agency's free-text spelling and the block's recipient_name is the registered legal name, so they
often differ, and on a multiple-award vehicle the forecast may list many holders while the block
resolves the one contract number it was given. Second, a named contract number sometimes resolves to a
later task order under the same vehicle rather than the expiring base award; expires and
latest_action_date tell you which one you are looking at. Third, expires is a fact about the
resolved award and carries no relationship to today: a live forecast routinely names an incumbent
whose period of performance has already ended, which normally means a bridge or extension is carrying
the work while the replacement is still in the plan stage. Compare expires against the current date
before you treat it as runway.
The block is best-effort. A recompete whose contract number does not resolve returns
incumbent_award: null with incumbent_name and incumbent_piid still populated, so filter on
incumbent_award being present when you need the full displacement picture.
Parameters
| Parameter | Type | Description |
|---|---|---|
source |
string | One of fco (GSA Forecast of Contracting Opportunities), dhs (APFS) or hhs (SBCX). Any other value returns 400. Optional, and the single most useful filter when a field's vocabulary matters. |
agency |
string | Agency name, case-insensitive partial match. Optional. |
naics |
string | NAICS code, 2 to 6 digits, prefix match, so 5415 returns every code beneath it. A handful of GSA records publish only a sector-level code and are reachable only by a prefix that short. Fewer than 2 or more than 6 digits, or any non-digit, returns 400. Optional. |
set_aside |
string | Set-aside program, case-insensitive substring match. Three vocabularies, listed in full in the feed-coverage section above, where the over-matching terms are named. Optional. |
state |
string | Place-of-performance state, 2-letter, exact case-insensitive match on pop_state. Returns no HHS records, which publish no place, and excludes the GSA block published as Cannot be disclosed. Optional. |
est_award_fy |
integer | Estimated award fiscal year, exact match. Passthrough, so malformed published years are matchable too. Optional. |
est_award_quarter |
string | Estimated award quarter, case-insensitive substring match against the feed's own spelling. A bare digit does not select a quarter; use the per-feed token listed above. Optional. |
amount_min, amount_max |
number | Estimated value bounds in dollars. Matches on range overlap, not containment. value_min and value_max are accepted aliases; sending a canonical name and its alias in the same request returns 400 rather than silently dropping one. Optional. |
status |
string | Lifecycle status, case-insensitive substring match. Effectively a GSA-feed filter: the DHS and HHS feeds carry one constant value each, so any lifecycle term excludes them entirely. Optional. |
is_recompete |
boolean | true narrows to forecasts that name an incumbent contract number. A narrowing flag only, so false does not exclude recompetes. Optional. |
keywords |
string | English full-text search across title and description. Stemmed and stopword-aware, not a substring match, so a multi-word phrase matches on all of its terms. Optional. |
active_only |
boolean | Defaults to true: forward-looking, not-yet-finished records only. Null status and null est_award_fy are both kept, see above. false includes finished and past-fiscal-year records. |
fields |
string | Comma-separated projection, supported on this endpoint. source and source_id are always returned whether or not you list them, because the pair is the record key. An unknown name returns 400 with the valid names. See Response Shaping for the syntax. Optional. |
sort_by |
string | See Ordering below. Optional. |
sort_order |
string | asc or desc, defaulting to desc. Applies only alongside sort_by. Optional. |
limit, offset |
integer | Page size and offset. limit defaults to 100 and is capped by your plan, see Plans and Limits. Optional. |
Every filter you send is combined with AND. There is no OR form and no repeated-parameter form, so a
multi-value query is several requests. filters_applied in the response echoes what actually took
effect, which is the cheapest way to confirm a filter was read the way you meant it.
Ordering
sort_by accepts est_award_fy, est_solicitation_date, value_high, agency and
last_updated_date. Anything else returns 400 with the allowlist in the message. sort_order
accepts asc or desc and defaults to desc. Nulls sort last in either direction, so sorting by
last_updated_date pushes the HHS records, which publish no update stamp, to the end.
Omit sort_by and the order is a fixed compound one: soonest estimated award fiscal year first, then
largest value range first within that year, then source and record key as the tie-break. sort_order
has no effect on that default, so pass sort_by explicitly whenever the direction matters.
Pagination
Offset-based, with limit and offset. The default page size and the per-plan cap are in the
Parameters table and in Plans and Limits; a limit above your cap returns 402
rather than a silently shortened page.
total is counted behind a ceiling. When a query matches more rows than the ceiling, total reports
the ceiling and total_is_estimate is true, which is your signal that the real figure is higher.
has_next reports page fullness, not a lookahead, so a final page that exactly fills limit reports
true and the following page comes back empty. For a bulk read, narrow by source, agency or
est_award_fy until total_is_estimate is false, then page with offset.
Response
A single record, with the description abridged for length. This is the full field set; the Examples
below use fields to trim to what each one reads.
{
"data": [
{
"source": "dhs",
"source_id": "*F2025068551",
"source_url": null,
"title": "Enterprise Automation and Unified Task Orchestration (eAUTO)",
"description": "***8/3/26 - updated Estimated Award Date. ***4/9/26 - Solicitation has been released ...",
"naics": "541519",
"psc": null,
"agency": "Department of Homeland Security",
"sub_agency": "USCIS",
"office": "MGMT/OIT/EID",
"value_low": 50000000.0,
"value_high": 100000000.0,
"value_range_text": "$50M to $100M",
"est_solicitation_date": "2026-04-01",
"est_award_date": "2026-08-17",
"est_award_fy": 2026,
"est_award_quarter": "Q4 2026",
"pop_start": "2026-09-22",
"pop_end": "2031-03-21",
"set_aside": null,
"contract_type": "Firm Fixed Price",
"extent_competed": "Follow-on to Existing Contract",
"acquisition_strategy": "GSA Schedule",
"pop_city": "Camp Springs",
"pop_state": "MD",
"pop_country": null,
"status": "Published",
"is_recompete": true,
"incumbent_name": "GDIT",
"incumbent_piid": "70SBUR21F00000019",
"poc_name": "Ricardo Rocha",
"poc_email": "[email protected]",
"poc_phone": "(240) 721-1386",
"co_name": null,
"co_email": null,
"sb_specialist_name": null,
"sb_specialist_email": null,
"sb_specialist_phone": null,
"published_date": "2026-08-03",
"last_updated_date": "2026-08-03",
"incumbent_award": {
"recipient_name": "GENERAL DYNAMICS INFORMATION TECHNOLOGY, INC.",
"current_value": 67972727.36,
"expires": "2026-03-21",
"awarding_agency": "Department of Homeland Security",
"latest_action_date": "2026-03-19"
}
}
],
"pagination": {
"limit": 1,
"offset": 0,
"total": 470,
"total_is_estimate": false,
"has_next": true
},
"filters_applied": {
"source": "dhs",
"is_recompete": true,
"active_only": true,
"sort_by": "est_award_fy"
}
}
The envelope:
| Field | Type | Meaning | Source |
|---|---|---|---|
data |
array | Forecast records, one object per planned requirement. Field by field below. | GSA FCO / DHS APFS / HHS SBCX |
pagination |
object | limit, offset, total, total_is_estimate and has_next. total is counted behind a ceiling of 10,000; above it, total reports 10,000 and total_is_estimate is true. has_next is page fullness. |
Derived |
filters_applied |
object | The filters that actually took effect, including the defaulted active_only and sort_by. A filter you sent and do not see here did not narrow anything. |
Derived |
Each object in data:
| Field | Type | Meaning | Source |
|---|---|---|---|
source |
string | Which publication the record came from: fco, dhs or hhs. With source_id, the record key. |
GSA FCO / DHS APFS / HHS SBCX |
source_id |
string | The publisher's own identifier for the forecast entry. Formats differ per feed and some carry a leading asterisk from the source. | GSA FCO / DHS APFS / HHS SBCX |
source_url |
string or null | Deep link to the entry on the publisher's site. Only the GSA feed ever provides one, and only on a handful of records. | GSA FCO / DHS APFS / HHS SBCX |
title |
string | The requirement's name as the agency published it. | GSA FCO / DHS APFS / HHS SBCX |
description |
string or null | The agency's narrative of the requirement. Length varies from one line to several pages, and often carries dated update notes, draft-RFP instructions and answered industry questions. | GSA FCO / DHS APFS / HHS SBCX |
naics |
string or null | The NAICS code, extracted by pattern from the feed's code-plus-label string (541512 Computer Systems Design Services yields 541512). Almost always 6 digits; a few GSA records publish only a sector-level code and land here as 2 digits, which no 6-digit naics= prefix query can reach. |
Derived |
psc |
string or null | Product or service code. No feed publishes one, so this is null on every record. | GSA FCO / DHS APFS / HHS SBCX |
agency |
string or null | Department or independent agency. | GSA FCO / DHS APFS / HHS SBCX |
sub_agency |
string or null | Bureau, component or operating division, in the feed's own spelling. | GSA FCO / DHS APFS / HHS SBCX |
office |
string or null | The contracting or requirements office identifier the feed publishes. Format differs per feed: a named office on DHS, a numeric office code on HHS. | GSA FCO / DHS APFS / HHS SBCX |
value_low |
number or null | Low bound of the estimated value in dollars, parsed from the published range label. | Derived |
value_high |
number or null | High bound of the estimated value in dollars, parsed from the published range label. | Derived |
value_range_text |
string or null | The published range label, verbatim. Each feed formats it differently, so parse value_low and value_high instead. |
GSA FCO / DHS APFS / HHS SBCX |
est_solicitation_date |
date or null | When the agency expects to issue the solicitation. An estimate, published by all three feeds. | GSA FCO / DHS APFS / HHS SBCX |
est_award_date |
date or null | When the agency expects to award. An estimate, published by the DHS and HHS feeds; the GSA feed publishes a fiscal year and quarter instead. | GSA FCO / DHS APFS / HHS SBCX |
est_award_fy |
integer or null | Estimated award fiscal year. Passthrough, so malformed published years appear as published. | GSA FCO / DHS APFS / HHS SBCX |
est_award_quarter |
string or null | Estimated award quarter, in the publishing feed's own spelling. Published by the GSA and DHS feeds, absent on the HHS feed. | GSA FCO / DHS APFS / HHS SBCX |
pop_start |
date or null | Estimated start of the period of performance. Published by the DHS feed only. | GSA FCO / DHS APFS / HHS SBCX |
pop_end |
date or null | Estimated end of the period of performance, including any option years the agency projects. Published by the DHS feed on nearly every record and by the GSA feed on a minority, absent on the HHS feed. | GSA FCO / DHS APFS / HHS SBCX |
set_aside |
string or null | The set-aside the agency plans, in the publishing feed's own vocabulary; the HHS value is normalised from that feed's coarse strategy token to Small Business or Full and Open. To Be Determined is a real GSA value meaning the decision is open. Full per-feed vocabulary above. |
GSA FCO / DHS APFS / HHS SBCX |
contract_type |
string or null | Planned pricing arrangement, for example Firm Fixed Price or Combination. Published by the GSA and DHS feeds, absent on the HHS feed. |
GSA FCO / DHS APFS / HHS SBCX |
extent_competed |
string or null | How the agency plans to compete it, for example Follow-on to Existing Contract. Published by the DHS feed only. |
GSA FCO / DHS APFS / HHS SBCX |
acquisition_strategy |
string or null | The planned route to market. Its meaning differs per feed: on DHS it names the vehicle (GSA Schedule, OASIS+, NASA SEWP V), on HHS it is the feed's raw strategy token, and on GSA it is the same published value that fills set_aside. |
GSA FCO / DHS APFS / HHS SBCX |
pop_city |
string or null | Place-of-performance city, published by the DHS feed. The GSA feed publishes a city only on the records it marks Cannot be disclosed, and the HHS feed publishes none. |
GSA FCO / DHS APFS / HHS SBCX |
pop_state |
string or null | Place-of-performance state, 2-letter, and the field state filters on. Published by the GSA and DHS feeds, absent on the HHS feed. Carries the literal Cannot be disclosed on a large block of GSA records and NA on some DHS records, both published values rather than nulls. |
GSA FCO / DHS APFS / HHS SBCX |
pop_country |
string or null | Place-of-performance country, published by the GSA feed only, and carrying the same Cannot be disclosed value on the same records. |
GSA FCO / DHS APFS / HHS SBCX |
status |
string or null | Lifecycle status. The GSA feed moves it through planning, solicitation, evaluation and award and leaves it null on a large share of records; the DHS and HHS feeds publish one constant publication state each. Vocabulary above. | GSA FCO / DHS APFS / HHS SBCX |
is_recompete |
boolean | true when the feed names an incumbent contract number, which is what is_recompete=true filters on. |
Derived |
incumbent_name |
string or null | The incumbent as the agency typed it: an abbreviation, a trade name, or a semicolon-joined list of holders on a multiple-award vehicle. | GSA FCO / DHS APFS / HHS SBCX |
incumbent_piid |
string or null | The incumbent contract number the agency published. The join key for incumbent_award. |
GSA FCO / DHS APFS / HHS SBCX |
poc_name |
string or null | The requirement owner the agency published for outreach. Published by all three feeds. On every plan. | GSA FCO / DHS APFS / HHS SBCX |
poc_email |
string or null | The requirement owner's published email, from all three feeds. Pro; null on other plans. |
GSA FCO / DHS APFS / HHS SBCX |
poc_phone |
string or null | The requirement owner's published phone. Published by the DHS feed only. Pro; null on other plans. |
GSA FCO / DHS APFS / HHS SBCX |
co_name |
string or null | Contracting officer, where the feed names one separately from the requirement owner. Published by the HHS feed only. | GSA FCO / DHS APFS / HHS SBCX |
co_email |
string or null | Contracting officer's published email. Published by the HHS feed only. Pro; null on other plans. |
GSA FCO / DHS APFS / HHS SBCX |
sb_specialist_name |
string or null | Small-business specialist for the office, published by the GSA and DHS feeds. | GSA FCO / DHS APFS / HHS SBCX |
sb_specialist_email |
string or null | Small-business specialist's published email, from the GSA and DHS feeds. Pro; null on other plans. |
GSA FCO / DHS APFS / HHS SBCX |
sb_specialist_phone |
string or null | Small-business specialist's published phone. Published by the DHS feed only. Pro; null on other plans. |
GSA FCO / DHS APFS / HHS SBCX |
published_date |
date or null | When the publisher first posted the entry. Stamped by the DHS feed only. | GSA FCO / DHS APFS / HHS SBCX |
last_updated_date |
date or null | When the publisher last revised the entry. Stamped by the GSA and DHS feeds, absent on the HHS feed, which publishes no update stamp. | GSA FCO / DHS APFS / HHS SBCX |
incumbent_award |
object or null | The incumbent's current federal award, resolved from incumbent_piid. Pro, and null on other plans, on non-recompetes, and where the published contract number does not resolve. Fields below. |
FPDS via USAspending |
incumbent_award:
| Field | Type | Meaning | Source |
|---|---|---|---|
recipient_name |
string or null | Registered legal name of the incumbent on the resolved award, which is often a fuller name than the forecast's incumbent_name. |
FPDS via USAspending |
current_value |
number or null | Value of the award as it stands: the obligated-through-options total on a contract, the ceiling on a vehicle. | FPDS via USAspending |
expires |
date or null | When the award ends: the current period of performance end on a contract, the ordering period end on a vehicle. A date already in the past is common and usually means a bridge or extension is carrying the work. | FPDS via USAspending |
awarding_agency |
string or null | Agency that made the award, which need not be the agency forecasting the replacement. | FPDS via USAspending |
latest_action_date |
date or null | Date of the most recent action on the award, so you can tell a live base contract from a dormant one. | FPDS via USAspending |
The record is the feed's row, kept whole. The three publications carry different fields, and rather
than narrow the shape to the intersection they all support, every field any of them publishes gets a
column and the feeds that do not publish it return null. That keeps a record comparable with its
own source and keeps fields projection stable across a mixed-source page. The one composed field is
incumbent_award, which is resolved page-wide in one bounded query and attached only where a
published contract number matches a federal award record.
Errors
| Code | Trigger |
|---|---|
400 |
source is not fco, dhs or hhs. The message lists the valid values. |
400 |
naics is not 2 to 6 digits. |
400 |
sort_by is not in the allowlist. The message lists the allowlist. |
400 |
fields names a field this resource does not return. The message lists the valid names. |
400 |
Both a canonical amount bound and its alias are sent in one request (amount_min with value_min, or amount_max with value_max). Send one form. |
400 |
amount_min or amount_max is inf or nan. A value that is not a number at all returns 422. |
400 |
The query is too broad to evaluate in time, typically a bare keyword search with nothing else narrowing it. The message names the filters to add: naics, agency, state or est_award_fy. |
402 |
limit is above your plan's page-size cap. |
The shared codes, including 401, 429 and the 400 for an unrecognised query parameter, are in
Error Codes. Burst behaviour is in Performance.
Examples
Each response below is trimmed with fields to the values its interpreting sentence reads. The full
field set is in Response above.
What is coming next in a NAICS family.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://govconapi.com/api/v1/forecasts/search?naics=5415&limit=3&fields=title,agency,est_award_fy,est_award_quarter,value_low,value_high,set_aside,status"
{
"data": [
{"source": "fco", "source_id": "36C10B26AP0099", "title": "Benefits Enterprise Services - New Task Order",
"agency": "Department of Veterans Affairs", "est_award_fy": 2026, "est_award_quarter": "1st (October 1 - December 31)",
"value_low": 2000000000.0, "value_high": 2900000000.0, "set_aside": "To Be Determined", "status": "Solicitation Issued"},
{"source": "fco", "source_id": "FHWA_2026_042", "title": "Software Engineering Services (SWES) 2.0",
"agency": "Department of Transportation", "est_award_fy": 2026, "est_award_quarter": "1st (October 1 - December 31)",
"value_low": 1000000000.0, "value_high": 1900000000.0, "set_aside": "To Be Determined", "status": "Acquisition Planning"},
{"source": "fco", "source_id": "36C10A25AP0160", "title": "Infrastructure Operations Franchise Fund Support Services",
"agency": "Department of Veterans Affairs", "est_award_fy": 2026, "est_award_quarter": "3rd (April 1 - June 30)",
"value_low": 500000000.0, "value_high": 999000000.0, "set_aside": "To Be Determined", "status": "Acquisition Planning"}
],
"pagination": {"limit": 3, "offset": 0, "total": 1653, "total_is_estimate": false, "has_next": true},
"filters_applied": {"naics": "5415", "active_only": true, "sort_by": "est_award_fy"}
}
The default order is soonest fiscal year first and largest range first within it, so the top of the
page is the biggest near-term professional-services requirement in scope: a $2.0B to $2.9B VA benefits
task order already at Solicitation Issued, ahead of a $1.0B to $1.9B DOT requirement still in
Acquisition Planning. Reading status alongside the value is how you separate a plan you can still
influence from one that has already gone to market. set_aside reads To Be Determined on all three,
which is a published GSA value meaning the decision is open, not a gap in the data.
The displacement view: recompetes with the contract they replace.
curl -H "Authorization: Bearer YOUR_PRO_KEY" \
"https://govconapi.com/api/v1/forecasts/search?is_recompete=true&agency=Homeland&amount_min=50000000&limit=2&fields=title,est_award_fy,value_low,value_high,incumbent_name,incumbent_piid,incumbent_award"
{
"data": [
{"source": "dhs", "source_id": "*F2025068551", "title": "Enterprise Automation and Unified Task Orchestration (eAUTO)",
"est_award_fy": 2026, "value_low": 50000000.0, "value_high": 100000000.0,
"incumbent_name": "GDIT", "incumbent_piid": "70SBUR21F00000019",
"incumbent_award": {"recipient_name": "GENERAL DYNAMICS INFORMATION TECHNOLOGY, INC.", "current_value": 67972727.36,
"expires": "2026-03-21", "awarding_agency": "Department of Homeland Security", "latest_action_date": "2026-03-19"}},
{"source": "dhs", "source_id": "*F2025068553", "title": "Secure Identification Platform (SIP) Consumable cards and program management.",
"est_award_fy": 2026, "value_low": 50000000.0, "value_high": 100000000.0,
"incumbent_name": "HID Global", "incumbent_piid": "70SBUR21D00000002",
"incumbent_award": {"recipient_name": "HID GLOBAL CORP", "current_value": 88260000.0,
"expires": "2026-03-31", "awarding_agency": "Department of Homeland Security", "latest_action_date": "2026-02-12"}}
],
"pagination": {"limit": 2, "offset": 0, "total": 74, "total_is_estimate": false, "has_next": true},
"filters_applied": {"agency": "Homeland", "amount_min": 50000000.0, "is_recompete": true, "active_only": true, "sort_by": "est_award_fy"}
}
Both rows are complete displacement targets: an FY2026 DHS forecast ranged $50M to $100M, with
incumbent_award naming the contract it replaces. GDIT holds $67,972,727.36 and HID Global
$88,260,000.00, both inside their forecast's published range, so the agency is projecting a follow-on
of roughly the size of the contract it replaces rather than a larger or smaller one. The range itself
is partly the query's own doing: amount_min=50000000 requires value_high at or above $50M, which
concentrates the page on the $50M to $100M band. Both expires dates, 2026-03-21 and 2026-03-31, have
already passed while the forecast is still live and the replacement unawarded, the usual sign that a
bridge or extension is carrying the work; latest_action_date within days of each expires confirms
these resolved to the active award rather than a dormant one. Note incumbent_name is the agency's
shorthand and recipient_name is the registered legal name; match on incumbent_piid, never on the
name string.
Scoping to one feed so a set-aside filter reads cleanly.
curl -H "Authorization: Bearer YOUR_PRO_KEY" \
"https://govconapi.com/api/v1/forecasts/search?source=dhs&set_aside=8(a)&limit=2&fields=title,agency,naics,set_aside,value_range_text,est_award_quarter,poc_name,poc_email"
{
"data": [
{"source": "dhs", "source_id": "*F2025069802", "title": "Grant Programmatic, Administration, and Technical Support (GPATS) for FEMA's Grant Programs Directorate (GPD)",
"agency": "Department of Homeland Security", "naics": "541611", "set_aside": "8(a)", "value_range_text": "$50M to $100M",
"est_award_quarter": "Q4 2026", "poc_name": "Christopher Engstrom", "poc_email": "[email protected]"},
{"source": "dhs", "source_id": "F2025071996", "title": "TCA Tactical Infrastructure Maintenance",
"agency": "Department of Homeland Security", "naics": "237990", "set_aside": "8(a)", "value_range_text": "$50M to $100M",
"est_award_quarter": "Q4 2026", "poc_name": "David Smith", "poc_email": "[email protected]"}
],
"pagination": {"limit": 2, "offset": 0, "total": 143, "total_is_estimate": false, "has_next": true},
"filters_applied": {"source": "dhs", "set_aside": "8(a)", "active_only": true, "sort_by": "est_award_fy"}
}
Scoping to one feed before filtering set_aside is what makes the column readable: every row comes
back tagged exactly 8(a) in the DHS short-code vocabulary, and est_award_quarter reads Q4 2026
in the DHS quarter-plus-year spelling rather than the GSA feed's ordinal. Drop source and the same
filter also reaches the GSA records tagged 8(a) Competitive and 8(a) Sole Source, which is usually
what you want for market sizing but means the field's text differs row to row. 8(a) is safe to send
unscoped because no other value in any of the three vocabularies contains it; SB and
Small Business are not. poc_email is populated here because the key is Pro; on other plans the
name stays and the email reads null.
The same data as competitive history: what an agency planned, and what it awarded.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://govconapi.com/api/v1/forecasts/search?active_only=false&source=fco&status=Awarded&limit=2&fields=title,agency,est_award_fy,status,value_low,value_high,incumbent_name,last_updated_date"
{
"data": [
{"source": "fco", "source_id": "USGS0070330044", "title": "Roof replacement of the IDWSC Newell Building",
"agency": "Department of the Interior", "est_award_fy": 2025, "status": "Awarded",
"value_low": 250000.0, "value_high": 499000.0, "incumbent_name": "BURTON CONSTRUCTION, INC.", "last_updated_date": "2026-03-12"},
{"source": "fco", "source_id": "FY26_004431", "title": "FY26 Landmark Call Order",
"agency": "Department of Agriculture", "est_award_fy": 2026, "status": "Awarded",
"value_low": 100000000.0, "value_high": 249000000.0, "incumbent_name": "PALANTIR TECHNOLOGIES INC.", "last_updated_date": "2026-04-22"}
],
"pagination": {"limit": 2, "offset": 0, "total": 191, "total_is_estimate": false, "has_next": true},
"filters_applied": {"source": "fco", "status": "Awarded", "sort_by": "est_award_fy"}
}
Turning active_only off and narrowing to the GSA feed's Awarded status converts the endpoint into
competitive history: these are plans that landed, with the winner named, from a $250K to $499K Interior
roof replacement to a $100M to $249M Agriculture call order that went to Palantir. Confirm the switch
took effect by reading filters_applied, which no longer carries active_only: a filter you sent and
cannot see there did not narrow the result. Awarded exists only in the GSA vocabulary, so source=fco
here is documentation rather than narrowing, and you should pair this with the contracts resource when
you need the awarded value rather than the planned range.
Related
- Data status for this dataset's current record count, refresh cadence and as-of date. Go there instead of hard-coding a size, because the feeds are re-read daily.
- Search opportunities when the requirement has moved from plan to posted solicitation. A forecast's
est_solicitation_dateis the cue to start watching SAM.gov for it. - Search contracts for the awarded value behind an
incumbent_awardblock, its modification history and its subawards. This is the resourceincumbent_awardis resolved from, so go there when the single summary block is not enough. - Search contract vehicles when a recompete's incumbent holds an IDIQ, GWAC or BPA rather than a standalone contract, which is where
incumbent_awardreads a ceiling and an ordering-period end. - Recompete Watchlist for the other direction on displacement: it starts from expiring contracts in a market rather than from an agency's published plan.
- Response Shaping for
fieldssyntax, Plans and Limits for page-size and rate caps, Error Codes for the shared status codes.