Docs
View as Markdown

eurostat.tourism_spend

stable Standard

Tourism trip spending by residents of up to 10 European countries plus the EU27 aggregate, by trip purpose, duration and destination, annual, as a JSON-stat cube.

GET /v1/eurostat/tourism_spend

What you get#

One Eurostat record in Onekey's unified shape, in data. If the record does not exist you get a 404 not_found and are not charged.

What it costs#

  • Standard · 1 credit for a fresh fetch, charged only when it succeeds.
  • Free when served from cache (0.2 credit for a cached response over 100 KB).
  • Free if the request is invalid (never charged) or the source fails or reports not found (refunded).

Parameters#

NameTypeRequiredDefaultWhat it isConstraints
geostringnoEU27_2020Reporting country codes joined by + (URL-encode it as %2B), up to 11: two-letter Eurostat codes (DE, FR, EL for Greece...) and/or EU27_2020, e.g. DE%2BFR%2BEU27_2020max 120 chars; must match (?:[A-Z]{2}|EU27_2020)(?:\+(?:[A-Z]{2}|EU27_2020)){0,10}; trimmed, upper
purposestringnoTOTALTrip purpose: TOTAL, PER (personal), PER_HOL (holidays and leisure), PER_VFR (visiting friends and relatives), PER_OTH (other personal), PROF (professional, business)max 8 chars; must match TOTAL|PER|PER_HOL|PER_VFR|PER_OTH|PROF; trimmed, upper
destinationstringnoWORLDMain destination: WORLD (all), DOM (domestic), FOR (abroad), EU27_2020_FOR (other EU27 countries), NEU27_2020_FOR (outside the EU27)max 14 chars; must match WORLD|DOM|FOR|EU27_2020_FOR|NEU27_2020_FOR; trimmed, upper
durationstringnoN_GE1Trip length: N_GE1 (1 night or more), N1-3 (1 to 3 nights), N_GE4 (4 nights or more)max 5 chars; must match N_GE1|N1-3|N_GE4; trimmed, upper
measurestringnoTOTALMeasure (euro): TOTAL (total spending), AVG_TRP (average per trip), AVG_NGT (average per night)max 7 chars; must match TOTAL|AVG_TRP|AVG_NGT; trimmed, upper
startstringno2015First year (YYYY)max 4 chars; must match (?:19[5-9]\d|20\d{2}); trimmed
endstringno2100Last year (YYYY); the default 2100 means the latest year publishedmax 4 chars; must match (?:19[5-9]\d|20\d{2}|2100); trimmed

Request#

curl "https://api.onekey.dev/v1/eurostat/tourism_spend?geo=DE%2BFR%2BEU27_2020&purpose=PER_HOL&start=2020" \
  -H "x-api-key: YOUR_API_KEY"

Try it

Add your key to run this call right here. No key? Get one free. The key stays in this tab.

Recorded response#

A real Eurostat response, recorded and returned in Onekey's shape. Fields the platform does not provide are null.

json
{
  "success": true,
  "data": {
    "entity": {
      "name": "Expenditure by purpose of the trip"
    },
    "ext": {
      "updated": "2026-10-08T23:00:00+0200",
      "dimensions": [
        "freq",
        "purpose",
        "duration",
        "c_dest",
        "statinfo",
        "unit",
        "geo",
        "time"
      ],
      "size": [
        1,
        1,
        1,
        1,
        1,
        1,
        3,
        6
      ],
      "values": {
        "0": 140259833396,
        "1": 192244962467,
        "2": 322669169183,
        "3": 371383751393,
        "4": 418754854019,
        "5": 439164477520,
        "6": 39514945647,
        "7": 59317925968,
        "8": 107160350040,
        "9": 122007865612,
        "10": 145860445562,
        "11": 136351310466,
        "12": 34117071809,
        "13": 40031650434,
        "14": 57559667438,
        "15": 66277409387,
        "16": 65004893822,
        "17": 67706433858
      },
      "flags": {
        "3": "e"
      },
      "geo": {
        "index": {
          "EU27_2020": 0,
          "DE": 1,
          "FR": 2
        },
        "label": {
          "EU27_2020": "European Union - 27 countries (from 2020)",
          "DE": "Germany",
          "FR": "France"
        }
      },
      "time": {
        "index": {
          "2020": 0,
          "2021": 1,
          "2022": 2,
          "2023": 3,
          "2024": 4,
          "2025": 5
        },
        "label": {
          "2020": "2020",
          "2021": "2021",
          "2022": "2022",
          "2023": "2023",
          "2024": "2024",
          "2025": "2025"
        }
      },
      "purpose": {
        "index": {
          "PER_HOL": 0
        },
        "label": {
          "PER_HOL": "Holidays, leisure and recreation"
        }
      },
      "destination": {
        "index": {
          "WORLD": 0
        },
        "label": {
          "WORLD": "All countries of the world"
        }
      },
      "duration": {
        "index": {
          "N_GE1": 0
        },
        "label": {
          "N_GE1": "1 night or over"
        }
      },
      "measure": {
        "index": {
          "TOTAL": 0
        },
        "label": {
          "TOTAL": "Total"
        }
      }
    }
  },
  "metadata": {
    "platform": "eurostat",
    "endpoint": "tourism_spend",
    "cached": false,
    "stale": false,
    "age_s": 0,
    "fetched_at": "2026-01-01T12:00:00+00:00",
    "credits_charged": 1,
    "request_id": "7f3a9c2e5b1d4c8fa2e6d0b9c4f18e37"
  },
  "error": null
}

Field mapping#

How this endpoint's source fields become Onekey's unified schema. Fields the source lacks come back as null.

Source pathOnekey fieldTransform
labelentity.name-
updatedext.updated-
idext.dimensions-
sizeext.size-
valueext.values-
statusext.flags-
dimension.geo.categoryext.geo-
dimension.time.categoryext.time-
dimension.purpose.categoryext.purpose-
dimension.c_dest.categoryext.destination-
dimension.duration.categoryext.duration-
dimension.statinfo.categoryext.measure-

Caching and freshness#

  • Fresh for about 6 hours. Repeat calls in that window are served from cache and are free.
  • Between 6 hours and 7 days the cached copy is still served instantly and marked stale: true while Onekey refreshes it in the background.
  • If the source is down when a refresh is needed, the last copy can be served for up to 7 days more (marked stale).
  • A "not found" is remembered for 1 hour and is free.
  • The cache is shared across all customers, which is what keeps repeat calls cheap.

What can go wrong#

StatusCodeWhat to do
401unauthorizedCheck the x-api-key header.
402insufficient_creditsAdd credits; your balance must cover the price.
404not_foundThat record does not exist. Free; do not retry.
422invalid_paramsFix the parameters using the table above. Free.
429rate_limitedWait Retry-After seconds, then retry.
502upstream_errorThe source failed. Refunded; retry with backoff.

See Errors for the full list and retry guidance.

Status: stable (verified against the live source).