Public Tenders API — TED, Find a Tender & Contracts Finder avatar

Public Tenders API — TED, Find a Tender & Contracts Finder

Pricing

from $0.36 / 1,000 procurement notices

Go to Apify Store
Public Tenders API — TED, Find a Tender & Contracts Finder

Public Tenders API — TED, Find a Tender & Contracts Finder

EU and UK public tenders in one dataset: TED notices from across the EU/EEA, UK Find a Tender and Contracts Finder. Filter by keyword, CPV code, country, stage, dates, deadline, value and buyer. Deadlines, values, winners and links on one row. No API key.

Pricing

from $0.36 / 1,000 procurement notices

Rating

0.0

(0)

Developer

Insight Solutions

Insight Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 hours ago

Last modified

Share

Public-procurement notices from three official journals in one dataset schema, with no API key:

SourceWhat it coversKey needed
TED — Tenders Electronic Daily (ted)Every notice above the EU procurement thresholds, from all EU and EEA countries: calls for competition, prior-information notices, contract awards and modificationsNone
Find a Tender (uk-fts)UK notices above the UK thresholds, since the UK left TED at the start of 2021None
Contracts Finder (uk-cf)Lower-value UK public-sector contracts, mostly English buyersNone

Same columns on every row. stage, buyerName, cpvMain, deadline, estimatedValue, winnerNames and url mean the same thing whether a Slovak city put an IT tender on TED or an English council put a framework call-off on Contracts Finder — so "every open IT tender in Europe and the UK this week" is one query and one table.

No login. No browser. No personal contact data: the UK releases name the buying officer with an e-mail address and a direct line, and this Actor drops those contact blocks before anything else is read, never asks TED for its contact fields, and scrubs any address or number typed into free text.

At a glance

Input — this is the Store prefill; paste it and run:

{ "sources": ["ted", "uk-fts", "uk-cf"], "keywords": [], "cpvCodes": ["72"], "stages": ["tender"],
"publishedFrom": null, "publishedTo": null, "maxResults": 25, "includeDescriptions": true,
"language": "eng", "maxConcurrency": 3, "maxRunSecs": 240, "proxyConfiguration": { "useApifyProxy": true } }

(null dates mean the last seven days; CPV 72 is IT services.)

Output — one notice row per notice, same columns across all three sources. The fields you will use most are source, stage, title, buyerName, buyerCountry, cpvMain, publishedAt, deadline, estimatedValue, currency, winnerNames, awardedValue and url (full list under Output reference). A source that could not be read, found nothing or was skipped comes back as a free diagnostic row (ok: false, errorType, error) instead of a charge.

Price — $0.60 per 1,000 notices (+ $0.001 per run); diagnostics and empty runs free; no API key, no browser, limited permissions, works over the Apify MCP server and with x402.

From code — client.actor("insight.solutions/public-tenders-api").call(run_input={…}) with apify-client, or POST https://api.apify.com/v2/acts/insight.solutions~public-tenders-api/run-sync-get-dataset-items.


What you get

One row per notice. This is a real TED row from the 2026-09-28 capture, trimmed to the columns that carry something:

{
"ok": true,
"rowType": "notice",
"source": "ted",
"input": "TED (EU); stages tender; CPV 72; published 2026-09-21..2026-09-28",
"noticeId": "632847-2026",
"stage": "tender",
"noticeType": "cn-standard",
"formType": "competition",
"procedureType": "open",
"title": "Slovakia – IT services: consulting, software development, Internet and support – Rozvoj a prevádzka informačného systému mestskej polície ŽandárIS",
"buyerName": "Hlavné mesto Slovenskej republiky Bratislava",
"buyerCountry": "SVK",
"cpvMain": "72000000",
"cpvCodes": ["72000000", "72267100", "48810000"],
"contractNature": "services",
"placeOfPerformance": ["SK010", "SVK"],
"performanceCountries": ["SVK"],
"publishedAt": "2026-09-15",
"deadline": "2026-10-19",
"estimatedValue": 378048.78,
"currency": "EUR",
"url": "https://ted.europa.eu/en/notice/-/detail/632847-2026",
"pdfUrl": "https://ted.europa.eu/en/notice/632847-2026/pdf",
"xmlUrl": "https://ted.europa.eu/en/notice/632847-2026/xml",
"language": "slk",
"rank": 4,
"scrapedAt": "2026-09-28T17:05:12.000Z"
}

A UK award fills the award half of the same schema — this is the Home Office row from the Contracts Finder capture: stage: "award", buyerName: "Home Office", winnerNames: ["Encircle Solutions Limited"], winnerSize: "sme", awardedValue: 232874, currency: "GBP", isFramework: true, contractStart: "2026-10-01", contractEnd: "2029-09-30", and a url on contractsfinder.service.gov.uk. The release it came from also named the buying officer with an e-mail address; the row does not.

Three dataset views ship with it: Notices (the columns a bid team scans), Awards (who won what, for how much) and Diagnostics.


Quick start

Every open IT tender in the EU and the UK published this week:

{ "cpvCodes": ["72"], "stages": ["tender"] }

German and Austrian construction tenders over €1m that close in November:

{
"sources": ["ted"],
"cpvCodes": ["45"],
"countries": ["DEU", "AUT"],
"minValue": 1000000,
"deadlineFrom": "2026-11-01",
"deadlineTo": "2026-11-30",
"maxResults": 0
}

Who won UK cyber-security contracts last month:

{
"sources": ["uk-fts", "uk-cf"],
"keywords": ["cyber", "security operations"],
"stages": ["award"],
"publishedFrom": "2026-08-01",
"publishedTo": "2026-08-31",
"maxResults": 500
}

Input

FieldTypeDefaultTEDFind a Tender / Contracts Finder
sourcesmulti-selectall threeteduk-fts, uk-cf
keywordsstring[][]Full-text search, server-sideMatched here against title, description, buyer and CPV labels (the UK APIs have no working keyword filter)
cpvCodesstring[][]classification-cpv, 2–8 digits; 72 covers every 72… codePrefix match on the tender and item codes
countriesstring[][]Buyer country, alpha-3 (DEU) or alpha-2 (DE)UK only: skipped with a free row when the list leaves out GBR
stagesmulti-select["tender"]notice-type (table below)Release tag; stages= sent when exactly one of planning / tender / award is picked
publishedFrom / publishedToISO date7 days ago / todaypublication-dateFind a Tender: last updated (its only window); Contracts Finder: published
deadlineFrom / deadlineToISO date—Deadline for tenders (deadline-receipt-tender-date-lot), server-side; applied on the rows instead if TED ever refuses the clauseApplied on the rows (tenderPeriod.endDate)
minValue / maxValuenumber—Applied on the rowsApplied on the rows
buyerNamesstring[][]buyer-name, server-sideCase-insensitive substring of the buyer name
includeDescriptionsbooleantrueRequest the procedure and lot descriptionsKeep tender.description
languagestringengWhich of TED's 24 title translations to return—
maxResultsinteger200Per source; 0 = no cap. Pages of 20, 50 or 100 notices (TED caps fields × page size at 10,000, so 100 is the working maximum)Per source; pages of 100 releases
maxConcurrencyinteger3Sources in parallel; pages within one source are sequentialsame
maxRunSecsinteger240Time budget; rows already returned are keptsame
proxyConfigurationobject{"useApifyProxy": true}Datacenter; all three also answered unproxiedsame

Values are compared in the notice's own currency — there is no currency conversion, so minValue: 1000000 means a million euros on a German notice and a million zloty on a Polish one. A notice that publishes no value is left out when minValue or maxValue is set; a notice with no deadline is left out when a deadline filter is set.

Every filter that runs on the rows runs before the row is written, so a notice it drops is never billed.


Output reference

Every row carries every column, null where it does not apply.

Envelope — ok, rowType (notice | diagnostic), input, source, sourceUrl, scrapedAt, error, errorType.

Identity — noticeId, ocid (UK), stage, noticeType, formType, procedureType, title, description.

Buyer — buyerName, buyerCountry (alpha-3), buyerCity, buyerPostcode, buyerType, buyerWebsite, buyerId. Organisation-level only.

What and where — cpvMain, cpvCodes[], cpvDescription (UK), contractNature (services / supplies / works), procurementCategory (the source's own word), placeOfPerformance[] (NUTS / ITL codes and countries), performanceCountries[].

Dates — publishedAt and dispatchedAt (the calendar date as published), deadline (an ISO-8601 UTC instant when a time is published, else the date), deadlineTime (the time of day as published, with its offset).

Money — estimatedValue, awardedValue, currency. Null when not published, never zero.

Award — winnerNames[], winnerCountries[], winnerCount, winnerSize.

Terms — isSmeSuitable, isFramework, electronicSubmission, contractStart, contractEnd, contractDurationDays, lots, legalBasis.

Links — url (the human notice page), pdfUrl and xmlUrl (TED), documentsUrl, submissionUrl. Only http(s) links; a mailto: or an e-mail address typed into a link field is dropped.

Run context — language (the notice's original language), matchedKeywords[], rank (1-based within its source for this run).

Notes on particular columns

  • title on TED rows is TED's own translation into language (English by default), falling back to English and then to the original. TED publishes every title in all 24 EU languages; the original language is in language.
  • Multi-lot notices: deadline is the earliest lot deadline still in the future (else the latest), estimatedValue is the procedure-level value when published, else the sum of the lot values when they share one currency, else the first lot's; lots counts the lot titles.
  • description is clipped to 4,000 characters and any e-mail address or phone number in it is replaced by [email removed] / [phone removed].
  • winnerNames are organisations. Where a winner trades under a person's name, that is the name it registered as a business.

Stages explained

stageTED notice-type codesUK release tags
planningpin-buyer, pin-only, pin-tran, pin-rtl, pin-cfc-standard, pin-cfc-socialplanning, planningUpdate
tendercn-standard, cn-social, cn-desg, qu-sy, subcotender, tenderUpdate, tenderAmendment
awardcan-standard, can-social, can-desg, can-tranaward, awardUpdate, contract, contractUpdate
modificationcan-modifcontractAmendment
othercorr, brin-eeig, brin-ecs, veat and any code not listedanything else

noticeType keeps the source's own code, so nothing is lost by the mapping.

Which source covers what

  • TED carries every notice above the EU thresholds from the EU and EEA — for supplies and services from the low hundreds of thousands of euros, for works from several million. Below the thresholds, national portals publish instead, and those are not in this Actor.
  • Find a Tender is the UK's replacement for TED since 2021: UK notices above the UK thresholds. Its API only offers a last updated window, so publishedFrom / publishedTo select notices updated in that window — a notice published last month and amended yesterday comes back.
  • Contracts Finder carries lower-value UK contracts, mostly from buyers in England, and some above-threshold ones too. Expect a few notices to appear in both UK sources.

What you are never charged for

  • Notices that were read and then excluded by one of your filters. Every filter runs before the row is written, so it is never billed.
  • Every diagnostic row — no-results, skipped, bad-query, bad-request, rate-limited, blocked, http, timeout, deadline, budget, partial, upstream-format, invalid-input, actor-error.
  • A run that returns nothing. A run whose input was usable but produced nothing — no match, filters that excluded everything, UK sources skipped by the country filter, a source that refused us or was down — finishes SUCCEEDED with zero results, a status message that says so and points at the diagnostic rows, and nothing charged, start fee included. A run finishes FAILED only when there was nothing usable to attempt (no source selected) or the Actor itself hit an error.

Pricing

EventFREEBRONZESILVERGOLD
Run started$0.001$0.001$0.001$0.001
Procurement notice$0.0006$0.0006$0.00048$0.00036

$0.60 per 1,000 notices at the free tier, whichever source they came from. 300 notices from three sources cost 300 × $0.0006 + $0.001 = $0.181.

The run honours ACTOR_MAX_TOTAL_CHARGE_USD: when the ceiling is reached it stops fetching, leaves a free budget row, keeps everything already delivered and finishes successfully.


Use it from an AI agent, or from code

One JSON object in, one flat array out. The Actor runs with limited permissions, uses pay-per-event pricing and never enters Standby, so it works over the Apify MCP server and with x402 agentic payments.

curl -X POST "https://api.apify.com/v2/acts/insight.solutions~public-tenders-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"cpvCodes":["72"],"stages":["tender"],"maxResults":50}'
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("insight.solutions/public-tenders-api").call(run_input={
"sources": ["ted", "uk-fts", "uk-cf"],
"cpvCodes": ["72"],
"stages": ["tender"],
"deadlineFrom": "2026-10-15",
"maxResults": 100,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["rowType"] != "notice":
continue
print(row["source"], row["buyerCountry"], row["buyerName"], row["title"],
row["deadline"], row["estimatedValue"], row["currency"], row["url"], sep=" | ")

For a daily feed, schedule the run with the default seven-day window and de-duplicate on source + noticeId.


FAQ

Do I need a TED or UK API key? No. All three search APIs are public and keyless, and this Actor asks you for no key of any kind.

Why are there no contact names, e-mails or phone numbers? By design. Buyers are organisations, and the rows describe organisations. The UK releases name the procurement officer with an e-mail address and a direct line, and TED notices can carry contact persons; this Actor never requests the TED contact, person or e-mail fields, removes every UK contactPoint before anything else is read, and scrubs addresses and numbers out of free text. The notice page in url is where a bidder finds the official channel for clarification questions.

Why are the TED titles in English? TED publishes every notice title machine-translated into all 24 EU languages. This Actor returns the one you pick in language (English by default); the language the buyer actually wrote in is in the language column, and the buyer's name is always as published.

Why is awardedValue empty on some TED award notices? TED fills a value the buyer did not disclose with -1. No contract is worth less than nothing, so any negative amount comes back as null rather than as a number to sort on. Likewise a placeholder name such as "." is skipped in favour of the next real one.

Are values converted to one currency? No. estimatedValue and awardedValue are in the notice's own currency. A value filter compares numbers in that currency, too.

Why do some UK notices appear twice? Some buyers publish the same procurement on both Find a Tender and Contracts Finder, and the two services number it differently. Within one service the ocid column ties every release of one procurement together; across the two, match on buyerName and title.

Why did my Find a Tender search return an old notice? Its API filters on last updated, not on publication. A notice amended inside your window comes back as its latest release, and publishedAt is that release's date.

What happens when a source is down? That source leaves a free diagnostic row saying so and the others keep going. If none produced a row, the run still finishes SUCCEEDED with zero results, a "0 results" status message pointing at the diagnostic rows, and nothing charged.


Limitations

  • Above-threshold EU notices only. National below-threshold portals are not in this version.
  • Keyword, CPV, buyer, deadline and value filters on the UK sources run on the rows, because those APIs have no working filter for them. It is correct and free to you, but a narrow filter over a wide window reads many pages to find a few matches; raise maxRunSecs for large windows.
  • TED pages hold at most 100 notices here. TED's own limit is 250 (a request for 251 is refused with SEARCH_EXCEEDS_MAX_LIMIT), but it also caps fields × page size at 10,000, and this Actor asks for 71–73 fields per notice, so 100 is the largest page it can use. It steps down on its own if TED ever lowers either ceiling.
  • TED field shapes change with eForms versions. Every field this Actor reads was checked against a capture of 120 TED notices carrying all of them — tenders, awards and prior-information notices — but every field is still read as optional, and one TED no longer recognises becomes a free upstream-format row naming it rather than a wrong value. A column can go null when TED changes what it publishes.
  • The upstream format may change. These are three independently operated government APIs; a shape this Actor does not recognise becomes a free diagnostic row, not a charge.
  • No currency conversion, and no de-duplication across sources.

Sources, terms and attribution

  • TED. Notices are published by the Publications Office of the European Union on Tenders Electronic Daily; reuse is authorised under the European Commission's reuse policy, with the source acknowledged.
  • Find a Tender and Contracts Finder. Contains public sector information licensed under the Open Government Licence v3.0.

This Actor is independent. It is not affiliated with, endorsed by or sponsored by the Publications Office of the European Union, the European Commission, the UK Cabinet Office or the Crown Commercial Service. Nothing here is legal advice, and you are responsible for using the data lawfully.

Our other Actors

Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.

Video, audio & social

News, documents & the web

Business, finance & jobs

Apps & games