Gov APIekapv2.kik.gov.tr ↗
Search 2 million Turkish public tenders on EKAP, retrieve full tender details, notices, CPV items, and filter vocabularies for all 81 provinces.
What is the Gov API?
This API exposes Turkey's EKAP public procurement platform across 3 endpoints, covering roughly 2 million tenders dating back to 2002. Use search_tenders to filter the catalogue by province, status, free-text query, or tender registration number (IKN), then call get_tender_details to retrieve the full record including CPV classifications, published notices with full text, contracting authority contacts, and signed contracts.
curl -X GET 'https://api.parse.bot/scraper/6a305a6d-0eb9-4eea-b9e7-df88af84fd81/search_tenders?sort=tender_date_desc&query=bilgisayar&tender_type=goods' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace ekapv2-kik-gov-tr-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: EKAP public tenders — search, drill into details, list filters."""
from parse_apis.ekapv2_kik_gov_tr_api import (
Ekap, SortOrder, TenderType, TenderNotFound,
)
client = Ekap()
# Search for goods tenders matching a keyword, newest first.
for summary in client.tender_summaries.search(
query="bilgisayar",
tender_type=TenderType.GOODS,
sort=SortOrder.TENDER_DATE_DESC,
limit=5,
):
print(summary.ikn, summary.title, summary.province)
# Drill into the first result's full details.
hit = client.tender_summaries.search(query="bilgisayar", limit=1).first()
if hit is not None:
try:
tender = hit.details()
except TenderNotFound:
print("Tender expired or not found:", hit.ikn)
else:
print(tender.title, tender.tender_datetime)
print("Electronic:", tender.is_electronic, "Partial bids:", tender.allows_partial_bids)
print("Authority:", tender.contracting_authority.name, tender.contracting_authority.province)
for cpv in tender.cpv_items:
print(" CPV", cpv.code, cpv.name)
for notice in tender.notices:
print(" Notice:", notice.title, notice.published_date)
# List available filter vocabularies for building richer searches.
filters = client.filter_options.get()
for status in filters.statuses[:3]:
print(status.id, status.name, status.name_en)
for province in filters.provinces[:3]:
print(province.id, province.name)
print("exercised: tender_summaries.search / details / filter_options.get")
Searches the EKAP tender catalogue (about 2 million tenders since 2002) and returns one page of tender summaries plus the total match count. Every filter is optional; with none given the whole catalogue is returned sorted by tender date, newest first. Free-text query matches tender titles as typed. Filters can be combined (type, status, province, tender-date window, notice-date window, exact IKN). Paging is caller-controlled through page (1-based, default 1) and page_size (default 20, values above 100 are clamped to 100); has_more tells whether a further page exists. Labels (status, procedure, tender_type) are returned in Turkish. tender_id values are opaque site tokens that are valid for the detail lookup; they are re-minted on each search, so do not compare them across calls — use ikn as the stable tender identity. One round trip plus a short human-verification handshake per call.
| Param | Type | Description |
|---|---|---|
| ikn | string | Exact tender registration number (İhale Kayıt Numarası) in the form YYYY/NNNNNN, as returned in results[*].ikn. |
| page | integer | 1-based page number. |
| sort | string | Result ordering. |
| query | string | Free-text search matched against tender titles (e.g. bilgisayar). |
| page_size | integer | Results per page; values above 100 are clamped to 100. |
| status_ids | string | Comma-separated tender status ids from list_filter_options.statuses[*].id (e.g. 2,3). The scraper splits on commas — do NOT pass an array. Omitted = all statuses. |
| tender_type | string | Procurement category filter. Omitted = all categories. |
| province_ids | string | Comma-separated province ids from list_filter_options.provinces[*].id (e.g. 251,284). The scraper splits on commas — do NOT pass an array. Omitted = all provinces. |
| advert_date_to | string | Latest notice publication date, ISO date YYYY-MM-DD, inclusive. |
| tender_date_to | string | Latest tender (bid opening) date, ISO date YYYY-MM-DD, inclusive. |
| advert_date_from | string | Earliest notice publication date, ISO date YYYY-MM-DD, inclusive. |
| tender_date_from | string | Earliest tender (bid opening) date, ISO date YYYY-MM-DD, inclusive. |
{
"type": "object",
"fields": {
"page": "integer, the page returned",
"total": "integer, total tenders matching the filters across all pages",
"results": "array of tender summaries: tender_id (opaque detail key), ikn (stable registration number), title, tender_type_code/tender_type (1 Mal=goods, 2 Yapım=works, 3 Hizmet=services), procedure, procedure_sub_clause, exception_procedure, status_code/status, contracting_authority, province, tender_datetime (DD.MM.YYYY HH:MM, Turkey local time), has_notice, document_count",
"has_more": "boolean, whether page+1 exists",
"page_size": "integer, effective page size after clamping"
},
"sample": {
"data": {
"page": 1,
"total": 13454,
"results": [
{
"ikn": "2026/1637364",
"title": "Makine-Teçhizat, Laboratuvar Cihazları ile Bilgisayar ve Diğer Ekipmanların Alınımı",
"status": "İhale İlanı Yayımlanmış, Katılıma Açık",
"province": "NİĞDE",
"procedure": "İhale Usulü: Açık",
"tender_id": "f67201be58c9522a8be57548730d7b9d0477b754b9ed17db9052a16b77b36a29",
"has_notice": true,
"status_code": "2",
"tender_type": "Mal",
"document_count": 0,
"tender_datetime": "02.10.2026 10:30",
"tender_type_code": "1",
"exception_procedure": null,
"procedure_sub_clause": null,
"contracting_authority": "NİĞDE ÖMER HALİSDEMİR ÜNİVERSİTESİ REKTÖRLÜĞÜ İDARİ VE MALİ İŞLER DAİRE BAŞKANLIĞI"
}
],
"has_more": true,
"page_size": 5
},
"status": "success"
}
}About the Gov API
What the API covers
The EKAP API surfaces Turkey's central public procurement registry, operated by the Public Procurement Authority (KİK). The search_tenders endpoint queries roughly 2 million tenders since 2002 and returns paginated summaries — each result includes an ikn (İhale Kayıt Numarası in YYYY/NNNNNN format), title, tender_type, status, and an opaque tender_id used to fetch full records. Page size is capped at 100 per request.
Filtering and vocabularies
Filters on search_tenders are all optional and combinable: query matches tender titles, province_ids accepts comma-separated integers from the provinces array in list_filter_options, and status_ids narrows by tender lifecycle stage. The list_filter_options endpoint returns every vocabulary the search accepts in one call: 81 provinces with their IDs, tender statuses with Turkish and English labels, offer types, advert (notice) types, sort keys, and the three top-level tender_types. Resolve IDs here before constructing search requests.
Tender detail records
get_tender_details takes the tender_id from a search result and returns the complete public record. Key fields include procedure, legal_scope (e.g. "4734 Kapsamında"), cpv_items (CPV/OKAS classification codes and names), a notices array with each notice's title, published_date, notice_text, and notice_html, a features array of flag keys such as TENDER_DETAIL.E_IHALE, and a contracts array that populates once a contract is signed. Cancellation information is included when the tender status reflects cancellation.
Coverage notes
All data reflects what is publicly published on EKAP. Tender records span procurement under Turkish law 4734 and related legislation. Notice text is available in Turkish as rendered on the platform. The status_code field in detail responses matches the id values in list_filter_options.statuses, making it straightforward to map statuses across endpoints.
The Gov API is a managed, monitored endpoint for ekapv2.kik.gov.tr — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when ekapv2.kik.gov.tr changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official ekapv2.kik.gov.tr API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Monitor newly published tenders in a specific province by polling
search_tenderswithprovince_idsfiltered to a target region. - Build a tender alert system that checks for status changes on tracked
iknvalues usingget_tender_details. - Aggregate CPV/OKAS category data from
cpv_itemsto analyze procurement spending patterns by sector. - Retrieve full notice texts from the
noticesarray inget_tender_detailsto track amendments or cancellation notices. - Cross-reference signed contract records from
contractswith original tender data to study award outcomes. - Populate a localized UI with Turkish and English status labels sourced from
list_filter_options.statuses. - Identify e-tender opportunities by filtering
featuresfor theTENDER_DETAIL.E_IHALEflag across search results.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does EKAP have an official developer API?+
What does `get_tender_details` return beyond what `search_tenders` includes?+
search_tenders returns summary fields: ikn, title, tender_type, status, and tender_id. get_tender_details adds CPV/OKAS items (cpv_items), the full notices array (each with notice_text and notice_html), procedure, legal_scope, contracting authority contact details, a features flag array, signed contracts, and cancellation information when applicable.Can I retrieve tender documents or attached files through this API?+
How does pagination work in `search_tenders`?+
page parameter is 1-based, page_size values above 100 are clamped to 100, and the response includes a total count of all matching tenders and a has_more boolean indicating whether a next page exists. With no filters applied, results are sorted newest-first by tender date.Does the API cover tenders under all Turkish procurement laws, including defence or concession contracts outside law 4734?+
legal_scope field in get_tender_details indicates the applicable legal framework (e.g. "4734 Kapsamında"), but procurement processes conducted outside EKAP's public registry — such as certain defence or utilities contracts — are not represented. You can fork this API on Parse and revise it to target any supplementary KİK data sources that cover those categories.