Data integration
Data sources & simulation
Every number in the planner traces to one of the sources below. Until a source is connected the planner runs on the bundled Simulated Industry Baseline, labeled as such throughout. Keys and files entered here live only in this browser session.
Status · 🇩🇪 Germany
3 of 32 sources live · simulation ON
🇩🇪 Germany
9 catchments · 8 bundesländer · 29 calendar entries · 16 POIs
Index context: Weather delta · lookahead 70–77 days · USD
🇬🇧 United Kingdom
8 catchments · 8 regions & nations · 42 calendar entries · 15 POIs
Index context: Weather delta · lookahead 40–55 days · USD
🇸🇦 Saudi Arabia
7 catchments · 6 provinces · 8 calendar entries · 12 POIs
Index context: Access & frequency · lookahead 10–21 days · USD
History warehouse
Supabase / Postgres (PostgREST) — IndexedDB in this browser until configured
- Feeds
- Time series of every capture (weather, pageviews, TAC, FX, OSM) and campaign outcomes; the training set for the propensity model and the source of trends
- Fields
- observations(key, market, region, captured_at, source, metric, value) · campaign_outcomes(key, market, region, motivation, objective, flight_start, flight_end, budget, reach, visits, bookings, rate, simulated)
- Hook
- historyStore() — src/lib/history.ts; schema in supabase/schema.sql; env VITE_SUPABASE_URL + VITE_SUPABASE_ANON_KEY
- Docs
- https://supabase.com/docs/guides/api
Collecting into … on this device. Set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY, run supabase/schema.sql, redeploy.
Propensity & forecast model
In-browser ridge regression + Holt forecast today; swap for a model service (Vertex AI / SageMaker / Databricks) later
- Feeds
- Learned booking propensity per catchment, demand trend and 14-day forecast, freeze-date estimates → Insights suggestions
- Fields
- features: affinity, search pace, context score, POI density, partner share · target: bookings / reach
- Hook
- trainPropensity() · holtForecast() — src/lib/ml.ts; buildSuggestions() — src/lib/suggestions.ts
Running in the browser on the warehouse rows · see the Insights tab. Point VITE_MODEL_URL at a model service to replace trainPropensity().
Wikipedia pageviews (demand proxy)
Wikimedia REST API (open, no key)
- Feeds
- Daily views of the 'Dubai' article in the market's language edition as an open search-interest proxy for the surge rule, until TAC is connected
- Fields
- items[].timestamp (YYYYMMDDHH), items[].views
- Hook
- fetchWikipediaPace() → store.paceSeries — src/lib/open-data.ts
- Docs
- https://wikimedia.org/api/rest_v1/
Not fetched yet
Travel Analytics Center (TAC) / Destination Insights
- Feeds
- Search pace (% YoY flight searches to DXB) per catchment, 15-day search index for the surge rule, and the search lookahead window, trip length and one-way share per route (city, region, country, subcontinent)
- Fields
- surge series: date, origin, destination=DXB, search_index · lookahead export: Origin, Destination, [Route ID], Ad Opp. Vol., MoM, Lookahead Avg (days), MoM, Trip Avg (days), MoM, One-way %, MoM (pp)
- Hook
- Region.pace · Market.paceSeries — src/lib/tac-csv.ts; Market.lookahead · Region.tac · Market.searchBenchmarks — src/lib/tac-lookahead.ts + src/data/tac-lookahead-uae.json
- Docs
- https://destinationinsights.withgoogle.com
export · 31 Oct 2026Lookahead window export · Germany → 164 countries, 1,005 regions, 1,000 city routes, 23 subcontinents
Cleaned JSONGoogle Trends API
- Feeds
- Fallback surge series and search-term discovery for the surge rule action
- Fields
- term, geo (DE-BY, GB-ENG, SA-01…), date, interest
- Hook
- Market.searchTerms · surgeStats() — src/lib/det-data.ts
Optional — simulated values already cover this.
Population & age structure (census)
Eurostat demo_r_pjangroup (open, no key) · ONS / GASTAT via CSV drop
- Feeds
- Eligible adults 25–64 per catchment from the city-core NUTS 3 districts, and census shares behind the audience overlay (55+, 25–44, children under 15) indexed vs national
- Fields
- geo (NUTS 1 / NUTS 3), age (Y_LT5 … Y_GE85), value · CSV: area, age group, population
- Hook
- fetchEurostatCensus() → applyCensus() — src/lib/open-stats.ts; Region.population · Region.audience
- Docs
- https://ec.europa.eu/eurostat/web/population-demography/demography-population-stock-balance/database
Not fetched yet
Population baseline (Destatis · ONS · GASTAT)
National statistics offices
- Feeds
- Eligible adults 25–65 per catchment (base for Estimated Relevant Audience)
- Fields
- area_code, age_band, population, income_band (optional)
- Hook
- Region.population — src/lib/markets/*.ts
- Docs
- https://www-genesis.destatis.de · https://www.ons.gov.uk · https://www.stats.gov.sa
Motivation affinity index
GWI / YouGov Profiles / Kantar TGI
- Feeds
- Affinity index per motivation per catchment (vs national 100) → Motivation Fit score and propensity
- Fields
- region, motivation, index, sample_size, wave
- Hook
- Region.affinity · fitScore() · BASE_PROPENSITY — src/lib/det-data.ts
Partner device pools
Azira · Maddict · TMG (DE/GB) · Almosafer / Seera (KSA)
- Feeds
- Available Partner Audience (verified MAIDs, 30-day) and segment IDs for the activation route
- Fields
- segment_id, region, maid_count_30d, spend_tier, refresh_date
- Hook
- Region.partnerShare · Market.partnerSegments — src/lib/markets/*.ts
Audience segments by origin
SafeGraph audience-origin · partner device pools
- Feeds
- Segment index vs national 100 per catchment (Active silvers, Younger families, Solos & couples) → audience overlay on motivation fit in the Opportunity Index
- Fields
- region_id, segment_id, segment_label, index_vs_national, devices_30d, refreshed_at
- Hook
- Region.audience — src/lib/markets/*.ts; audienceScore() in src/lib/det-data.ts
Optional — simulated values already cover this.
OpenStreetMap POI counts
Overpass API (open, no key, rate-limited)
- Feeds
- Restaurants, jewellery/boutique/watch shops, golf courses and outdoor/sports shops within 15 km of the selected catchment, as an open cross-check of the SafeGraph density
- Fields
- amenity=restaurant · shop=jewelry|boutique|watches · leisure=golf_course · shop=outdoor|sports (out count)
- Hook
- fetchOsmCounts() → store.openData.osm — src/lib/open-data.ts
- Docs
- https://overpass-api.de
Counts places around the selected catchment on demand
Places & footfall
SafeGraph (or Foursquare Places / Overture)
- Feeds
- POI clusters, footfall rank and geofence coordinates; POI density per catchment (dining, luxury, golf, outdoor)
- Fields
- placekey, name, category, lat, lng, postcode, visits_rank
- Hook
- Market.pois · Region.pois — src/lib/markets/*.ts; map layer in src/components/det/GermanyMap.tsx
- Docs
- https://docs.safegraph.com
Open-Meteo weather
Open-Meteo (open, no key)
- Feeds
- Live origin temperature, condition and consecutive rain days for every catchment, plus Dubai's temperature → weather delta, freeze trigger and Dubai ≥ 28°C condition
- Fields
- current.temperature_2m, current.weather_code, daily.precipitation_sum (past 7 days)
- Hook
- fetchOpenMeteo() → applyOpenData() — src/lib/open-data.ts
- Docs
- https://open-meteo.com/en/docs
Not fetched yet
Origin weather
DWD (DE) · Met Office DataHub (GB) · NCM (KSA) / OpenWeather
- Feeds
- Current temperature, condition and consecutive rain days per catchment → weather delta score and freeze trigger
- Fields
- station or lat/lng, observed_at, temp_c, condition, rain_days_consecutive
- Hook
- Region.tempC/weather/rainDays · weatherTriggerActive() · weatherScore() — src/lib/det-data.ts
Dubai weather
NCM UAE / OpenWeather
- Feeds
- Dubai daytime temperature for the delta and the ≥ 28°C condition
- Fields
- observed_at, temp_c
- Hook
- DUBAI_TEMP — src/lib/det-data.ts
Public & school holidays (open)
Nager.Date (public, DE/GB/SA) · OpenHolidays API (German school holidays) · ferien-api.de fallback
- Feeds
- Official public holidays per area and German school holidays replace the bundled calendar for the holiday trigger and timeline (UK and KSA school dates stay bundled)
- Fields
- date, localName, counties[] (Nager) · startDate, endDate, subdivisions[].code, name[] (OpenHolidays)
- Hook
- fetchHolidays() → applyOpenData() — src/lib/open-data.ts; ferien-api fallback via cached server function src/lib/ferien-proxy.ts
- Docs
- https://date.nager.at · https://openholidaysapi.org
Not fetched yet
School & public holiday calendars
KMK (DE) · gov.uk & devolved governments (GB) · MoE KSA + Umm al-Qura (SA)
- Feeds
- Holiday departure windows per area for the holiday trigger and the timeline
- Fields
- area, name, start, end, kind (school|public)
- Hook
- Market.holidays — src/lib/markets/*.ts
- Docs
- https://www.kmk.org/service/ferien.html · https://www.gov.uk/school-term-holiday-dates
Dubai event calendar
Dubai Calendar (DET)
- Feeds
- Event pull rule and timeline bands (DSF, DSS, Food Festival, World Cup, Fitness Challenge)
- Fields
- event, start, end, audience_tags
- Hook
- DUBAI_EVENTS · eventOpportunities() — src/lib/det-data.ts
- Docs
- https://www.visitdubai.com/en/whats-on
Events & demand intelligence
PredictHQ
- Feeds
- Events in the source market and Dubai (13 authorised categories) → event triggers and Booked-layer context
- Fields
- id, title, category, start, end, location[lat,lng], country, rank, local_rank, phq_attendance, predicted_event_spend
- Hook
- DUBAI_EVENTS — src/lib/det-data.ts (replace with PredictHQ adapter)
- Docs
- https://docs.predicthq.com/
Optional — simulated values already cover this.
Exchange rates (ECB)
Frankfurter (open, no key)
- Feeds
- ECB reference exchange rates stored for historical analysis; dashboard monetary amounts are reported in USD ($)
- Fields
- date, rates.GBP, rates.USD
- Hook
- fetchFx() · convert() — src/lib/open-data.ts
- Docs
- https://frankfurter.dev
Not fetched yet
Exchange rates
ECB reference rates / SAMA
- Feeds
- Cross-market budget comparison in a reporting currency
- Fields
- date, base, quote, rate
- Hook
- fmtMoney() — src/lib/markets/index.ts
Optional — simulated values already cover this.