Skip to content

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 state filter returns no HHS records at all. state matches pop_state exactly and case-insensitively, not pop_city. A large block of GSA records publishes the literal string Cannot be disclosed in pop_state, pop_city and pop_country together, which is the agency's published value rather than a null, so state=VA and every other two-letter query silently drops all of them. Read that block with state=Cannot be disclosed, and treat any state-scoped market size as a floor. Some DHS records publish NA in pop_state for the same reason.
  • Lifecycle status. Only the GSA feed moves status through a lifecycle: Acquisition Planning, Market Research, Drafting Solicitation, Solicitation Issued, Evaluation Stage, Exercise of Option, Awarded and Cancelled. The DHS feed publishes Published on every row and the HHS feed publishes PUBLISHED on every row, and those are the only values either carries. The filter is one case-insensitive substring match over all three, so status=Acquisition Planning returns GSA records and nothing else, while status=Published returns the whole DHS and HHS feeds and no GSA record at all. A lifecycle-status filter is a GSA filter; pass source=fco alongside it so that is explicit rather than accidental.
  • Estimated quarter. The three feeds spell it three ways, and est_award_quarter is a case-insensitive substring match against the whole published string. Filter with the token that belongs to the feed you are reading:

    • fco writes an ordinal with the calendar span. The full vocabulary is 1st (October 1 - December 31), 2nd (January 1 - March 31), 3rd (April 1 - June 30), 4th (July 1 - September 30) and To Be Determined. Filter on the ordinal: est_award_quarter=4th.
    • dhs writes the quarter joined to the fiscal year, spelled Q4 2026, Q1 2027 and so on, and never leaves it empty. Filter on Q4 for every fourth-quarter row in the feed, or on Q4 2026 for one quarter of one year.
    • hhs publishes no quarter at all, so any est_award_quarter value 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=0 returns the entire DHS feed, because every value carries a 20xx year; source=fco&est_award_quarter=1 returns more than half the GSA feed, because October 1, January 1, April 1, July 1, December 31 and March 31 all contain a 1; and source=fco&est_award_quarter=1st returns the first-quarter rows and nothing else.

  • Set-aside. Three vocabularies, matched by one case-insensitive substring filter.

    • fco publishes 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) and 8(a) with HUB Zone Preference. The most common of these is To Be Determined, a published GSA value meaning the decision is open.
    • dhs publishes a short code on a little over half its records: SB, 8(a), HUBZone, WOSB, SDVOSB and AbilityOne.
    • hhs publishes a coarse two-value flag on a minority of records, Small Business or Full 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=SB scoped to dhs returns the WOSB and SDVOSB rows too, because SB is a substring of both. set_aside=Small Business scoped to fco returns the Other Than Small Business rows, which carry the opposite meaning. Anchor on the longest fragment that appears only inside its own program family: 8(a), HUBZone, WOSB and Sole Source each reach every variant of their family and nothing outside it, so WOSB also returns the EDWOSB row and 8(a) also returns the competitive and sole-source variants. Pass source whenever you need the vocabulary itself to be uniform.

  • Product or service code. No feed publishes one. psc is 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.

  • 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_date is the cue to start watching SAM.gov for it.
  • Search contracts for the awarded value behind an incumbent_award block, its modification history and its subawards. This is the resource incumbent_award is 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_award reads 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 fields syntax, Plans and Limits for page-size and rate caps, Error Codes for the shared status codes.

A REST API and MCP server for U.S. federal procurement data.

Get a free key, emailed instantly, or follow the quickstart.

Found something wrong, missing or confusing on this page?

Press Ctrl + Enter to send a note. Highlight text first and it travels with your note.