Government Tender Awards: Winners, Values & Bids
Pricing
Pay per usage
Government Tender Awards: Winners, Values & Bids
Government contracts already awarded, not open opportunities: who won, for how much, and how many bidders they beat, from the US, UK and EU registers in one schema. Flags contracts labelled openly competed that drew a single bid, ranks repeat winners per buyer, never fills a blank with zero.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Ai-Q Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Every other government tender Actor gives you the contracts you can still bid on. That is the easy half, and it is the half that tells you nothing about whether bidding is worth your time.
This one reads the other end of the process: contracts that have already been awarded. Who won, how much they were paid, how many bidders they beat, and which buyers keep going back to the same supplier — from the US, UK and EU registers, in one schema.
Four of the tender Actors currently on the store were read line by line before this was
built. All four list open opportunities; none of them returns an award result. One even
ships an awardedTo field with nothing in it.
The finding this was built around
A US contract can be labelled FULL AND OPEN COMPETITION and receive exactly one offer. The label describes the procedure. The offer count describes what happened. When they disagree, that is the most useful line in the dataset: a market where the paperwork says anyone could bid and, in practice, nobody else did.
Measured on 12 US software contracts while this was written — three of them:
| Winner | Label on the contract | Offers received |
|---|---|---|
| CARAHSOFT TECHNOLOGY CORP | FULL AND OPEN COMPETITION | 1 |
| V3GATE, LLC | FULL AND OPEN COMPETITION AFTER EXCLUSION OF SOURCES | 1 |
| THUNDERCAT TECHNOLOGY, LLC | FULL AND OPEN COMPETITION AFTER EXCLUSION OF SOURCES | 1 |
Those rows carry uncontestedOpenAward: true and are collected in the
UNCONTESTED_AWARDS record. A contract that was openly advertised and drew one bid is
either a market nobody knows about or one nobody thinks they can win. Both are worth
knowing before you write a proposal.
A sole-source award that received one bid is not flagged. Its label never claimed
competition, so there is no contradiction — it is reported as single_bid_received
instead. The two are kept apart on purpose.
What it will not do
It never fills a blank with a zero. Award registers are full of holes. A UK buyer
often publishes the winner and withholds the price; a US contracting officer often
leaves the offer count empty. Writing those as 0 would turn we do not know into
nobody bid, and the price is secret into the contract was free.
So every uncertain number ships with the boolean that says whether it was published:
| Field | Companion |
|---|---|
awardAmount | amountDisclosed |
bidsReceived | bidsDisclosed |
singleBidder | null when the count is unknown — never false |
The disclosure rates are an output in their own right. Over one live run of 177 awards: the value was published on 47 and the bid count on 7. That is not a defect in the data collection; it is what the registers publish, and a tool that hid it would be lying by omission.
It never adds currencies together. GBP, EUR, USD, CZK and PLN awards all appear in the same run. Totals are kept as a map per currency, because converting them would need an exchange rate this Actor has no business inventing.
It never credits a shared contract twice. When three firms win a contract jointly, each is credited with a third of the value in the supplier ranking, not the whole amount.
What comes out
One row per award, plus four aggregate records.
Dataset row
| Field | Meaning |
|---|---|
source, country, sourceUrl | Which register, and a link straight to the original notice |
buyer, buyerUnit | The contracting organisation |
suppliers, supplierCount, supplierCountries | Who won, including joint winners |
awardAmount, currency, amountDisclosed, amountBasis | What it was worth, in the register's own currency, and what the number actually measures |
bidsReceived, bidsDisclosed, singleBidder | How many bids came in |
competitionLabel, uncontestedOpenAward | The procedure claimed, and whether it matches the bid count |
lowestBidAmount, highestBidAmount | The bid range, where the register publishes it |
awardDate, contractStart, contractEnd | Dates, normalised to yyyy-mm-dd across three different formats |
awardsOnThisNotice | How many awards the parent notice holds — a framework can hold over a hundred |
classification | NAICS/PSC for the US, CPV for the EU |
issues | Machine-readable flags: open_competition_with_one_bid, award_value_not_published, … |
Key-value records
| Record | What it answers |
|---|---|
TOP_SUPPLIERS | Who keeps winning, across how many buyers, for how much per currency |
BUYER_PROFILES | Per buyer: repeatWinnerShare — how often its awards go to its single most frequent supplier — plus its disclosure rates |
UNCONTESTED_AWARDS | The openly-competed contracts that drew one bid, biggest first |
SUMMARY | Counts, disclosure rates, the exact query sent to each register, and every caveat that applied to this run |
The three registers
| Winner | Value | Bid count | Keyword filter | |
|---|---|---|---|---|
| US — USAspending.gov | always | always | in about half the awards | server-side |
| UK — Find a Tender | almost always | sometimes | rarely | applied here, after fetching |
| EU — TED | always | always | never published | server-side, full text |
All three are official public APIs and none of them needs a key. Nothing here is scraped: no HTML is parsed, no login is used, no page is crawled.
Three differences worth knowing before you read the numbers:
- US amounts are obligated dollars, not a bid price, and every US row says so in
amountBasis. Bid counts live in a separate detail endpoint, which costs one extra request per award — that is whatincludeUsCompetitionDetailcontrols. - UK dates are notice-publication dates, not award dates; where the award itself
carries a date it is used, and
ukAwardDatePublishedsays which one you got. - EU rows are one per notice, not one per award. TED returns lot results as
parallel arrays with no reliable pairing between a winner and a lot, so a multi-lot
notice lists every winner and states in
amountBasisthat the amount covers all of them. Splitting it would mean inventing a breakdown the publisher did not give.
Three things real data changed
Unit tests pin the shapes. These only appeared once the code met the registers.
1. The obvious UK filter hides every award that has a price. Find a Tender accepts
stages=award, which looks like the correct way to ask for results. Measured over one
window it returned 486 awards — all under the old EU directive, none with a
published value. The unfiltered feed over the same window returned 435 awards of which
118 had values and 5 releases carried bid lists, because notices published under the UK
Procurement Act 2023 are missing from that filter entirely. Using it would have made
this Actor report that the UK never discloses what it paid. The filter is applied here
instead, on the release tag.
2. One framework notice can swallow the whole run. UK notice 071472-2026 holds
127 lot awards on its own — enough to fill the record budget on the first page and hide
the other 1,283 awards in the window. maxAwardsPerNotice bounds any single
procurement, whatever was left out is counted in SUMMARY, and every row carries
awardsOnThisNotice so the real size stays visible.
3. The same award is republished every time its notice is updated. In one 400-row sample, 32 rows were repeats of an award already collected — enough to inflate every supplier's win count. Awards are now deduplicated per procurement, keeping the most recent copy.
Limits
- Contracts only. Grants and loans are out of scope: they have no bidders.
- No bid counts for the EU. TED's search API exposes 1,830 fields and the received
submissions count is not one of them.
bidsReceivedisnullfor every EU row rather than guessed from the tender value range. - The UK has no keyword parameter, and its feed is rate limited. Keywords are matched here against title, description, buyer and winner, so a UK run reads the whole window looking for them — one test run scanned 3,400 releases to find 3 awards mentioning "cybersecurity". Find a Tender allows 12 requests per 90-second window per IP, and an Actor shares its egress with other tenants, so pages are spaced 8 seconds apart and reading stops after 40 pages with the truncation reported. Narrow the date range rather than relying on the keyword when you want UK coverage.
- A refused page never discards the pages before it. If a register starts refusing
mid-run, what was already collected is kept, the reason is written into
SUMMARY, and the run is marked truncated. repeatWinnerShareis a share, not a verdict. A buyer with three awards and one supplier scores 1.0 on very little evidence. Read it next toawards.- Disclosure rates describe the awards this run collected, not the register as a whole.
Example input
{"sources": ["us", "uk", "eu"],"keywords": ["cybersecurity"],"awardedFrom": "2026-06-01","awardedTo": "2026-07-31","maxRecordsPerSource": 200,"includeUsCompetitionDetail": true}
To go straight to the contradictions, set onlyUncontested to true. The rankings in
the key-value records are still built from every award found, not only the flagged ones.