Znajdź przetargi dzięki TED Search API
Czym jest TED Search API?
TED (Tenders Electronic Daily) to oficjalny dziennik UE dotyczący zamówień publicznych, w którym publikowane jest każde ogłoszenie o przetargu powyżej progów ze wszystkich 27 państw członkowskich. TED Search API udostępnia te ogłoszenia jako JSON przez jeden punkt końcowy:
POST https://api.ted.europa.eu/v3/notices/search
Możesz wywołać je bez żadnego uwierzytelniania, więc jest otwarte dla każdego ponownego użytkownika. Pełną dokumentację żądań i odpowiedzi znajdziesz w dokumentacji Swagger.
Czy potrzebujesz klucza API?
Nie do wyszukiwania. Search API jest w pełni publiczne, a klucz jedynie zwiększa limity zapytań i odblokowuje inne punkty końcowe, takie jak zarządzanie własnymi ogłoszeniami. Jeśli mimo to chcesz klucz, wystarczą trzy kroki:
- Wejdź na TED Developer Portal.
- Zaloguj się danymi EU Login.
- Wygeneruj klucz w sekcji Manage API Keys.
Wyszukiwanie przetargów w Pythonie
Każde żądanie zawiera trzy rzeczy: query, fields, które chcesz otrzymać, oraz limit. Sama query korzysta ze składni wyszukiwania eksperckiego TED, zapisanej jako field operator value i łączonej za pomocą AND, OR i NOT. Oto pola, których będziesz używać najczęściej:
| Pole | Przykład | Znaczenie |
|---|---|---|
classification-cpv | classification-cpv=38000000 | Kod CPV (branża) |
buyer-country | buyer-country=POL | Kraj zamawiającego, ISO 3-literowe |
publication-date | publication-date>=20260420 | Opublikowane w danym dniu lub później |
estimated-value-proc | estimated-value-proc>=50000 | Szacowana wartość zamówienia |
Zamiast uczyć się składni na pamięć, zbuduj zapytanie wizualnie w wyszukiwaniu eksperckim TED i skopiuj powstały ciąg zapytania do swojego kodu. Jeśli nie masz pewności, który kod CPV pasuje do twojej branży, sprawdź go w naszej wyszukiwarce kodów CPV.
Poniższy przykład znajduje przetargi na sprzęt laboratoryjny (CPV 38000000) opublikowane od początku roku, o szacowanej wartości od 50 000 do 500 000 EUR, od zamawiających w Polsce. Ponieważ pojedyncza strona zawiera najwyżej 250 ogłoszeń, przewija wyniki w trybie iteracji, pobierając pięć stron po 100, czyli do 500 ogłoszeń w jednym uruchomieniu:
import requests
import time
URL = "https://api.ted.europa.eu/v3/notices/search"
query = " AND ".join([
"classification-cpv=38000000", # Sprzęt laboratoryjny
"buyer-country=POL", # Polska
"publication-date>=20260101",
"estimated-value-proc>=50000",
"estimated-value-proc<=500000",
])
payload = {
"query": query,
"fields": [
"publication-number",
"notice-title",
"classification-cpv",
"estimated-value-proc",
"estimated-value-cur-proc",
],
"limit": 100,
"scope": "ACTIVE",
"paginationMode": "ITERATION",
}
notices = []
for _ in range(5): # Pobierz pięć stron.
data = requests.post(URL, json=payload).json()
notices.extend(data["notices"])
# Użyj tokenu iteracji do wydajnej paginacji.
token = data.get("iterationNextToken")
if not token or len(data["notices"]) < payload["limit"]:
break
payload["iterationNextToken"] = token
time.sleep(1)
for notice in notices:
number = notice["publication-number"]
title = notice["notice-title"]["pol"]
cpv = ", ".join(notice["classification-cpv"])
value = notice.get("estimated-value-proc", "n/a")
currency = notice.get("estimated-value-cur-proc", "")
print(f"{number} | {title} | {value} {currency} | {cpv}")
Warto znać kilka szczegółów dotyczących odpowiedzi. notice-title jest indeksowane według kodu języka, więc notice-title["pol"] zwraca tytuł po polsku, a classification-cpv przychodzi jako lista kodów. W trybie iteracji każda strona przekazuje token iterationNextToken, który odsyłasz w kolejnym żądaniu, a pętla zatrzymuje się, gdy tylko strona wróci mniejsza niż twój limit. Stąd możesz zamienić POL na dowolny kod kraju lub 38000000 na branżę, w której startujesz.
Ograniczenia i dobre praktyki
Search API jest hojne, ale kilka ograniczeń wpływa na sposób korzystania:
- Rozmiar strony. Żądanie zwraca najwyżej 250 ogłoszeń, więc cokolwiek większego wymaga
paginationMode: "ITERATION"i pokazanej powyżej pętli z tokenem. - Rozmiar zapytania. Pojedyncze zapytanie może zawierać do 2000 klauzul. Gdy celujesz w wiele kodów CPV, grupuj je za pomocą
IN (...)zamiast łączyć długi ciąg warunkówOR. - Limity zapytań. Wywołania anonimowe są ograniczane, więc zarejestruj klucz API, zanim uruchomisz ciężkie lub zaplanowane zadania.
- Kształt pól. Wiele pól jest wielojęzycznych lub wraca jako listy, dlatego przykład odczytuje je ostrożnie za pomocą
.get()i klucza języka. - Bądź w porządku. Buforuj pobrane dane i unikaj dwukrotnego pobierania tych samych ogłoszeń. TED aktualizuje się w ciągu dnia, więc zwykle wystarcza synchronizacja godzinna lub dzienna.
To cała pętla: zbuduj zapytanie, wyślij je metodą POST, odczytaj JSON i paginuj. Stąd możesz zapisywać ogłoszenia w bazie danych, wysyłać powiadomienia do zespołu lub przekazywać je bezpośrednio do własnego produktu.