How to find public contracts that end soon: re-tender data from TED and Find a Tender
No procurement portal publishes a list of contracts that are about to expire; the end date has to be derived from the award notice (start plus duration, or a stated end date) and each derivation can be wrong in a known way. Source: Arcadium Data, data as of .
Suppliers want the contract that was awarded two years ago, because the buyer must tender it again. The buyer wants the same: a pipeline of upcoming procurements. Everything needed is public, but it is scattered across award notices, and the one date you need is often missing. Competitors and incumbents already watch this: it is the basis of "re-tender radar" products from bid-intelligence firms.
This guide builds the list from the source notices, explains where the estimate fails, and then shows the API that does it for TED and Find a Tender.
The official route: derive it from award notices
Where the dates live
An award notice (TED: can-standard and relatives; UK: contract details UK7 and the OCDS contracts[] block) states some of these, per lot:
- Start date (eForms BT-536, TED field
contract-duration-start-date-lot) and end date (BT-537,contract-duration-end-date-lot). - Duration as a value and a unit (BT-36:
duration-period-value-lot,duration-period-unit-lot) or as "unlimited" / "unknown" (BT-538). - Conclusion date of the contract (BT-145,
contract-conclusion-date). - Renewals allowed (BT-57,
renewal-maximum-lot) and whether the contract is a framework agreement (BT-765,framework-agreement-lot) with its ceiling value (BT-709).
Use them in this order: a stated end date; else start plus duration; else conclusion date plus duration; and only for award notices, as a last resort, the publication day plus duration. Write down which one you used.
curl
# TED: result notices of one day with the period fields (anonymous, no key)
curl -s https://api.ted.europa.eu/v3/notices/search \
-H 'Content-Type: application/json' \
-d '{"query":"publication-date=20261023 AND notice-type IN (can-standard can-social can-desg can-tran veat can-modif compl)","fields":["publication-number","notice-type","buyer-name","winner-name","contract-duration-start-date-lot","contract-duration-end-date-lot","duration-period-value-lot","duration-period-unit-lot","contract-conclusion-date","renewal-maximum-lot","framework-agreement-lot"],"limit":250,"page":1,"paginationMode":"PAGE_NUMBER"}'
Python
from datetime import date
from dateutil.relativedelta import relativedelta # pip install python-dateutil
def contract_end(n: dict):
"""n: a normalised notice with start, end, concluded (date or None), duration_months (int or None).
Returns (end_date, basis) or (None, None)."""
if n.get("end"):
return n["end"], "end_date"
if n.get("duration_months"):
if n.get("start"):
return n["start"] + relativedelta(months=n["duration_months"]), "start_plus_duration"
if n.get("concluded"):
return n["concluded"] + relativedelta(months=n["duration_months"]), "concluded_plus_duration"
return None, None
def retender_window(end: date, framework: bool, months: int):
"""Typical lead time: a buyer starts the follow-up 9 months before the end, 12 for frameworks and 3+ year contracts."""
lead = 12 if framework or months >= 36 else 9
return end - relativedelta(months=lead), end - relativedelta(months=2)
TypeScript
export type Period = { start?: Date; end?: Date; concluded?: Date; durationMonths?: number };
const addMonths = (d: Date, m: number): Date => {
const r = new Date(d);
r.setUTCMonth(r.getUTCMonth() + m);
return r;
};
export function contractEnd(p: Period): { end: Date; basis: string } | null {
if (p.end) return { end: p.end, basis: 'end_date' };
if (!p.durationMonths) return null;
if (p.start) return { end: addMonths(p.start, p.durationMonths), basis: 'start_plus_duration' };
if (p.concluded) return { end: addMonths(p.concluded, p.durationMonths), basis: 'concluded_plus_duration' };
return null;
}
Where UK data helps
Under the Procurement Act 2023, buyers publish more than award notices. A pipeline notice (UK1) and a planned procurement notice (UK3) list contracts the buyer will tender, months before the call. Contract details (UK7) state the contract period. A contract change (UK10) can move the end date; a contract termination (UK11) ends one early. The notice types guide explains all seventeen codes, and the Find a Tender API guide shows how to read them.
From a list to leads
A raw expiry list is long and mostly irrelevant. Narrow it in this order: country and CPV division you can serve, then a value band that fits your delivery size, then contracts whose end date came from a stated end date rather than an estimate, then the buyers you have won from or lost to before. For each remaining row note the current holder (your competitor or a prospect), the framework flag, the renewals allowed and the expected window, and set a reminder at the start of the window to look for the follow-up call. The call itself appears as a new competition notice, often with a new title, so match by buyer and CPV rather than by the old name.
Why the estimate can be wrong
- Frameworks state a ceiling, not spend, and call-offs under them run on their own dates. A framework is re-tendered by the buyer before it ends, so use a longer lead time.
- Renewals and options. A "2 years plus 2 times 12 months" contract may live four years. If
renewal-maximum-lotis above zero, the earliest end is a floor. - Several lots. Lot arrays in TED are not aligned with each other. Take the earliest start, the latest end and the longest duration over the lots, and accept some error.
- Missing or silly values. Durations of 0 or 99 years appear; cap them (we treat more than 20 years as a typo) and flag the row.
- Early termination, extensions, direct awards. A buyer may extend instead of re-tendering. A notice of change after the award is the only signal.
- Currency and value. Values come per notice, per lot or per tender in different currencies. Convert once and say how.
The window you compute is a model of how buyers behave, not a promise. Sell it to yourself as "worth a look", not "will be tendered on date X".
The fast route: GET /v1/tenders/expiring
The Re-tender Radar route returns award notices from TED and UK Find a Tender whose contract ends in a window (default today to 18 months on, at most 36 months), soonest first, one row per procedure and winner set. Each row has the buyer, CPV, the current holders (with their website when the notice states one), a value band (frameworks flagged), how the end date was derived (endBasis) and the expected window of the follow-up call: 9 months (12 for frameworks and contracts of three years or more) to 2 months before the end.
Calls on this page work without a key from one IP (10 requests a minute, 100 a day, short answers, point lookups). A free key lifts the limits: sign up. Routes, parameters and fields: OpenAPI.
curl
curl -s "https://api.arcadiumdata.io/v1/tenders/expiring?cpv=72&limit=1"
Response (abridged)
{
"from": "2026-10-25",
"to": "2028-04-25",
"count": 1,
"data": [{
"id": "ted:216234-2026",
"buyer": { "name": "Consejería de Digitalización", "country": "ES" },
"cpvDivisionLabel": "IT services: consulting, software development, Internet and support",
"holders": [{ "name": "INDRA SOLUCIONES TECNOLOGÍAS DE LA INFORMACIÓN, S.L.U.", "domain": null }],
"value": { "eur": 954059.2, "basis": "award", "band": "100k_1m" },
"isFramework": false,
"awardedOn": "2026-03-30",
"endOn": "2026-10-25",
"endBasis": "concluded_plus_duration",
"durationMonths": 7,
"expectedRetender": { "from": "2026-01-25", "to": "2026-08-25" },
"url": "https://ted.europa.eu/en/notice/-/detail/216234-2026"
}]
}
This row shows the limits honestly: the end date comes from the conclusion date plus a seven-month duration, and the expected window already lies in the past, so the follow-up call is probably out or about to be. Use endBasis to rank rows (end_date is the most reliable) and from to look further ahead.
Filters: country, cpv (2 to 8 digits), from and to, minValueEur, frameworksOnly, and kind for the UK Procurement Act views (pipeline, terminated, changed). Anonymous calls need country or cpv (one value) and return at most five rows; a free key lifts that and adds paging.
curl
# Keyed: framework agreements ending in 2027, IT services, worth at least EUR 1 million
curl -s "https://api.arcadiumdata.io/v1/tenders/expiring?cpv=72&from=2027-01-01&to=2027-12-31&frameworksOnly=true&minValueEur=1000000&limit=50" \
-H "Authorization: Bearer $ARCADIUM_API_KEY"
Python
import os
import requests
url = "https://api.arcadiumdata.io/v1/tenders/expiring?country=DE&cpv=72&limit=50"
headers = {"Authorization": "Bearer " + os.environ["ARCADIUM_API_KEY"]}
page = requests.get(url, headers=headers, timeout=60).json()
for row in page["data"]:
names = ", ".join(h["name"] for h in row["holders"])
print(row["endOn"], row["endBasis"], row["buyer"]["name"], "<-", names)
TypeScript
type Row = { endOn: string; endBasis: string | null; buyer: { name: string | null }; holders: { name: string }[]; url: string };
const res = await fetch('https://api.arcadiumdata.io/v1/tenders/expiring?country=GB&kind=terminated&limit=5');
const body = (await res.json()) as { data: Row[] };
for (const r of body.data) console.log(r.endOn, r.buyer.name, r.url);
Three ways to use it: a bidder filters a CPV division and a value band and gets a weekly shortlist (the saved search POST /v1/watch/tenders emails it); a sales team takes the current holders as a competitor list; an analyst compares expiry waves by country. The Re-tender Radar page shows the product; the tenders demo runs without sign-up.
Comparison
| Build it from notices | Arcadium Data /v1/tenders/expiring | |
|---|---|---|
| Sources | TED API, Find a Tender, national portals, one by one | TED and UK Find a Tender in one schema |
| End date | You derive it and track the basis | endOn plus endBasis |
| Re-tender window | Your own rule | Stated rule: 9 to 2 months before the end (12 for frameworks and 3+ years) |
| Current holders and websites | Join winner names to companies yourself | Holders with website domain when the notice states one |
| Frameworks | Detect with BT-765 | isFramework, value basis framework_ceiling |
| UK planned and terminated contracts | Read UK1, UK3, UK10, UK11 | kind=pipeline|terminated|changed |
| Alerts | Build a scheduler | POST /v1/watch/tenders weekly email |
| Weak spots | Missing durations, renewals | Same data limits; shown in endBasis and renewalsMax |
Get the data without the plumbing
Arcadium Data serves these datasets from one REST API and one MCP server, with sources, licences and dates on every answer. No key is needed to try the routes in this guide.
Related
- Re-tender Radar
- UK procurement notice types UK1-UK17
- UK Find a Tender API
- TED API guide
- CPV codes explained
- Tenders demo
Sources
Last updated 2026-10-25. This guide is ours and independent of the organisations it describes. Found a mistake? Tell us and we correct it.
Questions
Is there an official list of public contracts that are about to expire?
No. Neither TED nor Find a Tender publishes one. You derive the end date from the award notice: a stated end date, or the start (or conclusion) date plus the duration.
How early does a buyer start the follow-up procurement?
It varies. Our API assumes a window from 9 months before the end to 2 months before (12 months for framework agreements and contracts of three years or more). Treat it as a model, not as a promise.
Which UK notices signal an upcoming re-tender?
UK1 (pipeline) and UK3 (planned procurement) list contracts a buyer will tender. UK7 states the contract period, UK10 can move the end date and UK11 ends a contract early.
Why does an expiring row show an expected re-tender window in the past?
The window is computed backwards from the end date. For short contracts or notices published late, the window has already passed, which usually means the follow-up call is out or imminent.
Can I get this without an API key?
Yes, in small doses: GET /v1/tenders/expiring with country or cpv returns up to five rows anonymously. A free key adds paging, all filters and full lists.
Cite as: Arcadium Data, "How to find public contracts that end soon: re-tender data from TED and Find a Tender", https://arcadiumdata.io/guides/contracts-ending-soon-re-tender-data/, data as of 2026-10-25.