European Union API: Search EU public procurement notices
Finds recently published EU procurement notices matching what is being bought, with buyer, estimated value, submission deadline and TED notice link. Open-only results must have a future submission deadline.
Unofficial. Not affiliated with or endorsed by European Union.
Inputs
Values from the run on Oct 27, 2026, shown under Output.
- What, required
what What is being bought, such as cloud hosting or school buses.
cloud hosting
2 characters or more.
- Country optional
country Buyer country by name or two-letter code, such as Germany or DE.
Not set
- Open Only optional
open_only Only notices whose submission deadline is still ahead; defaults to true.
true (default)
True or false.
- Max Results optional
max_results Maximum number of results, from 1 to 100; defaults to 25.
25 (default)
Whole number from 1 to 100.
- Published Since optional
published_since Earliest publication date, YYYY-MM-DD; defaults to 30 days ago.
Not set
- Minimum Value (EUR) optional
minimum_value_eur Minimum estimated value in euros; published non-euro values are converted at current ECB reference rates.
Not set
Number 0 or more.
Input as JSON
{ "what": "cloud hosting"}Output
{ "tenders": [ { "title": "Webbyrå", "currency": "SEK", "cpv_codes": [ "72413000", "72415000" ], "buyer_name": "Högskoleservice i Jönköping AB", "notice_link": "https://ted.europa.eu/en/notice/-/detail/737548-2026" , "buyer_country": "Sweden", "procedure_type": "Open procedure", "estimated_value": 7000000, "publication_date": "2026-10-26", "submission_deadline": "2026-11-12T23:00:00+00:00", "category_description": "World wide web (www) site design services", "notice_publication_number": "737548-2026" }, { "title": "Energy Management Information System", "currency": "EUR", "cpv_codes": [ "71314200" ], "buyer_name": "[\"Iarnród Eireann-Irish Rail\"]", "notice_link": "https://ted.europa.eu/en/notice/-/detail/736760-2026" , "buyer_country": "Ireland", "procedure_type": "Negotiated procedure with prior call for competition", "estimated_value": 770000, "publication_date": "2026-10-23", "submission_deadline": "2026-11-02T12:00:00+01:00", "category_description": "Energy-management services", "notice_publication_number": "736760-2026" }, { "title": "Elhub.no - Operation and development", "currency": "NOK", "cpv_codes": [ "72222300", "72415000" ], "buyer_name": "[\"Elhub AS\"]", "notice_link": "https://ted.europa.eu/en/notice/-/detail/733190-2026" , "buyer_country": "Norway", "procedure_type": "Negotiated procedure with prior call for competition", "estimated_value": 7260000, "publication_date": "2026-10-22", "submission_deadline": "2026-11-13T10:00:00+00:00", "category_description": "Information technology services", "notice_publication_number": "733190-2026" } ]}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"ted.europa.eu/search_tenders","input":{"what":"cloud hosting"}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "ted.europa.eu/search_tenders" , "input": { "what": "cloud hosting" }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "ted.europa.eu/search_tenders" , "input": { "what": "cloud hosting" } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run ted.europa.eu/search_tenders# with {"what":"cloud hosting"}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "what" ], "properties": { "what": { "type": "string", "examples": [ "cloud hosting" ], "minLength": 2, "description": "What is being bought, such as cloud hosting or school buses." }, "country": { "type": "string", "examples": [ "Germany" ], "description": "Buyer country by name or two-letter code, such as Germany or DE." }, "open_only": { "type": "boolean", "default": true, "description": "Only notices whose submission deadline is still ahead; defaults to true." }, "max_results": { "type": "integer", "default": 25, "maximum": 100, "minimum": 1, "description": "Maximum number of results, from 1 to 100; defaults to 25." }, "published_since": { "type": "string", "description": "Earliest publication date, YYYY-MM-DD; defaults to 30 days ago." }, "minimum_value_eur": { "type": "number", "minimum": 0, "examples": [ 100000 ], "description": "Minimum estimated value in euros; published non-euro values are converted at current ECB reference rates." } }}Output schema
{ "type": "object", "required": [ "tenders" ], "properties": { "tenders": { "type": "array", "items": { "type": "object", "required": [ "title", "buyer_name", "buyer_country", "estimated_value", "currency", "submission_deadline", "procedure_type", "category_description", "publication_date", "notice_link", "notice_publication_number", "cpv_codes" ], "properties": { "title": { "type": [ "string", "null" ] }, "currency": { "type": [ "string", "null" ] }, "cpv_codes": { "type": "array", "items": { "type": "string" } }, "buyer_name": { "type": [ "string", "null" ] }, "notice_link": { "type": [ "string", "null" ] }, "buyer_country": { "type": [ "string", "null" ] }, "procedure_type": { "type": [ "string", "null" ] }, "estimated_value": { "type": [ "number", "null" ] }, "publication_date": { "type": [ "string", "null" ] }, "submission_deadline": { "type": [ "string", "null" ], "description": "ISO 8601 date-time with time zone offset." }, "category_description": { "type": [ "string", "null" ] }, "notice_publication_number": { "type": [ "string", "null" ] } }, "additionalProperties": false } } }, "additionalProperties": false}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
ted.europa.eu/search_tenders- Returns
- title, buyer, country, estimated value, currency, submission deadline, procedure type, CPV codes, TED notice link
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method ted.europa.eu/search_tenders with the inputs above.
Ask your agent
- Find open EU tenders for office cleaning services from buyers in France published in the last two weeks
- I need recent public procurement notices for school buses over 500000 euros with deadlines still ahead
- Show me EU calls for tender on cloud hosting from Italian public bodies, only open ones
- Are there any currently open Spanish government notices for road maintenance contracts worth at least 250000 euros?
- List EU procurement opportunities for medical imaging equipment published since 2024-09-01 with submission deadlines still in the future, max 40 results
See more
All European Union methodsFinds published EU contract award notices on Tenders Electronic Daily by contract topic or winning company, newest publication first, optionally limited to a buyer country and a start date. Values and tender counts are included when published; counts across lots are summed.
ted.europa.eu/search_contract_awardsSearches EUR-Lex legal acts by topic, ranked by the site's relevance, filtered by document type, year of adoption and in-force status. Short names and ELI links are included when shown in the results.
eur-lex.europa.eu/search_eu_lawGets the official text and key dates of one article of an EU regulation or directive from EUR-Lex, in the latest consolidated version when there is one, in any official EU language.
eur-lex.europa.eu/get_law_articleLooks up an official Eurostat statistic for an EU or EEA country and the EU27 figure for the same period. Quarterly and half-yearly series return the reporting period that contains a requested month.
ec.europa.eu/get_statisticReturns the ECB's current deposit facility, main refinancing operations and marginal lending facility rates with their effective date. Optionally includes earlier rate changes, newest first.
ecb.europa.eu/get_key_interest_ratesConverts an amount between currencies using ECB euro reference rates, including euro and cross-currency conversions. Uses the latest preceding published rate when the date has none.
ecb.europa.eu/convert_currencyGets the official ECB euro reference exchange rates for a day, or the latest published day. Weekends, holidays and dates before publication return the previous published day.
ecb.europa.eu/get_euro_exchange_ratesChecks an EU VAT number in the European Commission's VIES service and returns whether it is valid, with the registered name and address when the country makes them available.
ec.europa.eu/validate_vat_number