Skip to content

Tourism and border

GET /v1/border/arrivals returns foreign visitor entries to Türkiye from the border statistics of the Ministry of Culture and Tourism (full count at the border gates). It counts entries, not distinct people: a person who enters twice is counted twice. The default query gives the monthly number of Russian entries.

curl -s -H "Authorization: Bearer $TRRU_KEY" \
  "https://trru.atapinar.com/v1/border/arrivals?freq=M&year_from=2025&year_to=2025"

Parameters

Parameter Type Default Meaning
nationality string Rusya Fed. Nationality exactly as published, in Turkish: Rusya Fed. (Russia), Beyaz Rusya (Belarus), Ukrayna, Almanya, and so on. * means all foreigners. Exact match, case-sensitive. An empty value (nationality=) removes the filter and returns every nationality, so rows from many countries are mixed. A name that is not a published value (for example Rusya) returns no rows, not an error.
gate string empty Border gate, case-insensitive substring match. Names carry a type suffix: Antalya Merkez (H).
province string empty Province, case-insensitive substring match: Antalya, İstanbul.
transport string empty hava (air), deniz (sea), kara (road), demiryolu (rail). Lower-cased by the server.
freq string empty M monthly or Y yearly (case-insensitive). Empty returns both, if both exist for the cut.
year_from integer 0 First calendar year to include. 0 means no lower bound.
year_to integer 0 Last calendar year to include (inclusive). 0 means no upper bound.
limit integer 200 Maximum rows, capped at 2000 (larger values are clamped). Rows are ordered by freq, period, then visitors descending, so the cut keeps the oldest periods first.

The gate suffix is the type: (H) air (hava), (D) sea (deniz), (K) road (kara), (T) rail (demiryolu). gate=Antalya matches every Antalya gate, gate=Sarp matches Sarp (K). The match ignores case and the dotted İ, so Istanbul, istanbul and İstanbul all match İstanbul Yeni Havalimanı (H). Abbreviated names exist (S. Gökçen (H) for Sabiha Gökçen), so search for a fragment you can see in the names.

What data exists: the default and the cuts

The table has four cuts. What you get depends on which of gate, province, transport you set.

You want Parameters Rows you get
Monthly total for a nationality (default) nationality=..., no gate, province or transport freq=M, gate and transport empty. Russia: monthly, January 2016 to the latest month (129 rows at the time of writing).
Yearly entries by mode of transport nationality=...&transport=hava&freq=Y freq=Y, one row per year, gate empty.
Yearly entries by gate nationality=...&gate=Antalya&freq=Y (or province=...) freq=Y, one row per gate and year.
Monthly entries by gate for all foreigners nationality=*&gate=Antalya&freq=M freq=M, one row per gate and month, 2016 to 2025.

Default totals are monthly only

With no gate, province or transport, the API returns country totals (gate and transport empty) and those exist only monthly. freq=Y alone returns nothing: there is no yearly total row. Get a yearly total by summing the 12 monthly rows, or by summing the four yearly transport rows. For Russia in 2024 both give 6,710,198.

Yearly rows exist per gate and per transport; for Russians they are available up to 2025, while monthly totals run to the latest published month. Other combinations are simply empty, for example Russians by gate by month (gate=Antalya&freq=M with the default nationality), or all foreigners by transport by month.

How to get yearly gate-level numbers

Pass gate (or province) and freq=Y:

# Russians entering through Antalya airport, per year, from 2023
curl -s -H "Authorization: Bearer $TRRU_KEY" \
  "https://trru.atapinar.com/v1/border/arrivals?gate=Antalya&freq=Y&transport=hava&year_from=2023"

# every gate in Antalya province, 2025
curl -s -H "Authorization: Bearer $TRRU_KEY" \
  "https://trru.atapinar.com/v1/border/arrivals?province=Antalya&freq=Y&year_from=2025&year_to=2025"
body = get("/v1/border/arrivals", province="Antalya", freq="Y", year_from=2025, year_to=2025)
for r in body["data"]["rows"]:
    print(r["gate"], r["transport"], r["visitors"])
const body = await get("/v1/border/arrivals", { province: "Antalya", freq: "Y", year_from: "2025", year_to: "2025" });
for (const r of body.data.rows) console.log(r.gate, r.transport, r.visitors);

For 2025 this returns eight Antalya gates for Russians, the largest being Antalya Merkez (H) with 3,964,846 and Gazipaşa (H) with 67,468 entries.

Example: monthly totals

Request: GET /v1/border/arrivals?freq=M&year_from=2025&year_to=2025&limit=3

{
  "data": {
    "rows": [
      { "freq": "M", "period": "2025-01-01", "nationality": "Rusya Fed.", "province": "", "gate": "", "transport": "", "visitors": 203733 },
      { "freq": "M", "period": "2025-02-01", "nationality": "Rusya Fed.", "province": "", "gate": "", "transport": "", "visitors": 167611 },
      { "freq": "M", "period": "2025-03-01", "nationality": "Rusya Fed.", "province": "", "gate": "", "transport": "", "visitors": 229988 }
    ],
    "row_count": 3,
    "truncated": false
  },
  "meta": {
    "sources": [
      { "source_id": "ktb_border", "fetched_at": "2026-11-13T09:50:04.503063+00:00", "as_of": "2025-03-01" }
    ],
    "request_id": "13700d42532e4d93abbc1239fc01f4c1",
    "truncated": false
  }
}

meta.sources[].as_of is the newest period in the rows you received (here March 2025 because of limit=3), not the newest data held. To find the latest month, request year_from as the current year.

Example: yearly by gate

Request: GET /v1/border/arrivals?gate=Antalya&freq=Y&transport=hava&year_from=2023&limit=3

{
  "data": {
    "rows": [
      { "freq": "Y", "period": "2023-01-01", "nationality": "Rusya Fed.", "province": "Antalya", "gate": "Antalya Merkez (H)", "transport": "hava", "visitors": 3421620 },
      { "freq": "Y", "period": "2024-01-01", "nationality": "Rusya Fed.", "province": "Antalya", "gate": "Antalya Merkez (H)", "transport": "hava", "visitors": 3851695 },
      { "freq": "Y", "period": "2025-01-01", "nationality": "Rusya Fed.", "province": "Antalya", "gate": "Antalya Merkez (H)", "transport": "hava", "visitors": 3964846 }
    ],
    "row_count": 3,
    "truncated": false
  },
  "meta": {
    "sources": [
      { "source_id": "ktb_border", "fetched_at": "2026-11-13T09:50:04.503063+00:00", "as_of": "2025-01-01" }
    ],
    "request_id": "71d10f9522674550987740721724c911",
    "truncated": false
  }
}

Russian entries through Antalya airport rose from 3.42 M (2023) to 3.85 M (2024, +12.6%) and 3.96 M (2025, +2.9%).

Field notes

Field Meaning
freq M monthly or Y yearly.
period First day of the month (M) or of the year (Y): 2025-01-01 with freq=Y is the whole of 2025.
nationality As published, Turkish. * for all foreigners.
province Province of the gate. Empty on totals.
gate Border gate with type suffix. Empty on totals and on yearly transport rows.
transport hava, deniz, kara, demiryolu. Empty on monthly totals. A gate row carries its own transport.
visitors Number of entries of foreign visitors.

Errors and edge cases

Case Result
No rows match (unknown nationality, freq=Q, years outside the data, an impossible combination) 200, "rows": []. Check which cut you are asking for.
year_from=abc 400 invalid or missing parameter(s): year_from
limit=0 200 with no rows
meta.truncated true only if the 2000-row cap cut the result.

Tips

  • Cross-check yearly and monthly data: for Russia in 2024 the 12 monthly totals and the four yearly transport rows both sum to 6,710,198.
  • Seasonality is strong: Russian entries in 2026 range from 172 k in February to 1.05 M in August.
  • Macro series on tourism (for example revenue) are in /v1/series under category tourism.