TED EU Tenders Scraper: Public Procurement Notices
Pricing
from $1.60 / 1,000 notices
TED EU Tenders Scraper: Public Procurement Notices
Search EU public procurement notices on TED by keyword, CPV code, country and date: buyer, deadline, estimated value, CPV codes, winners and links.
Pricing
from $1.60 / 1,000 notices
Rating
0.0
(0)
Developer
MRSLM Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
Search EU public procurement notices on TED by keyword, CPV, country and date: buyer, deadline, estimated value, CPV codes, winners and links. $2.00 per 1,000 notices.
TED (Tenders Electronic Daily) publishes every public contract above EU thresholds from 30+ European countries: hundreds of thousands of notices a year. This Actor turns it into a clean daily lead feed of open tenders, or a list of awards and winners.
Quick start
- Press Start. The form is already filled with this example input, so the first run returns real rows in under a minute:
{"keywords": ["software development"],"countries": ["DE","FR","NL"],"publishedWithinDays": 14,"maxResults": 30}
- Swap in your own values, or call the Actor through the Apify API, Make, Zapier, n8n or the Python/JS clients with the same JSON.
- Download the results as JSON, CSV or Excel from the Output tab, or schedule the run to repeat.
Full guide: How to Find Translation and Interpreting Tenders in the EU and See Who Wins Them (Real Runs on TED)
Why language services are a good TED niche
Language services are a niche where TED works particularly well, for three reasons.
- One clean pair of codes. In the Common Procurement Vocabulary (CPV), translation services are 79530000 and interpretation services are 79540000, both under 79500000 (office-support services). Buyers in every member state use these codes even when they write the notice in Dutch, Swedish or Latvian. So you can search by code once instead of guessing at keywords in 24 languages.
- Lots of mid-sized contracts. In the awards run below, the 46 euro-denominated award notices that gave a value (after removing modifications and duplicates) had a median of about €404,000, with a long tail up to a €90 million interpreting framework. That's large enough to matter, and small enough that specialised agencies win them.
- Repeat buyers on a cycle. Interpreting frameworks for police, councils and hospitals run two to four years, then go back out to tender.
The same workflow works for any service with clear CPV codes, such as cleaning (90910000) or legal services (79100000).
What you need
A free Apify account and the Actor: apify.com/mrslm_data/ted-eu-tenders. No TED account, API key or proxy is needed, because the Actor reads TED's public Search API (api.ted.europa.eu, version 3), the same index the TED website uses.
Run 1: every open translation and interpreting tender in Europe
The input
Open the Actor, switch the input form to JSON and paste this:
{"cpvCodes": ["79530000", "79540000"],"noticeKind": "tenders","publishedWithinDays": 30,"openForBidsOnly": true,"maxResults": 40}
Here is what each field does, taken from the Actor's input schema and source:
- cpvCodes: 8-digit CPV codes. You can paste codes with the check digit (
79530000-8); the Actor strips the-Npart. A code also matches the codes below it in the CPV tree, so79530000would also catch a narrower child code if a buyer used one. - noticeKind:
tenders(calls for competition, the default),awardsorall.tenderscovers ordinary contract notices, light-regime social services notices, design contests, prior-information notices used as a call for competition, qualification systems and subcontracting notices. - publishedWithinDays: only notices published in the last N days. 30 gives a month of history.
- openForBidsOnly: keep only notices whose tender deadline is today or later, so nothing has already closed.
- maxResults: a hard cap on rows (and therefore on cost). 40 was a safe ceiling; the run found 37.
The other filters (countries, keywords, language, includeDescription, expertQuery and maxResultsPerSearch) are covered in "Choosing CPV codes and filters" below.
What the Actor sends to TED
The run summary (in the run's key-value store, record RUN_SUMMARY) records the exact TED query. For this input it was:
classification-cpv IN (79530000 79540000) AND notice-type IN (cn-standard cn-social cn-desg pin-cfc-standard pin-cfc-social qu-sy subco) AND publication-date>=today(-30) AND deadline-receipt-tender-date-lot>=20261031
You can paste it into TED's own expert search to check the results by hand, and add any filter the form lacks through expertQuery in the same syntax.
The result
Run rRmhiQtHgyMbV2xUN finished in 4.1 seconds with 37 rows. That's every notice that matched, below the 40 cap. It was charged for 1 start event and 37 notice events.
Where the tenders were:
| Country | Open notices |
|---|---|
| Netherlands | 5 |
| Poland, Germany, France, Sweden | 4 each |
| Norway, Denmark | 3 each |
| Spain, Slovakia, Finland | 2 each |
| Estonia, Latvia, Ireland, Greece | 1 each |
All 37 were cn-standard notices for services under the open procedure. Publication dates ran from 1 to 30 October 2026. Deadlines ran from 2 November 2026 to 27 January 2027, most of them in November, so a weekly check would already miss some.
A sample of real rows:
| Buyer | Country | What | Value | Deadline | Notice |
|---|---|---|---|---|---|
| Ministerie van Buitenlandse Zaken | NL | Translation Dutch–English (framework) | €400,000 | 6 Nov 2026 | 755696-2026 |
| European Central Bank | DE | Translation EN→DE/FR/IT, 9 lots | est. €2.23M, total €2.3M | 2 Nov 2026 | 683267-2026 |
| European Central Bank | DE | Legal translation, 7 lots | total €1.45M | 27 Nov 2026 | 750606-2026 |
| Politie | NL | On-site interpreting, 3 lots | est. €60M, total €6M | 7 Dec 2026 | 678243-2026 |
| Stockholms läns sjukvårdsområde | SE | Interpreting services, 3 lots | total SEK 300M | 19 Nov 2026 | 720335-2026 |
| Innherred anskaffelser | NO | Interpreting framework | NOK 35M | 1 Dec 2026 | 747923-2026 |
| Department of Social Protection | IE | Polish document translation | €620,000 | 23 Nov 2026 | 732190-2026 |
| Tieslietu ministrija (Ministry of Justice) | LV | Translation, 13 lots | est. €467,851.24 | 27 Nov 2026 | 731547-2026 |
| Sametinget | NO | Norwegian–Northern Sami translation | NOK 2.2M | 23 Nov 2026 | 694228-2026 |
| Stichting Nidos | NL | Interpreting | not published | 27 Jan 2027 | 715098-2026 |
All 37 rows have a deadline. Two of them are sign-language interpreting tenders (a French ministry and a German federal body), which are also filed under these codes.
One full row, exactly as the dataset returns it:
{"noticeId": "755696-2026","title": "Netherlands – Translation services – Vertaaldiensten Nederlands-Engels","procedureTitle": "Vertaaldiensten Nederlands-Engels","buyerName": "Ministerie van Buitenlandse Zaken","buyerCity": "Den Haag","buyerCountry": "NLD","noticeType": "cn-standard","procedureType": "open","contractNature": "services","mainCpv": "79530000","cpvCodes": ["79530000"],"placeOfPerformance": ["NLD"],"publicationDate": "2026-10-30","deadline": "2026-11-06","requestToParticipateDeadline": null,"estimatedValue": 400000,"totalValue": 400000,"currency": "EUR","lots": 1,"winners": [],"frameworkAgreement": true,"url": "https://ted.europa.eu/en/notice/-/detail/755696-2026","pdfUrl": "https://ted.europa.eu/en/notice/755696-2026/pdf","scrapedAt": "2026-10-31T16:19:38.927Z"}
What the open tenders tell you
Reading the 37 rows together brings out some patterns you'd never see one notice at a time:
- Frameworks dominate. 24 of the 37 notices are framework agreements. You're usually bidding for a place on a panel for two to four years, not for a single job. That changes how to price: a framework "value" is a ceiling, not a guaranteed spend.
- Lots are how small agencies get in. 24 notices have a single lot, but some are split finely. The Latvian Ministry of Justice has 13 lots, the ECB 9 and 7. A lot is usually a language pair or a region, and you can often bid for just one.
- Values are optional. Only 18 rows have
estimatedValueand 22 havetotalValue. 14 rows have no currency at all because the buyer published no value. Four in Swedish kronor, three in Norwegian kroner and one in Danish kroner remind you that the Nordic buyers don't price in euros. - Interpreting outweighs translation. By main CPV, 21 rows were interpreting and 10 translation. Police, healthcare, social services and asylum make public-sector interpreting a big, steady market.
Run 2: who wins these contracts
Finding tenders is half the job. The other half is knowing the competition: who won the last round, how many winners a framework takes, and what the contracts were worth. Award notices answer all three.
The input
{"cpvCodes": ["79530000", "79540000"],"noticeKind": "awards","publishedWithinDays": 180,"maxResults": 120}
The only changes are noticeKind: "awards", a longer look-back and a bigger cap. With awards, the Actor asks TED for notice types can-standard, can-social, can-desg, can-tran and can-modif. Those are ordinary award notices, light-regime awards, design-contest results, transport awards and contract modifications.
The result
Run ErOam2bXgJFt2MZMR finished in 8.5 seconds with 120 rows. Its status message was "Done. 120 results from 1 target(s). Reached maxResults (120)". It was charged for 1 start event and 120 notice events.
Important: TED returns notices newest first, and the cap cut the run off. So although the input asked for 180 days, the 120 rows only reach back to 31 July 2026, three months. To cover the full six months, raise maxResults (the run summary reported at least 200 matching award notices), or run month by month. This is the single most common way to get a silently partial dataset, so check the oldest publicationDate in your results.
By country: Spain 28, Poland 20, Germany 10, France 9, Switzerland 9, Luxembourg 5, Czechia, Bulgaria and Ireland 4 each, and the rest spread across 14 other countries. Spain and Poland publish many small, single-lot awards; Luxembourg's 5 are mostly large EU-agency frameworks.
By notice type: 96 can-standard, 21 can-modif and 3 can-social. None of the 21 modification notices names a winner in the winners field; they amend an existing contract (an extension, a price change). Of the 99 actual award notices, 90 name at least one winner.
Values: 87 of the 120 rows have a totalValue. Currencies: 57 EUR, 18 PLN, 9 CHF, and smaller numbers of CZK, SEK, NOK, DKK, RON and HUF. After removing modifications and duplicates, the 46 euro award notices with a positive value have a median of about €404,000.
The biggest awards in the window
| Published | Buyer | Contract | Value | Winners (first few) |
|---|---|---|---|---|
| 26 Oct | European Border and Coast Guard Agency (Frontex), PL | Interpretation and cultural mediation framework, 7 lots | €90M | Authentic Enterprise Solutions, Interpreti Traduttori Mediatori, Language Academy, Ofilingua, SeproTec |
| 11 Aug | Høje-Taastrup Kommune, DK | Interpreting for the ICØ municipalities | DKK 59.8M (est. DKK 43.0M) | ViTolker ApS |
| 5 Aug | Politie, NL | Remote interpreting | €40M | Global Talk |
| 28 Aug | Ministerie van Justitie en Veiligheid, NL | Translation for the Public Prosecution Service | €36.9M (est. €24.6M) | AVB Language Group, thebigword |
| 22 Sep | Translation Centre for the Bodies of the EU, LU | Translation and post-editing of standardised technical texts, 22 lots | €10.55M | 16 winners, including ARTE.DOC, Acolad Luxembourg, Avatar and CBG Konsult |
| 23 Oct | Translation Centre for the Bodies of the EU, LU | Translation and post-editing, 12 lots | €3.80M | Acolad Luxembourg, Celer Pawlowsky, ETC Europe, IDEST Communication… |
| 2 Oct | DSS (Norwegian government shared services), NO | Translation of EEA-relevant EU rules, 3 lots | NOK 8M | Totaltekst, Semantix Translations Norway, and one sole trader |
| 28 Oct | Assistance Publique – Hôpitaux de Paris, FR | Remote interpreting for Paris hospitals | €3M | ISM Interprétariat, Association Tradlibre, Acolad France |
| 23 Oct | Giunta Regionale, IT | Linguistic mediation by telephone interpreting | €990,000 (est. €1.52M) | Translated srl |
The €64.8 million row from the EU Agency for Asylum is a can-modif (a modification), not a new award, which is why it isn't in the table. If you sort by value without filtering noticeType, modifications float to the top and mislead you.
Two Translation Centre notices (626728-2026 on 11 September and 651574-2026 on 22 September) carry the same title, value and 16 winners. That's a corrected re-publication, not two contracts. The €3.80M procedure also appears twice (674567-2026 on 1 October, then 736670-2026 on 23 October with a different winner list), so read both before deciding which is final. More on deduplication below.
Who wins most often
Counting each winner once per notice, after cleaning (see the next section), the award notices name 267 distinct winners, companies and sole traders together. The most frequent names are:
- Swiss federal frameworks dominate the top. The Swiss Federal Chancellery split one tender into many lots of framework contracts and published nine award notices, each naming between 6 and 40 distinct winners. That's why Apostroph Bern (8 notices), Swisstrade Solutions (7), All Languages Made Accessible, Translingua and SwissGlobal Language Services (6 each), and Hieronymus, Supertext and About SA (5 each) lead the count.
- Acolad appears under four entities: Acolad France, Acolad Luxembourg (two spellings) and Acolad Finland Oy. Together they're on 6 distinct award notices in France, Luxembourg, Finland and Portugal. It's the clearest multinational in this sample.
- Extran / TTN Translation Network on 5 notices (Switzerland and Germany), Ofilingua on 4 (Spain and Poland), SeproTec on 3 under three different spellings (Spain and Poland), Lingsoft on 3 (Finland and Luxembourg) and Semantix on 2 (Luxembourg and Norway).
- The long tail is local. Most winners appear once: a Romanian media company on three Romanian awards (two ministries), a Prague translation centre that won with both the Czech Social Security Administration and the Ministry of Health, and many single-office agencies and sole traders in Poland and Spain. (This guide doesn't name individual sole traders. Their names are in the public notices, but there's no reason to repeat them.)
What that means if you're bidding: large frameworks attract multinationals and take many winners, so a panel place is achievable but is a place in a queue. Single-lot municipal and regional contracts in Spain, Poland, the Nordics and the Netherlands are where one capable local agency wins outright.
Clean the data before you use it
Raw TED data has quirks. None of them is a bug in the Actor; they're how buyers publish. All of these turned up in the two runs above.
1. The same procedure appears more than once
Run 1 had three pairs of notices that were really the same procedure, each published twice:
- Gemeente Súdwest-Fryslân: 713580-2026 and 710856-2026
- Ringkøbing-Skjern Kommune: 715122-2026 and 678911-2026
- Slovak Ministry of Transport: 724648-2026 and 705830-2026
Run 2 had the Translation Centre pair above and two identical Polizeipräsidium Wuppertal award notices for interpreting and translation (28 and 30 September, 24 winners each, €2.5M).
Usually the second notice is a correction, a changed deadline or a re-publication. For open tenders, group by buyer and procedure title and keep the newest publicationDate. For awards, be careful: the nine Swiss Chancellery notices share one procedure title but cover different lots and winners. So treat award notices as duplicates only when buyer, title, value and winners all match.
2. Off-topic matches through secondary codes
TED matches a CPV code anywhere on the notice, not only the main code. In run 1, 31 of 37 rows had translation or interpreting as their main CPV. The other six listed it as a secondary code:
- Polish regional development agencies organising trade missions and study trips (main codes 79952000 event services and 55100000 hotel services). Interpreting is one item in a travel package.
- Two research-related notices (main code 73000000).
- A visitor-centre project for Santorini's volcano (main code 92110000).
If you sell translation, those six probably aren't for you. Filter on mainCpv, or keep them in a separate tab if you're a travel or events company that subcontracts interpreters.
3. Two value fields that disagree
estimatedValue is the sum of the lot estimates; totalValue is the value given for the whole notice. Usually they match. When they don't, it's worth a look:
- Politie (NL) on-site interpreting: estimated €60M, total €6M. A factor of ten suggests one figure is per year and the other for the whole term, or a typo. Open the notice.
- Lomma kommun (SE): estimated SEK 80M, total SEK 40M.
- Högskoleservice i Jönköping (SE): estimated SEK 56M, total SEK 14M. In the awards run, the same buyer's award shows SEK 14M with an SEK 56M estimate.
- Høje-Taastrup (DK): estimated DKK 43.0M, awarded DKK 59.8M.
In the awards data, 11 rows have a total of 0 (mostly the Swiss frameworks, which publish no value) and one has −1, a placeholder some buyers use. Treat 0 and negative values as "not published".
4. Winner names in several languages
Swiss notices are multilingual, and TED returns each winner name once per language with a prefix, for example FR_Apostroph Bern GmbH, DE_Apostroph Bern GmbH, IT_Apostroph Bern GmbH. The Actor passes these through unchanged. Strip a leading two-letter prefix and an underscore before counting, or a company is counted three times. Companies also appear under different spellings (SeproTec in three spellings), so a little manual merging is needed for a clean league table.
A small Python cleaning script
This is the script used for the counts in this guide (on run 2 it keeps 97 of the 120 notices). It works on the JSON export of an awards run:
import json, re, collectionsrows = json.load(open("ted-awards.json")) # dataset export, JSON formatdef clean_name(w):return re.sub(r"^(FR|DE|IT|EN)_", "", w).strip()# 1. drop modifications and exact re-publications (same buyer, title, value, winners)awards = [r for r in rows if r["noticeType"] != "can-modif"]latest = {}for r in sorted(awards, key=lambda r: r["publicationDate"]):key = (r["buyerName"], r["procedureTitle"], r["totalValue"],tuple(sorted({clean_name(w) for w in r["winners"]})))latest[key] = rawards = list(latest.values())# 2. count each winner once per noticewins = collections.Counter()for r in awards:for name in {clean_name(w) for w in r["winners"]}:wins[name] += 1for name, n in wins.most_common(15):print(n, name)# 3. values: treat 0 and negatives as missingeur = sorted(r["totalValue"] for r in awardsif r["currency"] == "EUR" and (r["totalValue"] or 0) > 0)print("median EUR award:", eur[len(eur) // 2] if eur else None)
The same steps in a spreadsheet: sort by publicationDate descending, filter noticeType ≠ can-modif, use Data > Data clean-up > Remove duplicates on the buyer, procedure-title, value and first-winner columns, and filter mainCpv to your codes.
Choosing CPV codes and filters
For language services, these codes cover nearly everything:
| CPV | Meaning | Use it when |
|---|---|---|
| 79530000 | Translation services | Written translation, sworn and legal translation, localisation |
| 79540000 | Interpretation services | On-site, remote, phone and video interpreting, sign language is often here too |
| 79500000 | Office-support services | Broader: catches some translation filed one level up, plus a lot of noise |
| 79952000 | Event services | Only if you also want conferences with interpreting bundled in |
Some practical filters:
- Countries. Add
"countries": ["NL", "BE", "DE"]to narrow to where you can deliver. Two- and three-letter codes both work. The Actor converts to TED's three-letter form. - Keywords for sub-niches. For sign language or a specific language pair, add
"keywords": ["sign language"]or a phrase in the notice language, such as"tolkning"or"vertaling". Each keyword line runs as its own search, combined with your CPV codes, and maxResultsPerSearch caps each one. - Language of titles.
"language": "fr"returns titles in French when TED has them, falling back to English and then to the first language available. - Descriptions.
"includeDescription": trueadds up to 4,000 characters of the description, which often names the language pairs and volumes. Contact details are removed from that text. - expertQuery. For anything else, add a clause in TED's syntax, such as
organisation-country-buyer=SWE, or a buyer-name match. It's ANDed with the rest, and the full query is logged, so you can check it on TED.
Run it every morning
Tender windows are short (run 1's earliest deadline was two days away), so fetch new notices daily.
-
Paste this input into the Actor's form and click Save as new task. Name it
ted-language-tenders-daily.{"cpvCodes": ["79530000", "79540000"],"noticeKind": "tenders","publishedWithinDays": 2,"openForBidsOnly": true,"maxResults": 100}Using 2 days instead of 1 means a notice published late in the day isn't missed. You'll see some notices twice across consecutive runs; deduplicate on
noticeId. -
Go to Schedules > Create new schedule. Use the cron expression
0 7 * * 1-5(07:00 Monday to Friday) and pick your timezone. TED publishes on working days, so weekend runs add nothing. -
Add the task to the schedule and save.
-
On the task's Integrations tab, add an email or Slack notification for "Run succeeded", or a webhook to your own system.
For a weekly competitor digest, add a second task with "noticeKind": "awards" and "publishedWithinDays": 8, scheduled for Monday morning (0 8 * * 1).
The newest results of a task are always at the same address:
https://api.apify.com/v2/actor-tasks/<USERNAME>~ted-language-tenders-daily/runs/last/dataset/items?status=SUCCEEDED&format=json
Send the results to Google Sheets
Three options, from simplest to most automated:
- Manual export. Open a run, go to Output > Export, choose CSV and the columns you want, then in Sheets use File > Import > Upload. Lists such as
winnersbecome numbered columns (winners/0,winners/1…). - Formula in a private sheet.
=IMPORTDATA("https://api.apify.com/v2/actor-tasks/<USERNAME>~ted-language-tenders-daily/runs/last/dataset/items?status=SUCCEEDED&format=csv&fields=publicationDate,deadline,buyerCountry,buyerName,procedureTitle,totalValue,currency,url&token=<YOUR_TOKEN>")This refreshes from the latest successful run. Your token is visible to anyone who can open the sheet, so keep the sheet private, or use a token with limited permissions. - Automatic append with Make, Zapier or n8n, as described in the next section.
Use it from Make, Zapier or n8n
All three have an official Apify integration, and the pattern is the same:
- Trigger: "Watch Actor runs" or "Watch task runs" (Make), "Finished Actor Run" or "Finished Task Run" (Zapier), or the Apify Trigger node (n8n), pointed at
ted-language-tenders-daily. - Get the rows: "Get dataset items" with the run's default dataset ID, which the trigger provides.
- Act on each row, for example:
- Google Sheets "Add a row" into a "Pipeline" tab.
- A Slack or Teams message for rows above a value: in Make, add a filter
totalValue > 100000. - Create a card in Trello, Asana or your CRM with the deadline as the due date.
Tip: add a Google Sheets "Search rows" step on noticeId first, and only add new rows. That removes the overlap from the 2-day window.
To start the run from the automation tool itself, use "Run a task", then "Get dataset items".
Call it from your own code
Put your API token (Console > Settings > API & Integrations) in an environment variable called APIFY_TOKEN; don't paste it into code.
Python, apify-client 3.x (pip install "apify-client>=3"):
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("mrslm_data/ted-eu-tenders").call(run_input={"cpvCodes": ["79530000", "79540000"],"noticeKind": "tenders","publishedWithinDays": 30,"openForBidsOnly": True,"maxResults": 40,})# apify-client 3.x returns a Run object: use attributes, not run["defaultDatasetId"]items = list(client.dataset(run.default_dataset_id).iterate_items())interpreting = [i for i in items if i["mainCpv"] == "79540000"]for i in sorted(interpreting, key=lambda i: i["deadline"] or ""):print(i["deadline"], i["buyerCountry"], i["buyerName"], "-", i["procedureTitle"])
JavaScript / Node.js (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('mrslm_data/ted-eu-tenders').call({cpvCodes: ['79530000', '79540000'],noticeKind: 'awards',publishedWithinDays: 180,maxResults: 120,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const withWinners = items.filter((i) => i.winners.length > 0);console.log(`${withWinners.length} of ${items.length} award notices name a winner`);
curl, one synchronous request that returns CSV. It waits up to 5 minutes, which is plenty for runs this size:
curl -X POST "https://api.apify.com/v2/acts/mrslm_data~ted-eu-tenders/run-sync-get-dataset-items?format=csv&fields=publicationDate,deadline,buyerCountry,buyerName,procedureTitle,totalValue,currency,url" \-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \-d '{"cpvCodes":["79530000","79540000"],"noticeKind":"tenders","publishedWithinDays":30,"openForBidsOnly":true,"maxResults":40}' \-o language-tenders.csv
Ask an AI assistant through MCP
Apify runs a hosted MCP server that can expose any Store Actor as a tool. To give Claude, Cursor, VS Code or another MCP client this Actor and nothing else, add the server URL:
https://mcp.apify.com/?tools=mrslm_data/ted-eu-tenders
For example, in a client that reads mcp.json:
{"mcpServers": {"ted-tenders": { "url": "https://mcp.apify.com/?tools=mrslm_data/ted-eu-tenders" }}}
The server uses OAuth: on first use, your client opens an Apify sign-in window. Clients that can't do OAuth can send Authorization: Bearer <your Apify token> instead. Then ask in plain language, for example:
- "Find open interpreting tenders in the Netherlands and Belgium published in the last two weeks, and list buyer, deadline and value."
- "Get translation award notices from the last 90 days in Spain and tell me which companies won more than one."
The assistant fills in the Actor input (CPV codes, countries, notice kind) and runs it on your Apify account at the normal per-notice price. Keep maxResults modest in your prompt ("at most 50 notices"), so an over-eager assistant doesn't run a large search.
What it costs
The Actor uses pay-per-event pricing, so you pay per notice returned, not for compute time.
| Event | Free / Bronze | Silver | Gold / Platinum / Diamond |
|---|---|---|---|
| Notice (per 1,000) | $2.00 | $1.80 | $1.60 |
| Actor start (once per run, at the default 512 MB) | $0.00005 | $0.00005 | $0.00005 |
The two runs in this guide, at Free/Bronze prices:
| Run | Rows | Charge |
|---|---|---|
| Run 1: open tenders (rRmhiQtHgyMbV2xUN) | 37 | 1 start + 37 notices = $0.07405 |
| Run 2: awards (ErOam2bXgJFt2MZMR) | 120 | 1 start + 120 notices = $0.24005 |
For ongoing use, at 21 working days and, say, 5 new notices a day, the daily schedule returns about 105 notices a month: about $0.21 a month plus 21 start fees (about $0.001). A weekly awards digest of 20–40 notices adds roughly $0.04–$0.08 a week. If you widen the search to 79500000 or remove the CPV filter, row counts rise quickly, so set Maximum cost per run in the run options (maxTotalChargeUsd in the API). The Actor stops cleanly at the cap.
Output fields
| Field | Meaning |
|---|---|
noticeId, url, pdfUrl | TED publication number, notice page and PDF. |
title, procedureTitle | TED's composed title and the buyer's procedure title. |
buyerName, buyerCity, buyerCountry | Contracting authority (ISO 3-letter country). |
noticeType, procedureType, contractNature | For example can-standard, open, services. |
mainCpv, cpvCodes | Main CPV code and every code on the notice. |
placeOfPerformance | NUTS or country codes. |
publicationDate, deadline, requestToParticipateDeadline | Publication date and deadlines. |
estimatedValue, totalValue, currency | Sum of lot estimates, notice total (awarded value on awards), currency. |
lots, frameworkAgreement | Number of lots; true for framework agreements. |
winners | Winners on award notices. |
description | With includeDescription only: up to 4,000 characters, contact details removed. |
scrapedAt | When the row was saved. |
Limits and honest caveats
- TED isn't every tender. It carries contracts above the EU thresholds plus those buyers publish voluntarily. Many small translation jobs only appear on national portals (TenderNed, Doffin, PLACSP, e-Zamówienia and so on), or are bought directly without a tender.
- The cap cuts off the oldest results. Results come newest first, so a capped run covers a shorter period than
publishedWithinDayssuggests (run 2 asked for 180 days and covered 92). Check the oldest date. - Data quality is the buyer's. Missing values, values of 0 or −1, estimates that disagree with totals, and winner names in three languages are all published that way.
- Award notices lag the contract signature, often by weeks, and framework call-offs are usually not published at all.
- No documents. The Actor returns the notice data and links. Tender documents (specifications, price schedules) sit on the buyer's procurement platform, often behind a free registration, and aren't downloaded.
- Personal data. Some winners are sole traders trading under their own name. Treat those names as personal data under the GDPR if you store or republish them.
FAQ
Does this work for languages other than English?
Yes. The search is by CPV code, which is language-independent, so you get notices from every country whatever language they're written in. Titles come in your chosen language when TED has a translation, and fall back to English, then to whatever language the notice has.
Why did a hotel or travel tender show up in my translation search?
Because translation or interpreting is one of its secondary CPV codes. TED matches every code on a notice. Filter on mainCpv to keep only notices that are mainly about language services.
How do I get only sign-language interpreting?
Keep cpvCodes at 79540000 and add "keywords": ["sign language"] plus the local terms you care about, such as "gebarentaal", "teckenspråk" or "Gebärdensprache". Each keyword runs as a separate search, and the results are merged.
Can I see who won a specific tender I bid on?
Yes. Run with "noticeKind": "awards". Add an expertQuery that narrows to the buyer, or search by keyword using words from the procedure title. The award notice usually has a different notice ID from the original call, so match on buyer and title.
Why are there no winners on some award notices?
Modification notices (can-modif) amend an existing contract and don't name winners in this field. Some award notices are published for procedures that ended without an award, or where the buyer withheld the name. In run 2, 9 of the 99 non-modification award notices had no winners.
Does it cover the UK, Switzerland or Norway? Switzerland and Norway publish on TED and appear above. The UK left TED in 2021; use UK Public Tenders for Contracts Finder and Find a Tender. For US federal awards, see USAspending Awards.
Is it legal?
This Actor only reads official open-data APIs that the publisher offers to everyone without a login or key. It obeys robots.txt, stays under the published rate limits, and never tries to get past logins, paywalls, captchas or bot checks. Contact persons, e-mail addresses and phone numbers in notices are never requested, and descriptions are scrubbed of contact details. Award notices name the winning organisations as published by the buyer; in rare cases a winner is a sole trader, so treat winner names with care under GDPR. You are responsible for how you use the data: follow the source's licence and terms and the privacy and marketing laws that apply to you (GDPR, CAN-SPAM, PECR, etc.). This tool is independent and not affiliated with or endorsed by the data publisher.