openapi: 3.0.3 info: title: 'OpenVan.camp — Public API' description: 'Open data API for fuel prices, currency rates and vanlife events. Free to use with attribution (CC BY 4.0).' version: 1.0.0 servers: - url: 'https://openvan.camp' tags: - name: 'Currency Rates' description: '' - name: Endpoints description: '' - name: Events description: '' - name: 'Fuel Prices' description: '' - name: Stories description: "\nVanlife news stories — clustered and translated into 7 languages.\nEach story aggregates multiple source articles from different publishers." - name: 'VanBasket Food Price Index' description: "\nVanBasket Index shows how expensive food is in a country\nrelative to the world average (World = 100).\nBased on World Bank ICP 2021 data, adjusted with IMF CPI." - name: 'Visa & Border Rules' description: "\nHow long you may stay and how the days are counted — for all 199 × 199\npassport/destination pairs, plus temporary vehicle import rules.\n\nEvery answer carries `confidence` and `source_url`, and says which layer it\ncame from: `curated` (hand-verified), `window` (counting window applied on\ntop of the dataset), `zone` (Schengen-style shared counter) or `dataset`.\nTreat `confidence: low` as \"the number of days is right, the way they are\ncounted is an assumption\" — verify at the border." paths: /api/currency/rates: get: summary: 'Get currency rates' operationId: getCurrencyRates description: "Returns EUR-base exchange rates. By default the response is limited to ~165 ISO 4217\nactive fiat currencies that are realistic for travel/fuel-price use cases.\n\n**Source chain:** national central banks (RUB/TRY/GEL/UAH/BYN/UZS) for precision,\nthen Fawaz API / ExchangeRate-API / Frankfurter / ECB for the long tail.\n\n**Refresh:** Redis-backed cache stored `forever`; refreshed by cron every 6 hours.\nA separate hourly watchdog alerts in Telegram if cache > 25h old.\n\n**HTTP cache:** `Cache-Control: public, max-age=1800` (edge `X-Accel-Expires: 1800`).\nEdge кеш 30 минут — соответствует фактической частоте обновления (раз в 6 часов).\nNote: PHP-уровневый Cache-Control затирается nginx через `fastcgi_hide_header` +\n`cache-control-map.conf`, поэтому фактический header в ответе всегда задаётся nginx.\n\n**Query parameters:**\n- `include=all` — return the raw upstream set (~340 codes), including crypto, metals\n and historical/legacy codes (BTC, ETH, USDT, XAU, ATS, DEM, VEF, TRL, ZWL, etc.).\n Without this parameter, those are filtered out.\n\n**Market overrides:** the `meta.overrides` field lists codes whose rate is a manual\nmarket-rate override rather than an official feed. Currently only **CUP** (Cuba uses\na parallel market rate of ~120 CUP/USD; the official fixing of ~24 CUP/USD does not\nreflect retail fuel pricing).\n\n**License:** CC BY 4.0 — free to use with attribution to [OpenVan.camp](https://openvan.camp)." parameters: [] responses: 200: description: Success content: application/json: schema: type: object example: success: true rates: EUR: 1 USD: 1.1641 GBP: 0.8729 RUB: 84.0742 TRY: 53.0915 GEL: 3.1146 meta: count: 165 base: EUR updated_at: '2026-05-19T12:24:28+00:00' refreshed_every_hours: 6 max_age_seconds: 90000 scope: fiat overrides: CUP: reason: dual_exchange_rate source: market_rate_120_cup_per_usd note: 'Куба: официальный фиксинг ~24 CUP/USD расходится с реальным рынком ~120 CUP/USD.' properties: success: type: boolean example: true rates: type: object properties: EUR: type: integer example: 1 USD: type: number example: 1.1641 GBP: type: number example: 0.8729 RUB: type: number example: 84.0742 TRY: type: number example: 53.0915 GEL: type: number example: 3.1146 meta: type: object properties: count: type: integer example: 165 base: type: string example: EUR updated_at: type: string example: '2026-05-19T12:24:28+00:00' refreshed_every_hours: type: integer example: 6 max_age_seconds: type: integer example: 90000 scope: type: string example: fiat overrides: type: object properties: CUP: type: object properties: reason: type: string example: dual_exchange_rate source: type: string example: market_rate_120_cup_per_usd note: type: string example: 'Куба: официальный фиксинг ~24 CUP/USD расходится с реальным рынком ~120 CUP/USD.' tags: - 'Currency Rates' security: [] /api/route-cost: post: summary: '' operationId: postApiRouteCost description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: waypoints: type: array description: 'Названия 2–10 точек.' example: - Волгоград - Грузия - Анталия items: type: string tank: type: number description: 'Объём бака, л.' example: 80.0 nullable: true cons: type: number description: 'Расход, л/100 км.' example: 10.0 nullable: true fuel: type: string description: diesel|gasoline|lpg. example: diesel nullable: true currency: type: string description: 'ISO 4217.' example: RUB nullable: true locale: type: string description: 'Язык названий стран.' example: ru nullable: true required: - waypoints security: [] /api/vansky/weather: get: summary: 'VanSky weather for all countries' operationId: vanSkyWeatherForAllCountries description: 'Все страны — сводные данные для таблицы / карты. Ответ ~900 КБ, кешируется на 1 час.' parameters: [] responses: 200: description: 'Success (truncated)' content: application/json: schema: type: object example: data: - country_code: DE country_slug: germany van_score: 90 temp_day: 24.1 temp_night: 14.3 solar_kwh: 2.8 sea_temp: 18.2 is_coastal: true label: ideal count: 155 updated_at: '2026-07-15T02:00:00+03:00' source: 'Open-Meteo (api.open-meteo.com)' properties: data: type: array example: - country_code: DE country_slug: germany van_score: 90 temp_day: 24.1 temp_night: 14.3 solar_kwh: 2.8 sea_temp: 18.2 is_coastal: true label: ideal items: type: object properties: country_code: type: string example: DE country_slug: type: string example: germany van_score: type: integer example: 90 temp_day: type: number example: 24.1 temp_night: type: number example: 14.3 solar_kwh: type: number example: 2.8 sea_temp: type: number example: 18.2 is_coastal: type: boolean example: true label: type: string example: ideal count: type: integer example: 155 updated_at: type: string example: '2026-07-15T02:00:00+03:00' source: type: string example: 'Open-Meteo (api.open-meteo.com)' tags: - Endpoints security: [] '/api/vansky/weather/{code}': get: summary: 'VanSky weather for one country' operationId: vanSkyWeatherForOneCountry description: 'Подробные данные одной страны (ISO 3166-1 alpha-2).' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: code: DE marine: sea_temp: 19.5 wave_dir: 295 swell_dir: 247 wave_height: 1.54 wave_period: 4.6 swell_height: 0 swell_period: 5.8 wind_wave_dir: 295 wind_wave_height: 1.54 wind_wave_period: 4.6 region: europe weather: sunset: '2026-07-26T18:58' uv_max: null sunrise: '2026-07-26T03:41' humidity: 65 temp_day: 26.5 wind_dir: 240 wind_max: 15.7 dew_point: 12.6 precip_sum: 0.2 temp_night: 18.4 cloud_cover: 75 temp_current: 19.4 weather_code: 51 feels_like_day: 25.3 peak_sun_hours: 4.7 sunshine_hours: 11.4 wind_gusts_max: 37.4 precip_prob_max: 0 feels_like_night: 18 feels_like_current: 18.9 shortwave_radiation_sum: 16.89 forecast: - date: '2026-07-26' temp_day: 26.5 solar_kwh: 2.1 van_score: 97 temp_night: 18.4 drive_score: 100 score_label: ideal sleep_score: 97 weather_code: 51 - date: '2026-07-27' temp_day: 25.5 solar_kwh: 2.1 van_score: 94 temp_night: 16.8 drive_score: 99 score_label: ideal sleep_score: 95 weather_code: 2 - date: '2026-07-28' temp_day: 28.4 solar_kwh: 2.8 van_score: 73 temp_night: 14 drive_score: 100 score_label: comfortable sleep_score: 88 weather_code: 0 - date: '2026-07-29' temp_day: 33.1 solar_kwh: 2.8 van_score: 53 temp_night: 16.8 drive_score: 100 score_label: acceptable sleep_score: 89 weather_code: 51 - date: '2026-07-30' temp_day: 36.2 solar_kwh: 2.7 van_score: 82 temp_night: 19.7 drive_score: 94 score_label: ideal sleep_score: 95 weather_code: 1 - date: '2026-07-31' temp_day: 33.7 solar_kwh: 2.2 van_score: 95 temp_night: 20.7 drive_score: 100 score_label: ideal sleep_score: 93 weather_code: 51 - date: '2026-08-01' temp_day: 28.8 solar_kwh: 2.3 van_score: 90 temp_night: 19 drive_score: 98 score_label: ideal sleep_score: 84 weather_code: 61 sea_score: null solar_kwh: 2.1 van_score: 97 confidence: high fetched_at: '2026-07-26T23:22:45.181608Z' is_coastal: true week_score: 69 band_counts: hard: 0 ideal: 33 extreme: 0 acceptable: 473 comfortable: 1269 drive_score: 100 score_label: ideal sleep_score: 96 solar_score: 46 drive_window: null awning_status: caution best_move_day: date: '2026-07-26' temp_day: 26.5 solar_kwh: 2.1 van_score: 93 temp_night: 18.4 drive_score: 100 score_label: ideal sleep_score: 97 weather_code: 51 sample_points: 1775 typical_score: 65 ideal_coverage: 0 sample_regions: 16 best_area_score: 72 recommendations: - key: vansky.rec.awning_caution type: warning params: gusts: 37.4 - key: vansky.rec.night_ideal type: success params: temp: 19.1 - key: vansky.rec.day_comfortable type: success params: temp: 24.7 condensation_risk: low aggregation_version: 2 comfortable_coverage: 81 updated_at: '2026-07-27T02:23:24+03:00' source: 'Open-Meteo (api.open-meteo.com)' properties: data: type: object properties: code: type: string example: DE marine: type: object properties: sea_temp: type: number example: 19.5 wave_dir: type: integer example: 295 swell_dir: type: integer example: 247 wave_height: type: number example: 1.54 wave_period: type: number example: 4.6 swell_height: type: integer example: 0 swell_period: type: number example: 5.8 wind_wave_dir: type: integer example: 295 wind_wave_height: type: number example: 1.54 wind_wave_period: type: number example: 4.6 region: type: string example: europe weather: type: object properties: sunset: type: string example: '2026-07-26T18:58' uv_max: type: string example: null nullable: true sunrise: type: string example: '2026-07-26T03:41' humidity: type: integer example: 65 temp_day: type: number example: 26.5 wind_dir: type: integer example: 240 wind_max: type: number example: 15.7 dew_point: type: number example: 12.6 precip_sum: type: number example: 0.2 temp_night: type: number example: 18.4 cloud_cover: type: integer example: 75 temp_current: type: number example: 19.4 weather_code: type: integer example: 51 feels_like_day: type: number example: 25.3 peak_sun_hours: type: number example: 4.7 sunshine_hours: type: number example: 11.4 wind_gusts_max: type: number example: 37.4 precip_prob_max: type: integer example: 0 feels_like_night: type: integer example: 18 feels_like_current: type: number example: 18.9 shortwave_radiation_sum: type: number example: 16.89 forecast: type: array example: - date: '2026-07-26' temp_day: 26.5 solar_kwh: 2.1 van_score: 97 temp_night: 18.4 drive_score: 100 score_label: ideal sleep_score: 97 weather_code: 51 - date: '2026-07-27' temp_day: 25.5 solar_kwh: 2.1 van_score: 94 temp_night: 16.8 drive_score: 99 score_label: ideal sleep_score: 95 weather_code: 2 - date: '2026-07-28' temp_day: 28.4 solar_kwh: 2.8 van_score: 73 temp_night: 14 drive_score: 100 score_label: comfortable sleep_score: 88 weather_code: 0 - date: '2026-07-29' temp_day: 33.1 solar_kwh: 2.8 van_score: 53 temp_night: 16.8 drive_score: 100 score_label: acceptable sleep_score: 89 weather_code: 51 - date: '2026-07-30' temp_day: 36.2 solar_kwh: 2.7 van_score: 82 temp_night: 19.7 drive_score: 94 score_label: ideal sleep_score: 95 weather_code: 1 - date: '2026-07-31' temp_day: 33.7 solar_kwh: 2.2 van_score: 95 temp_night: 20.7 drive_score: 100 score_label: ideal sleep_score: 93 weather_code: 51 - date: '2026-08-01' temp_day: 28.8 solar_kwh: 2.3 van_score: 90 temp_night: 19 drive_score: 98 score_label: ideal sleep_score: 84 weather_code: 61 items: type: object properties: date: type: string example: '2026-07-26' temp_day: type: number example: 26.5 solar_kwh: type: number example: 2.1 van_score: type: integer example: 97 temp_night: type: number example: 18.4 drive_score: type: integer example: 100 score_label: type: string example: ideal sleep_score: type: integer example: 97 weather_code: type: integer example: 51 sea_score: type: string example: null nullable: true solar_kwh: type: number example: 2.1 van_score: type: integer example: 97 confidence: type: string example: high fetched_at: type: string example: '2026-07-26T23:22:45.181608Z' is_coastal: type: boolean example: true week_score: type: integer example: 69 band_counts: type: object properties: hard: type: integer example: 0 ideal: type: integer example: 33 extreme: type: integer example: 0 acceptable: type: integer example: 473 comfortable: type: integer example: 1269 drive_score: type: integer example: 100 score_label: type: string example: ideal sleep_score: type: integer example: 96 solar_score: type: integer example: 46 drive_window: type: string example: null nullable: true awning_status: type: string example: caution best_move_day: type: object properties: date: type: string example: '2026-07-26' temp_day: type: number example: 26.5 solar_kwh: type: number example: 2.1 van_score: type: integer example: 93 temp_night: type: number example: 18.4 drive_score: type: integer example: 100 score_label: type: string example: ideal sleep_score: type: integer example: 97 weather_code: type: integer example: 51 sample_points: type: integer example: 1775 typical_score: type: integer example: 65 ideal_coverage: type: integer example: 0 sample_regions: type: integer example: 16 best_area_score: type: integer example: 72 recommendations: type: array example: - key: vansky.rec.awning_caution type: warning params: gusts: 37.4 - key: vansky.rec.night_ideal type: success params: temp: 19.1 - key: vansky.rec.day_comfortable type: success params: temp: 24.7 items: type: object properties: key: type: string example: vansky.rec.awning_caution type: type: string example: warning params: type: object properties: gusts: type: number example: 37.4 condensation_risk: type: string example: low aggregation_version: type: integer example: 2 comfortable_coverage: type: integer example: 81 updated_at: type: string example: '2026-07-27T02:23:24+03:00' source: type: string example: 'Open-Meteo (api.open-meteo.com)' 404: description: 'Not found' content: application/json: schema: type: object example: error: 'Country not found or not supported' properties: error: type: string example: 'Country not found or not supported' tags: - Endpoints security: [] parameters: - in: path name: code description: 'ISO 3166-1 alpha-2 код страны.' example: DE required: true schema: type: string /api/events: get: summary: 'List events' operationId: listEvents description: "Returns a paginated list of vanlife events (exhibitions, festivals, meetups, road trips).\nFilter by status, type, country, or search by name." parameters: - in: query name: locale description: 'Language code for localized names. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en required: false schema: type: string description: 'Language code for localized names. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en - in: query name: status description: 'Filter by event status. One of: `upcoming`, `ongoing`, `past`, `all`. Defaults to `upcoming`.' example: upcoming required: false schema: type: string description: 'Filter by event status. One of: `upcoming`, `ongoing`, `past`, `all`. Defaults to `upcoming`.' example: upcoming - in: query name: type description: 'Filter by event type. One of: `expo`, `festival`, `forum`, `meetup`, `roadtrip`.' example: festival required: false schema: type: string description: 'Filter by event type. One of: `expo`, `festival`, `forum`, `meetup`, `roadtrip`.' example: festival - in: query name: country description: '2-letter ISO country code.' example: DE required: false schema: type: string description: '2-letter ISO country code.' example: DE - in: query name: search description: 'Text search by event name.' example: 'Adventure Northside' required: false schema: type: string description: 'Text search by event name.' example: 'Adventure Northside' - in: query name: page description: 'Page number. Defaults to 1.' example: 1 required: false schema: type: integer description: 'Page number. Defaults to 1.' example: 1 - in: query name: limit description: 'Results per page (max 100). Defaults to 30.' example: 30 required: false schema: type: integer description: 'Results per page (max 100). Defaults to 30.' example: 30 responses: 200: description: Success content: application/json: schema: type: object example: events: - id: 960 slug: adventure-northside-2026 event_name: 'Adventure Northside 2026' event_type: festival event_type_emoji: 🎉 start_date: '2026-09-18' end_date: '2026-09-20' city: Basthorst country_code: DE country: code: de slug: germany name: Germany flag_emoji: 🇩🇪 status: upcoming url: 'https://openvan.camp/en/event/adventure-northside-2026' pagination: total: 48 page: 1 limit: 30 pages: 2 properties: events: type: array example: - id: 960 slug: adventure-northside-2026 event_name: 'Adventure Northside 2026' event_type: festival event_type_emoji: 🎉 start_date: '2026-09-18' end_date: '2026-09-20' city: Basthorst country_code: DE country: code: de slug: germany name: Germany flag_emoji: 🇩🇪 status: upcoming url: 'https://openvan.camp/en/event/adventure-northside-2026' items: type: object properties: id: type: integer example: 960 slug: type: string example: adventure-northside-2026 event_name: type: string example: 'Adventure Northside 2026' event_type: type: string example: festival event_type_emoji: type: string example: 🎉 start_date: type: string example: '2026-09-18' end_date: type: string example: '2026-09-20' city: type: string example: Basthorst country_code: type: string example: DE country: type: object properties: code: type: string example: de slug: type: string example: germany name: type: string example: Germany flag_emoji: type: string example: 🇩🇪 status: type: string example: upcoming url: type: string example: 'https://openvan.camp/en/event/adventure-northside-2026' pagination: type: object properties: total: type: integer example: 48 page: type: integer example: 1 limit: type: integer example: 30 pages: type: integer example: 2 tags: - Events security: [] '/api/event/{slug}': get: summary: 'Get event details' operationId: getEventDetails description: 'Returns full details for a single vanlife event by slug, including location, description, and social links.' parameters: - in: query name: locale description: 'Language for localized content. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`.' example: en required: false schema: type: string description: 'Language for localized content. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`.' example: en responses: 200: description: Success content: application/json: schema: type: object example: id: 960 slug: adventure-northside-2026 event_name: 'Adventure Northside 2026' event_type: festival event_type_emoji: 🎉 start_date: '2026-09-18' end_date: '2026-09-20' city: Basthorst country_code: DE description: "Northern Germany's Overland & Self-build expo and festival..." official_url: 'https://adventurenorthside.de/' image_url: 'https://...' status: upcoming url: 'https://openvan.camp/en/event/adventure-northside-2026' properties: id: type: integer example: 960 slug: type: string example: adventure-northside-2026 event_name: type: string example: 'Adventure Northside 2026' event_type: type: string example: festival event_type_emoji: type: string example: 🎉 start_date: type: string example: '2026-09-18' end_date: type: string example: '2026-09-20' city: type: string example: Basthorst country_code: type: string example: DE description: type: string example: "Northern Germany's Overland & Self-build expo and festival..." official_url: type: string example: 'https://adventurenorthside.de/' image_url: type: string example: 'https://...' status: type: string example: upcoming url: type: string example: 'https://openvan.camp/en/event/adventure-northside-2026' 404: description: 'Not found' content: application/json: schema: type: object example: message: 'No query results for model [App\Models\Event].' properties: message: type: string example: 'No query results for model [App\Models\Event].' tags: - Events security: [] parameters: - in: path name: slug description: 'The event slug.' example: adventure-northside-2026 required: true schema: type: string '/api/event/{slug}/articles': get: summary: 'Get event articles' operationId: getEventArticles description: "Returns source articles linked to this event.\nWhen `locale` is provided, attempts to return only articles in that language.\nIf no articles match the requested locale, **all articles are returned** as a fallback\n(they may be in the original source language, e.g. Japanese or German).\nThe `language` field on each article indicates the actual language of the source." parameters: - in: query name: locale description: 'Language code to filter articles by source language. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en required: false schema: type: string description: 'Language code to filter articles by source language. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en responses: 200: description: Success content: application/json: schema: type: array items: type: object properties: id: type: integer example: 1001 title: type: string example: 'Adventure Northside 2026 opens its doors' image_url: type: string example: 'https://...' published_at: type: string example: '2026-03-11T10:00:00+00:00' source_name: type: string example: 'CamperVan Magazine' original_url: type: string example: 'https://...' language: type: string example: en example: - id: 1001 title: 'Adventure Northside 2026 opens its doors' image_url: 'https://...' published_at: '2026-03-11T10:00:00+00:00' source_name: 'CamperVan Magazine' original_url: 'https://...' language: en tags: - Events security: [] parameters: - in: path name: slug description: 'The event slug.' example: adventure-northside-2026 required: true schema: type: string /api/fuel/prices: get: summary: 'Get fuel prices' operationId: getFuelPrices description: "Returns current retail fuel prices for all supported countries.\nPrice keys follow FuelGradeCatalog::ORDER plus the legacy `premium` alias.\nData is updated weekly from 45+ official government sources and independent aggregators.\n\nPrices are weighted averages from multiple sources per country. The `sources` array\nlists all contributing data providers (sorted by trust weight, highest first).\n\n**License:** CC BY 4.0 — free to use with attribution to [OpenVan.camp](https://openvan.camp)." parameters: [] responses: 200: description: Success content: application/json: schema: type: object example: success: true data: DE: country_code: DE country_name: Germany region: europe currency: EUR local_currency: EUR unit: liter prices: gasoline_regular: null gasoline: 2.1313 gasoline_premium: null gasoline_super: null diesel_regular: null diesel: 2.2845 diesel_premium: null lpg: 1.113 cng: null e85: null kerosene: null premium: null price_changes: gasoline_regular: null gasoline: -0.02 gasoline_premium: null gasoline_super: null diesel_regular: null diesel: 0.01 diesel_premium: null lpg: 0.0 cng: null e85: null kerosene: null premium: null fetched_at: '2026-06-29T11:12:55+00:00' sources: - Fuelo.net - 'EU Weekly Oil Bulletin' - Cargopedia.net sources_count: 3 is_excluded: false meta: total_countries: 135 updated_at: '2026-06-29 11:12:55' cache_ttl_hours: 6 properties: success: type: boolean example: true data: type: object properties: DE: type: object properties: country_code: type: string example: DE country_name: type: string example: Germany region: type: string example: europe currency: type: string example: EUR local_currency: type: string example: EUR unit: type: string example: liter prices: type: object properties: gasoline_regular: type: string example: null nullable: true gasoline: type: number example: 2.1313 gasoline_premium: type: string example: null nullable: true gasoline_super: type: string example: null nullable: true diesel_regular: type: string example: null nullable: true diesel: type: number example: 2.2845 diesel_premium: type: string example: null nullable: true lpg: type: number example: 1.113 cng: type: string example: null nullable: true e85: type: string example: null nullable: true kerosene: type: string example: null nullable: true premium: type: string example: null nullable: true price_changes: type: object properties: gasoline_regular: type: string example: null nullable: true gasoline: type: number example: -0.02 gasoline_premium: type: string example: null nullable: true gasoline_super: type: string example: null nullable: true diesel_regular: type: string example: null nullable: true diesel: type: number example: 0.01 diesel_premium: type: string example: null nullable: true lpg: type: number example: 0.0 cng: type: string example: null nullable: true e85: type: string example: null nullable: true kerosene: type: string example: null nullable: true premium: type: string example: null nullable: true fetched_at: type: string example: '2026-06-29T11:12:55+00:00' sources: type: array example: - Fuelo.net - 'EU Weekly Oil Bulletin' - Cargopedia.net items: type: string sources_count: type: integer example: 3 is_excluded: type: boolean example: false meta: type: object properties: total_countries: type: integer example: 135 updated_at: type: string example: '2026-06-29 11:12:55' cache_ttl_hours: type: integer example: 6 tags: - 'Fuel Prices' security: [] /api/stories: get: summary: 'List stories' operationId: listStories description: "Returns a paginated list of vanlife news stories in the requested language.\nTitles and summaries are translated; `sources` are original-language articles." parameters: - in: query name: locale description: 'Language for localized titles and summaries. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en required: false schema: type: string description: 'Language for localized titles and summaries. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en - in: query name: category description: 'Filter by category slug. One of: `lifestyle`, `industry`, `incident`, `opening`, `closing`, `law`, `builds`, `festival`, `expo`, `review`, `ban`, `other`.' example: festival required: false schema: type: string description: 'Filter by category slug. One of: `lifestyle`, `industry`, `incident`, `opening`, `closing`, `law`, `builds`, `festival`, `expo`, `review`, `ban`, `other`.' example: festival - in: query name: country description: '2-letter ISO country code to filter by associated country.' example: DE required: false schema: type: string description: '2-letter ISO country code to filter by associated country.' example: DE - in: query name: search description: 'Full-text search by story title.' example: 'vanlife festival' required: false schema: type: string description: 'Full-text search by story title.' example: 'vanlife festival' - in: query name: page description: 'Page number. Defaults to 1.' example: 1 required: false schema: type: integer description: 'Page number. Defaults to 1.' example: 1 - in: query name: limit description: 'Results per page (max 50). Defaults to 20.' example: 20 required: false schema: type: integer description: 'Results per page (max 50). Defaults to 20.' example: 20 responses: 200: description: Success content: application/json: schema: type: object example: stories: - slug: adac-camper-des-jahres-der-wettbewerb-fuer title: "ADAC launches 'Camper of the Year' competition for motorhome drivers" summary: "ADAC is holding the national 'Camper des Jahres 2026' competition for motorhome owners..." image_url: 'https://...' category: slug: festival name: Festivals countries: - code: de name: Germany flag_emoji: 🇩🇪 first_published_at: '2026-01-22T11:00:00+03:00' articles_count: 5 url: 'https://openvan.camp/en/news/festival/adac-camper-des-jahres-der-wettbewerb-fuer' pagination: total: 120 page: 1 limit: 20 pages: 6 properties: stories: type: array example: - slug: adac-camper-des-jahres-der-wettbewerb-fuer title: "ADAC launches 'Camper of the Year' competition for motorhome drivers" summary: "ADAC is holding the national 'Camper des Jahres 2026' competition for motorhome owners..." image_url: 'https://...' category: slug: festival name: Festivals countries: - code: de name: Germany flag_emoji: 🇩🇪 first_published_at: '2026-01-22T11:00:00+03:00' articles_count: 5 url: 'https://openvan.camp/en/news/festival/adac-camper-des-jahres-der-wettbewerb-fuer' items: type: object properties: slug: type: string example: adac-camper-des-jahres-der-wettbewerb-fuer title: type: string example: "ADAC launches 'Camper of the Year' competition for motorhome drivers" summary: type: string example: "ADAC is holding the national 'Camper des Jahres 2026' competition for motorhome owners..." image_url: type: string example: 'https://...' category: type: object properties: slug: type: string example: festival name: type: string example: Festivals countries: type: array example: - code: de name: Germany flag_emoji: 🇩🇪 items: type: object properties: code: type: string example: de name: type: string example: Germany flag_emoji: type: string example: 🇩🇪 first_published_at: type: string example: '2026-01-22T11:00:00+03:00' articles_count: type: integer example: 5 url: type: string example: 'https://openvan.camp/en/news/festival/adac-camper-des-jahres-der-wettbewerb-fuer' pagination: type: object properties: total: type: integer example: 120 page: type: integer example: 1 limit: type: integer example: 20 pages: type: integer example: 6 tags: - Stories security: [] '/api/story/{slug}': get: summary: 'Get story details' operationId: getStoryDetails description: "Returns full details for a single news story including all source articles.\nThe `sources` array contains original publisher articles with direct links." parameters: - in: query name: locale description: 'Language for localized title and summary. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en required: false schema: type: string description: 'Language for localized title and summary. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: en responses: 200: description: Success content: application/json: schema: type: object example: slug: adac-camper-des-jahres-der-wettbewerb-fuer title: "ADAC launches 'Camper of the Year' competition for motorhome drivers" summary: "ADAC is holding the national 'Camper des Jahres 2026' competition for motorhome owners..." image_url: 'https://...' category: slug: festival name: Festivals countries: - code: de name: Germany flag_emoji: 🇩🇪 first_published_at: '2026-01-22T11:00:00+03:00' last_updated_at: '2026-07-04T04:16:47+03:00' articles_count: 5 url: 'https://openvan.camp/en/news/festival/adac-camper-des-jahres-der-wettbewerb-fuer' sources: - title: 'Nürburgring: Bundesweiter Wettbewerb «Camper des Jahres»' original_url: 'https://www.blick-aktuell.de/Berichte/...' source_name: 'BLICK aktuell' published_at: '2026-04-30T09:24:20+03:00' language: de image_url: 'https://...' properties: slug: type: string example: adac-camper-des-jahres-der-wettbewerb-fuer title: type: string example: "ADAC launches 'Camper of the Year' competition for motorhome drivers" summary: type: string example: "ADAC is holding the national 'Camper des Jahres 2026' competition for motorhome owners..." image_url: type: string example: 'https://...' category: type: object properties: slug: type: string example: festival name: type: string example: Festivals countries: type: array example: - code: de name: Germany flag_emoji: 🇩🇪 items: type: object properties: code: type: string example: de name: type: string example: Germany flag_emoji: type: string example: 🇩🇪 first_published_at: type: string example: '2026-01-22T11:00:00+03:00' last_updated_at: type: string example: '2026-07-04T04:16:47+03:00' articles_count: type: integer example: 5 url: type: string example: 'https://openvan.camp/en/news/festival/adac-camper-des-jahres-der-wettbewerb-fuer' sources: type: array example: - title: 'Nürburgring: Bundesweiter Wettbewerb «Camper des Jahres»' original_url: 'https://www.blick-aktuell.de/Berichte/...' source_name: 'BLICK aktuell' published_at: '2026-04-30T09:24:20+03:00' language: de image_url: 'https://...' items: type: object properties: title: type: string example: 'Nürburgring: Bundesweiter Wettbewerb «Camper des Jahres»' original_url: type: string example: 'https://www.blick-aktuell.de/Berichte/...' source_name: type: string example: 'BLICK aktuell' published_at: type: string example: '2026-04-30T09:24:20+03:00' language: type: string example: de image_url: type: string example: 'https://...' 404: description: 'Not found' content: application/json: schema: type: object example: error: 'Story not found.' properties: error: type: string example: 'Story not found.' tags: - Stories security: [] parameters: - in: path name: slug description: 'The story slug.' example: adac-camper-des-jahres-der-wettbewerb-fuer required: true schema: type: string /api/news/search: get: summary: 'Semantic news search (RAG)' operationId: semanticNewsSearchRAG description: "Semantic search over news via the same engine as the /{locale}/search page\n(SemanticSearchService: Jina embeddings + pgvector). Returns matching news\nstories ranked by similarity. Story summary shape matches /stories." parameters: - in: query name: q description: 'Search query.' example: 'ford camper 2026' required: true schema: type: string description: 'Search query.' example: 'ford camper 2026' - in: query name: locale description: 'Language for localized titles/summaries. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: ru required: false schema: type: string description: 'Language for localized titles/summaries. One of: `en`, `ru`, `de`, `fr`, `es`, `pt`, `tr`. Defaults to `en`.' example: ru - in: query name: limit description: 'Max results (1-15). Defaults to 8.' example: 8 required: false schema: type: integer description: 'Max results (1-15). Defaults to 8.' example: 8 responses: 200: description: '' content: application/json: schema: type: object example: results: - slug: panoramic-ford-f-camper-truck-costs-fraction title: 'Supertramp представила кемпер Paragon на базе Ford F-350' summary: 'Компания Supertramp анонсировала новую модель кемпера Paragon на шасси Ford F-350. Базовая цена составляет 199 000 долларов, что значительно ниже конкурентов, таких как Earthroamer (от 825 000 долларов) и Winnebago Arka (330 000 долларов). Модель оснащена композитным модулем с вакуумной инфузией, спальными местами на четыре человека и опциональной палаткой на крыше для шести человек. Стандартная комплектация включает литий-ионную батарею на 270 А·ч, инвертор на 3000 Вт и солнечную систему на 660 Вт.' image_url: 'https://assets.newatlas.com/dims4/default/00d5475/2147483647/strip/true/crop/3276x1720+0+514/resize/1200x630!/quality/85/?url=https%3A%2F%2Fnewatlas-brightspot.s3.amazonaws.com%2Fb8%2F31%2F5eb910d0450196ac9000fdc083c3%2F699761506-18360938500231222-6098785867930289037-n.jpg&na.image_optimisation=0' category: slug: industry name: Индустрия countries: [] first_published_at: '2026-06-05T04:35:09+03:00' articles_count: 1 url: 'https://openvan.camp/ru/news/industry/panoramic-ford-f-camper-truck-costs-fraction' score: 0.562 - slug: ram-promaster-add-new-prebuilt-camper-van-thats title: 'Ram ProMaster 2027 получил пакет Vanlife для автодомов' summary: 'Компания Ram представила пакет Vanlife для фургона ProMaster 2027 года, упрощающий переоборудование в кемпер. Цена — от $60 320.' image_url: 'https://hips.hearstapps.com/hmg-prod/images/94800d47-567d-49f8-8bb7-2996f6c8af4c.jpg?crop=1.00xw:0.753xh;0,0.171xh&resize=1200:*' category: slug: industry name: Индустрия countries: - code: ru name: Россия flag_emoji: 🇷🇺 - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-06-02T20:53:00+03:00' articles_count: 6 url: 'https://openvan.camp/ru/news/industry/ram-promaster-add-new-prebuilt-camper-van-thats' score: 0.533 - slug: ford-convierte-la-transit-custom-en-la-mejor title: 'Carado T457 на базе Ford Transit признан лучшим автодомом 2026 года по версии Red Dot Awards' summary: 'Модель Carado T457, полуинтегрированный автодом на платформе Ford Transit, получил награду Red Dot Design Awards 2026. Длина — 7,4 м, ширина — 2,32 м, высота — 2,93 м. Цена от 71 690 евро.' image_url: 'https://album.mediaset.es/eimg/2026/01/03/ford-logo-16-9-aspect-ratio-default-1027707_da39.jpg' category: slug: industry name: Индустрия countries: - code: de name: Германия flag_emoji: 🇩🇪 first_published_at: '2026-02-18T10:20:01+03:00' articles_count: 2 url: 'https://openvan.camp/ru/news/industry/ford-convierte-la-transit-custom-en-la-mejor' score: 0.529 - slug: dfsk-tebar-promo-besar-di-prj-2026-mulai title: 'DFSK на PRJ 2026: кемпер Delima x Explora и анонс PHEV' summary: 'На Jakarta Fair Kemayoran 2026 компания DFSK представила Camper Van Delima x Explora, электромобили и анонсировала технологию Plug-in Hybrid Electric Vehicle (PHEV). Действуют программы trade-in и бесплатного обслуживания.' image_url: 'https://dapurletter.id/wp-content/uploads/2026/06/PRJ-DFSK-2.jpeg' category: slug: expo name: Выставки countries: - code: id name: Индонезия flag_emoji: 🇮🇩 first_published_at: '2026-06-11T07:13:45+03:00' articles_count: 2 url: 'https://openvan.camp/ru/news/expo/dfsk-tebar-promo-besar-di-prj-2026-mulai' score: 0.524 - slug: chrysler-pacifica-awd-minit-campervan-brings-van title: '2026 Chrysler Pacifica AWD Mini-T Campervan' summary: 'Компания DLM-Distribution представила кемпер на базе Chrysler Pacifica с полным приводом. Модель помещается в стандартный гараж и оснащена спальным местом, холодильником, раковиной и солнечной батареей. Цена — $66 900.' image_url: 'https://moparinsiders.com/wp-content/uploads/2026/05/2026-Chrysler-Pacifica-AWD-Mini-T-Campervan.-DLM-Distribution.-1.jpeg' category: slug: industry name: Индустрия countries: - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-05-17T19:00:21+03:00' articles_count: 1 url: 'https://openvan.camp/ru/news/industry/chrysler-pacifica-awd-minit-campervan-brings-van' score: 0.524 - slug: volkswagen-id-buzz-coming-back-america-van-camp title: 'Volkswagen возвращает кемпер ID. Buzz в США с новой комплектацией Tourer' summary: 'Volkswagen представил комплектацию Tourer для электрического микроавтобуса ID. Buzz 2027 года, предназначенную для кемпинга. В оснащение входят складная кровать, шторки, режим Overnight и уличная мебель. Продажи начнутся в 2027 году, цены пока не объявлены.' image_url: 'https://images-stag.jazelc.com/uploads/theautopian-m2en/ID_Camper_TS2.png' category: slug: industry name: Индустрия countries: - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-05-14T16:49:00+03:00' articles_count: 7 url: 'https://openvan.camp/ru/news/industry/volkswagen-id-buzz-coming-back-america-van-camp' score: 0.523 timing_ms: 60 _attribution: data_source: openvan.camp license: 'CC BY 4.0' attribution_url: 'https://openvan.camp/' attribution_html: 'Data: OpenVan.camp (CC BY 4.0)' properties: results: type: array example: - slug: panoramic-ford-f-camper-truck-costs-fraction title: 'Supertramp представила кемпер Paragon на базе Ford F-350' summary: 'Компания Supertramp анонсировала новую модель кемпера Paragon на шасси Ford F-350. Базовая цена составляет 199 000 долларов, что значительно ниже конкурентов, таких как Earthroamer (от 825 000 долларов) и Winnebago Arka (330 000 долларов). Модель оснащена композитным модулем с вакуумной инфузией, спальными местами на четыре человека и опциональной палаткой на крыше для шести человек. Стандартная комплектация включает литий-ионную батарею на 270 А·ч, инвертор на 3000 Вт и солнечную систему на 660 Вт.' image_url: 'https://assets.newatlas.com/dims4/default/00d5475/2147483647/strip/true/crop/3276x1720+0+514/resize/1200x630!/quality/85/?url=https%3A%2F%2Fnewatlas-brightspot.s3.amazonaws.com%2Fb8%2F31%2F5eb910d0450196ac9000fdc083c3%2F699761506-18360938500231222-6098785867930289037-n.jpg&na.image_optimisation=0' category: slug: industry name: Индустрия countries: [] first_published_at: '2026-06-05T04:35:09+03:00' articles_count: 1 url: 'https://openvan.camp/ru/news/industry/panoramic-ford-f-camper-truck-costs-fraction' score: 0.562 - slug: ram-promaster-add-new-prebuilt-camper-van-thats title: 'Ram ProMaster 2027 получил пакет Vanlife для автодомов' summary: 'Компания Ram представила пакет Vanlife для фургона ProMaster 2027 года, упрощающий переоборудование в кемпер. Цена — от $60 320.' image_url: 'https://hips.hearstapps.com/hmg-prod/images/94800d47-567d-49f8-8bb7-2996f6c8af4c.jpg?crop=1.00xw:0.753xh;0,0.171xh&resize=1200:*' category: slug: industry name: Индустрия countries: - code: ru name: Россия flag_emoji: 🇷🇺 - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-06-02T20:53:00+03:00' articles_count: 6 url: 'https://openvan.camp/ru/news/industry/ram-promaster-add-new-prebuilt-camper-van-thats' score: 0.533 - slug: ford-convierte-la-transit-custom-en-la-mejor title: 'Carado T457 на базе Ford Transit признан лучшим автодомом 2026 года по версии Red Dot Awards' summary: 'Модель Carado T457, полуинтегрированный автодом на платформе Ford Transit, получил награду Red Dot Design Awards 2026. Длина — 7,4 м, ширина — 2,32 м, высота — 2,93 м. Цена от 71 690 евро.' image_url: 'https://album.mediaset.es/eimg/2026/01/03/ford-logo-16-9-aspect-ratio-default-1027707_da39.jpg' category: slug: industry name: Индустрия countries: - code: de name: Германия flag_emoji: 🇩🇪 first_published_at: '2026-02-18T10:20:01+03:00' articles_count: 2 url: 'https://openvan.camp/ru/news/industry/ford-convierte-la-transit-custom-en-la-mejor' score: 0.529 - slug: dfsk-tebar-promo-besar-di-prj-2026-mulai title: 'DFSK на PRJ 2026: кемпер Delima x Explora и анонс PHEV' summary: 'На Jakarta Fair Kemayoran 2026 компания DFSK представила Camper Van Delima x Explora, электромобили и анонсировала технологию Plug-in Hybrid Electric Vehicle (PHEV). Действуют программы trade-in и бесплатного обслуживания.' image_url: 'https://dapurletter.id/wp-content/uploads/2026/06/PRJ-DFSK-2.jpeg' category: slug: expo name: Выставки countries: - code: id name: Индонезия flag_emoji: 🇮🇩 first_published_at: '2026-06-11T07:13:45+03:00' articles_count: 2 url: 'https://openvan.camp/ru/news/expo/dfsk-tebar-promo-besar-di-prj-2026-mulai' score: 0.524 - slug: chrysler-pacifica-awd-minit-campervan-brings-van title: '2026 Chrysler Pacifica AWD Mini-T Campervan' summary: 'Компания DLM-Distribution представила кемпер на базе Chrysler Pacifica с полным приводом. Модель помещается в стандартный гараж и оснащена спальным местом, холодильником, раковиной и солнечной батареей. Цена — $66 900.' image_url: 'https://moparinsiders.com/wp-content/uploads/2026/05/2026-Chrysler-Pacifica-AWD-Mini-T-Campervan.-DLM-Distribution.-1.jpeg' category: slug: industry name: Индустрия countries: - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-05-17T19:00:21+03:00' articles_count: 1 url: 'https://openvan.camp/ru/news/industry/chrysler-pacifica-awd-minit-campervan-brings-van' score: 0.524 - slug: volkswagen-id-buzz-coming-back-america-van-camp title: 'Volkswagen возвращает кемпер ID. Buzz в США с новой комплектацией Tourer' summary: 'Volkswagen представил комплектацию Tourer для электрического микроавтобуса ID. Buzz 2027 года, предназначенную для кемпинга. В оснащение входят складная кровать, шторки, режим Overnight и уличная мебель. Продажи начнутся в 2027 году, цены пока не объявлены.' image_url: 'https://images-stag.jazelc.com/uploads/theautopian-m2en/ID_Camper_TS2.png' category: slug: industry name: Индустрия countries: - code: us name: США flag_emoji: 🇺🇸 first_published_at: '2026-05-14T16:49:00+03:00' articles_count: 7 url: 'https://openvan.camp/ru/news/industry/volkswagen-id-buzz-coming-back-america-van-camp' score: 0.523 items: type: object properties: slug: type: string example: panoramic-ford-f-camper-truck-costs-fraction title: type: string example: 'Supertramp представила кемпер Paragon на базе Ford F-350' summary: type: string example: 'Компания Supertramp анонсировала новую модель кемпера Paragon на шасси Ford F-350. Базовая цена составляет 199 000 долларов, что значительно ниже конкурентов, таких как Earthroamer (от 825 000 долларов) и Winnebago Arka (330 000 долларов). Модель оснащена композитным модулем с вакуумной инфузией, спальными местами на четыре человека и опциональной палаткой на крыше для шести человек. Стандартная комплектация включает литий-ионную батарею на 270 А·ч, инвертор на 3000 Вт и солнечную систему на 660 Вт.' image_url: type: string example: 'https://assets.newatlas.com/dims4/default/00d5475/2147483647/strip/true/crop/3276x1720+0+514/resize/1200x630!/quality/85/?url=https%3A%2F%2Fnewatlas-brightspot.s3.amazonaws.com%2Fb8%2F31%2F5eb910d0450196ac9000fdc083c3%2F699761506-18360938500231222-6098785867930289037-n.jpg&na.image_optimisation=0' category: type: object properties: slug: type: string example: industry name: type: string example: Индустрия countries: type: array example: [] first_published_at: type: string example: '2026-06-05T04:35:09+03:00' articles_count: type: integer example: 1 url: type: string example: 'https://openvan.camp/ru/news/industry/panoramic-ford-f-camper-truck-costs-fraction' score: type: number example: 0.562 timing_ms: type: integer example: 60 _attribution: type: object properties: data_source: type: string example: openvan.camp license: type: string example: 'CC BY 4.0' attribution_url: type: string example: 'https://openvan.camp/' attribution_html: type: string example: 'Data: OpenVan.camp (CC BY 4.0)' tags: - Stories security: [] /api/news/digest: get: summary: 'Daily news digest (raw content)' operationId: dailyNewsDigestrawContent description: "Returns the structured evening news digest for the requested locale,\nassembled once per evening by the site. Consumers (site social channels," parameters: - in: query name: locale description: 'Digest language. Currently `ru` or `en`. Defaults to `ru`.' example: ru required: false schema: type: string description: 'Digest language. Currently `ru` or `en`. Defaults to `ru`.' example: ru responses: 200: description: Success content: application/json: schema: type: object example: locale: ru date: '2026-07-25' intro: 'Дороги сегодня подкинули всё…' groups: - key: incident title: '⚠️ Происшествия' items: - id: 123 flag: 🇩🇪 hook: Заголовок-зацепка detail: 'Деталь сюжета' url: 'https://openvan.camp/ru/news/incident/slug' properties: locale: type: string example: ru date: type: string example: '2026-07-25' intro: type: string example: 'Дороги сегодня подкинули всё…' groups: type: array example: - key: incident title: '⚠️ Происшествия' items: - id: 123 flag: 🇩🇪 hook: Заголовок-зацепка detail: 'Деталь сюжета' url: 'https://openvan.camp/ru/news/incident/slug' items: type: object properties: key: type: string example: incident title: type: string example: '⚠️ Происшествия' items: type: array example: - id: 123 flag: 🇩🇪 hook: Заголовок-зацепка detail: 'Деталь сюжета' url: 'https://openvan.camp/ru/news/incident/slug' items: type: object properties: id: type: integer example: 123 flag: type: string example: 🇩🇪 hook: type: string example: Заголовок-зацепка detail: type: string example: 'Деталь сюжета' url: type: string example: 'https://openvan.camp/ru/news/incident/slug' 204: description: 'No digest yet' content: text/plain: schema: type: string example: '' tags: - Stories security: [] /api/vanbasket/countries: get: summary: 'Get all countries with VanBasket index.' operationId: getAllCountriesWithVanBasketIndex description: "Returns food price index for 90+ countries.\nWorld average = 100. Above 100 = more expensive, below 100 = cheaper." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: DE: country_code: DE country_name: Germany vanbasket_index: 124.9 pct_vs_world: 24.9 meta: total_countries: 92 properties: success: type: boolean example: true data: type: object properties: DE: type: object properties: country_code: type: string example: DE country_name: type: string example: Germany vanbasket_index: type: number example: 124.9 pct_vs_world: type: number example: 24.9 meta: type: object properties: total_countries: type: integer example: 92 tags: - 'VanBasket Food Price Index' security: [] /api/vanbasket/compare: get: summary: 'Compare food prices between two countries.' operationId: compareFoodPricesBetweenTwoCountries description: '' parameters: - in: query name: from description: 'ISO 3166-1 alpha-2 code of home country.' example: DE required: true schema: type: string description: 'ISO 3166-1 alpha-2 code of home country.' example: DE - in: query name: to description: 'ISO 3166-1 alpha-2 code of destination country.' example: TR required: true schema: type: string description: 'ISO 3166-1 alpha-2 code of destination country.' example: TR responses: 200: description: '' content: application/json: schema: type: object example: success: true data: from: country_code: DE country_name: Germany vanbasket_index: 124.9 to: country_code: TR country_name: Turkey vanbasket_index: 88.0 diff_percent: -29.5 budget_100: 70 cheaper: true properties: success: type: boolean example: true data: type: object properties: from: type: object properties: country_code: type: string example: DE country_name: type: string example: Germany vanbasket_index: type: number example: 124.9 to: type: object properties: country_code: type: string example: TR country_name: type: string example: Turkey vanbasket_index: type: number example: 88.0 diff_percent: type: number example: -29.5 budget_100: type: integer example: 70 cheaper: type: boolean example: true tags: - 'VanBasket Food Price Index' security: [] '/api/vanbasket/countries/{code}': get: summary: 'Get VanBasket country details' operationId: getVanBasketCountryDetails description: 'Detailed data for a single country including historical snapshots.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: country: country_code: DE vanbasket_index: 124.9 snapshots: - snapshot_date: '2021-01-01' vanbasket_index: 124.9 properties: success: type: boolean example: true data: type: object properties: country: type: object properties: country_code: type: string example: DE vanbasket_index: type: number example: 124.9 snapshots: type: array example: - snapshot_date: '2021-01-01' vanbasket_index: 124.9 items: type: object properties: snapshot_date: type: string example: '2021-01-01' vanbasket_index: type: number example: 124.9 tags: - 'VanBasket Food Price Index' security: [] parameters: - in: path name: code description: 'ISO 3166-1 alpha-2 country code.' example: DE required: true schema: type: string /api/visa/check: get: summary: 'Check a passport against a destination.' operationId: checkAPassportAgainstADestination description: "Returns the stay rule (days, counting window, whether a visa run resets\nthe counter), the entry mode, and the vehicle import rule for the same\ndestination.\n\nIf the country belongs to a shared-counter zone, the stay rule is the\nzone's — entering Spain spends Schengen days, not \"Spanish\" ones — and\n`counted_against` names the place the counter belongs to." parameters: - in: query name: passport description: 'ISO 3166-1 alpha-2 code of the passport.' example: RU required: true schema: type: string description: 'ISO 3166-1 alpha-2 code of the passport.' example: RU - in: query name: destination description: 'ISO alpha-2 code, slug or zone code.' example: TR required: true schema: type: string description: 'ISO alpha-2 code, slug or zone code.' example: TR - in: query name: weight description: 'Vehicle weight class for the vehicle rule: le35 (≤3.5t) or gt35.' example: le35 required: false schema: type: string description: 'Vehicle weight class for the vehicle rule: le35 (≤3.5t) or gt35.' example: le35 - in: query name: plate description: 'Vehicle plate origin for the vehicle rule: eu, non_eu, eaeu, third.' example: third required: false schema: type: string description: 'Vehicle plate origin for the vehicle rule: eu, non_eu, eaeu, third.' example: third - in: query name: locale description: 'Language of place names, one of ru/en/de/es/fr/pt/tr. Defaults to en.' example: en required: false schema: type: string description: 'Language of place names, one of ru/en/de/es/fr/pt/tr. Defaults to en.' example: en responses: 200: description: '' content: application/json: schema: type: object example: success: true data: passport: code: RU name: Russia destination: code: TR name: Turkey kind: country zone: null entry_mode: visa_free stay: visa_type: visa_free max_continuous: 90 max_total: 90 window: rolling window_days: 180 visa_run: false confidence: high source_url: 'https://www.mfa.gov.tr/visa-information-for-foreigners.en.mfa' note: 'Безвиз 90/180.' layer: curated vehicle: max_days: null basis: tied_to_person green_card: required confidence: high properties: success: type: boolean example: true data: type: object properties: passport: type: object properties: code: type: string example: RU name: type: string example: Russia destination: type: object properties: code: type: string example: TR name: type: string example: Turkey kind: type: string example: country zone: type: string example: null nullable: true entry_mode: type: string example: visa_free stay: type: object properties: visa_type: type: string example: visa_free max_continuous: type: integer example: 90 max_total: type: integer example: 90 window: type: string example: rolling window_days: type: integer example: 180 visa_run: type: boolean example: false confidence: type: string example: high source_url: type: string example: 'https://www.mfa.gov.tr/visa-information-for-foreigners.en.mfa' note: type: string example: 'Безвиз 90/180.' layer: type: string example: curated vehicle: type: object properties: max_days: type: string example: null nullable: true basis: type: string example: tied_to_person green_card: type: string example: required confidence: type: string example: high 422: description: '' content: application/json: schema: type: object example: success: false error: 'Parameters "passport" and "destination" are required.' properties: success: type: boolean example: false error: type: string example: 'Parameters "passport" and "destination" are required.' tags: - 'Visa & Border Rules' security: [] /api/visa/rank: get: summary: 'Passport ranking by destinations reachable without a prior visa.' operationId: passportRankingByDestinationsReachableWithoutAPriorVisa description: "Score = visa free + visa on arrival + eTA. The breakdown is returned\nalongside so the number can be checked rather than taken on faith.\nTies share a rank." parameters: - in: query name: limit description: 'How many rows to return, 1..199. Defaults to all.' example: 10 required: false schema: type: integer description: 'How many rows to return, 1..199. Defaults to all.' example: 10 - in: query name: locale description: 'Language of passport names. Defaults to en.' example: en required: false schema: type: string description: 'Language of passport names. Defaults to en.' example: en responses: 200: description: '' content: application/json: schema: type: object example: success: true data: - rank: 1 passport: SG name: Singapore score: 168 visa_free: 130 visa_on_arrival: 30 eta: 8 e_visa: 20 visa_required: 10 meta: total: 199 scoring: 'visa_free + visa_on_arrival + eta' properties: success: type: boolean example: true data: type: array example: - rank: 1 passport: SG name: Singapore score: 168 visa_free: 130 visa_on_arrival: 30 eta: 8 e_visa: 20 visa_required: 10 items: type: object properties: rank: type: integer example: 1 passport: type: string example: SG name: type: string example: Singapore score: type: integer example: 168 visa_free: type: integer example: 130 visa_on_arrival: type: integer example: 30 eta: type: integer example: 8 e_visa: type: integer example: 20 visa_required: type: integer example: 10 meta: type: object properties: total: type: integer example: 199 scoring: type: string example: 'visa_free + visa_on_arrival + eta' tags: - 'Visa & Border Rules' security: [] /api/visa/history: get: summary: 'Change log of visa and vehicle rules.' operationId: changeLogOfVisaAndVehicleRules description: "One row per changed field, written both by imports and by editors.\nCommercial passport APIs charge for rule history; this one is open." parameters: - in: query name: subject_type description: 'Filter: requirement, window, window_exception, curated_rule, vehicle_rule, place.' example: requirement required: false schema: type: string description: 'Filter: requirement, window, window_exception, curated_rule, vehicle_rule, place.' example: requirement - in: query name: subject_key description: 'Filter by subject, e.g. RU>TR for a pair or TR for a place.' example: RU>TR required: false schema: type: string description: 'Filter by subject, e.g. RU>TR for a pair or TR for a place.' example: RU>TR - in: query name: since description: 'ISO date, only changes on or after it.' example: '2026-01-01' required: false schema: type: string description: 'ISO date, only changes on or after it.' example: '2026-01-01' - in: query name: limit description: '1..500, defaults to 100.' example: 50 required: false schema: type: integer description: '1..500, defaults to 100.' example: 50 responses: 200: description: '' content: application/json: schema: type: object example: success: true data: - subject_type: requirement subject_key: RU>TR field: days old_value: '60' new_value: '90' source: import changed_at: '2026-07-27T10:00:00+00:00' meta: total: 1 properties: success: type: boolean example: true data: type: array example: - subject_type: requirement subject_key: RU>TR field: days old_value: '60' new_value: '90' source: import changed_at: '2026-07-27T10:00:00+00:00' items: type: object properties: subject_type: type: string example: requirement subject_key: type: string example: RU>TR field: type: string example: days old_value: type: string example: '60' new_value: type: string example: '90' source: type: string example: import changed_at: type: string example: '2026-07-27T10:00:00+00:00' meta: type: object properties: total: type: integer example: 1 tags: - 'Visa & Border Rules' security: [] '/api/visa/passport/{code}': get: summary: 'All destinations for one passport.' operationId: allDestinationsForOnePassport description: "199 rows resolved through the full chain, sorted by destination name.\nCounts by entry mode are in `meta`." parameters: - in: query name: mode description: 'Filter by entry mode: visa_free, visa_required, e_visa, eta, voa, no_admission.' example: visa_free required: false schema: type: string description: 'Filter by entry mode: visa_free, visa_required, e_visa, eta, voa, no_admission.' example: visa_free - in: query name: locale description: 'Language of place names. Defaults to en.' example: en required: false schema: type: string description: 'Language of place names. Defaults to en.' example: en responses: 200: description: '' content: application/json: schema: type: object example: success: true data: - destination: TR name: Turkey slug: turkey mode: visa_free days: 90 stay: window: rolling window_days: 180 confidence: medium layer: window meta: passport: DE total: 199 by_mode: visa_free: 130 properties: success: type: boolean example: true data: type: array example: - destination: TR name: Turkey slug: turkey mode: visa_free days: 90 stay: window: rolling window_days: 180 confidence: medium layer: window items: type: object properties: destination: type: string example: TR name: type: string example: Turkey slug: type: string example: turkey mode: type: string example: visa_free days: type: integer example: 90 stay: type: object properties: window: type: string example: rolling window_days: type: integer example: 180 confidence: type: string example: medium layer: type: string example: window meta: type: object properties: passport: type: string example: DE total: type: integer example: 199 by_mode: type: object properties: visa_free: type: integer example: 130 tags: - 'Visa & Border Rules' security: [] parameters: - in: path name: code description: 'ISO 3166-1 alpha-2 code of the passport.' example: DE required: true schema: type: string '/api/visa/map/{code}': get: summary: 'Compact payload for colouring a world map by one passport.' operationId: compactPayloadForColouringAWorldMapByOnePassport description: "Same data as /passport/{code} stripped to what a choropleth needs:\n`m` — entry mode, `d` — visa-free days if known." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: TR: m: visa_free d: 90 RU: m: visa_required d: null meta: passport: US legend: - visa_free - voa - eta - e_visa - visa_required - no_admission - self properties: success: type: boolean example: true data: type: object properties: TR: type: object properties: m: type: string example: visa_free d: type: integer example: 90 RU: type: object properties: m: type: string example: visa_required d: type: string example: null nullable: true meta: type: object properties: passport: type: string example: US legend: type: array example: - visa_free - voa - eta - e_visa - visa_required - no_admission - self items: type: string tags: - 'Visa & Border Rules' security: [] parameters: - in: path name: code description: 'ISO 3166-1 alpha-2 code of the passport.' example: US required: true schema: type: string '/api/visa/vehicle/{place}': get: summary: 'Temporary vehicle import rules for a country.' operationId: temporaryVehicleImportRulesForACountry description: "Only rules we can stand behind are returned: an official source, or two\nindependent research runs agreeing, or manual verification. A country\nwith nothing trustworthy returns an empty list rather than a guess —\nthe cost of being wrong here is a vehicle held at the border." parameters: - in: query name: locale description: 'Language of the place name. Defaults to en.' example: en required: false schema: type: string description: 'Language of the place name. Defaults to en.' example: en responses: 200: description: '' content: application/json: schema: type: object example: success: true data: - weight_class: le35 plate_group: null max_days: 90 basis: per_entry window_days: null carnet_required: false extension_possible: null green_card: border_insurance confidence: high source_url: 'https://georgiacb.com/en/articles/customs-procedure-temporary-importation-admission-im-53' curated: true meta: place: GE name: Georgia green_card_by_plate: eu: plate_ok properties: success: type: boolean example: true data: type: array example: - weight_class: le35 plate_group: null max_days: 90 basis: per_entry window_days: null carnet_required: false extension_possible: null green_card: border_insurance confidence: high source_url: 'https://georgiacb.com/en/articles/customs-procedure-temporary-importation-admission-im-53' curated: true items: type: object properties: weight_class: type: string example: le35 plate_group: type: string example: null nullable: true max_days: type: integer example: 90 basis: type: string example: per_entry window_days: type: string example: null nullable: true carnet_required: type: boolean example: false extension_possible: type: string example: null nullable: true green_card: type: string example: border_insurance confidence: type: string example: high source_url: type: string example: 'https://georgiacb.com/en/articles/customs-procedure-temporary-importation-admission-im-53' curated: type: boolean example: true meta: type: object properties: place: type: string example: GE name: type: string example: Georgia green_card_by_plate: type: object properties: eu: type: string example: plate_ok tags: - 'Visa & Border Rules' security: [] parameters: - in: path name: place description: 'ISO alpha-2 code, slug or zone code.' example: georgia required: true schema: type: string