IP Geolocation for Travel & Hospitality — Geo-Rate Enforcement, OTA Carding Defence, Sanctions Screening, GDS Routing

Why travel & hospitality is its own axis: every search-result paint on a booking site is a four-jurisdiction decision in <40 ms — origin-country dynamic-pricing tier (legitimate price-discrimination per IATA Resolution 010e + HOTREC member-state guidance), OFAC + EU CONSILIUM + UK OFSI sanctions on the prospective traveller, EU OSS distance-sales VAT on the digital-booking fee (27 destination-VAT rates + Norway MVA + Switzerland VAT + UK VAT), and DAC7 platform-operator reporting (Council Directive 2021/514) for in-EU intermediaries. IP-layer signals are upstream of the rate-card render, the checkout payment-gate, the GDS inventory-call (Amadeus EU / Sabre US / Travelport APAC), and the post-booking AML/KYC eval. A wrong country resolve at search-paint either burns margin (1st-class fare quoted at LATAM-tier to a US-resident on a VPN) or breaches sanctions (Maldives villa booked from an IR-resolved IP via residential proxy without OFAC SDN screening).

The country an IP resolves to, the ASN it belongs to, and whether it’s a known datacenter, VPN, residential-proxy, or Tor exit are inputs to four separate travel + hospitality control surfaces:

  1. Geo-rate enforcement + dynamic-pricing per booking origin — every OTA, hotel-chain CRS, and airline IBE quotes a different rate per origin country (LATAM/SEA tiers vs US/EU/JP tiers vs MENA luxury tiers) — legitimate price-discrimination, but VPN/proxy arbitrage (NL-resident routing through a BR residential proxy to hit LATAM-tier rates) is a contract-violation per the booking-engine T&Cs and a margin-leak event. Hard-fail-closed: VPN/proxy/Tor at search → fall back to highest-tier rate (anti-arbitrage), residential-proxy ASN → block booking outright at checkout. Booking opened at LATAM-tier from a NL+VPN IP = ~€450 unit-margin leak per night on a 3-star Maldives villa.
  2. OTA carding + account-takeover defence at booking checkout — card-BIN country vs IP-country mismatch (>20-pt score), IP-velocity gating (>5 bookings/IP/h on a guest-checkout flow = automation), residential-proxy ASN block (Bright Data 212238/401116, Oxylabs 396982/60068, Smartproxy 62240/16276, IPRoyal 35916/174, Tier3 21859/32475 — same proxy networks driving 60-80% of OTA carding-fraud per Riskified 2024 report), datacenter ASN reject on non-corporate-booking flows. Carding loss on a hotel-OTA = ~€350 per disputed booking (chargeback + arbitration + cancellation-fee + commission claw-back from supplier).
  3. OFAC + EU + UK sanctions screening at booking-init — IR/KP/SY/CU/BY/RU/MM/VE/AF/SO hard-stop at first booking-action (search, login, checkout); EU CONSILIUM list (~2 000 SDN entries) + UK OFSI consolidated list + US OFAC SDN; dual-control on luxury-segment thresholds (yacht charter >€10 K, private jet >€20 K, Maldives/Seychelles/Bora Bora villa >€5 K/night = AML-flag + manual review). Per-country booking restrictions: US-citizen Cuba travel (12 OFAC General Licenses + ban on tourist-purpose travel + no Cuban-government-property), EU sanctions on Russian luxury-travel post-2022 (Council Reg. 833/2014 amended).
  4. GDS + inventory routing + EU OSS / DAC7 reporting — Amadeus (EU-hosted, Madrid + Erding DC) vs Sabre (US-hosted, Southlake TX) vs Travelport/Galileo (US + APAC) routing on inventory-fetch based on traveller residency + supplier residency; EU OSS distance-sales VAT on the digital booking-fee (27 destination-VAT rates: DE 19%, NL 21%, FR 20%, IE 23%, IT 22%, ES 21%, PL 23%, SE 25%, DK 25%, FI 25%, AT 20%, PT 23%, CZ 21%, HU 27%, GR 24%, RO 19%, BE 21%, BG 20%, HR 25%, CY 19%, EE 22%, LV 21%, LT 21%, LU 17%, MT 18%, SI 22%, SK 23%) + Norway MVA 25% + Switzerland VAT 8.1% + UK VAT 20%; DAC7 reporting (Directive 2021/514) requires reportable-platform-operators (EU-OTAs, EU-marketplaces) to report seller-residency + transaction-count + transaction-value per calendar year by Jan 31; HOTREC pricing-display compliance (separate display of taxes, resort-fees, cleaning-fees).

A single REST call to IP Geo API returns all four signal classes — country/region/city/lat-lon, ASN, threat-flags (VPN/proxy/Tor/hosting/relay), risk score — on every plan, no add-on SKU, ≤40 ms median in EU.

What travel & hospitality buyers care about (in order)

  1. Search-results-paint latency budget ≤ 40 ms. OTA/IBE/CRS search-results page must paint in ≤ 1 s on a 4G connection; the IP-resolve sits inside the first-paint path for geo-rate-tier + currency-display + sanctions-pre-gate. IP Geo API runs on EU edges (Hetzner Frankfurt) for ≤ 30-40 ms median across DE/NL/FR/IE/ES/IT/UK, ≤ 60 ms US-EU round-trip — well under the search-paint budget and ahead of GDS-inventory round-trip (typically 300-800 ms for Amadeus/Sabre/Travelport availability-search).
  2. DAC7 + EU OSS + OFAC audit-trail bundle. DAC7 (Directive 2021/514) requires reportable-platform-operators to retain seller + transaction + residency evidence for 5 years post-reporting-year; EU OSS requires per-transaction destination-country evidence for 10 years; OFAC requires SDN-screening retention for 5 years post-transaction. IP Geo API ships a deterministic-replay log-format on every paid tier — same country_code + region + is_vpn + is_proxy + risk_score at lookup-time gets persisted in the response envelope for audit-grade reconstruction by your compliance + tax-controller teams.
  3. Threat fields on every plan, not a paid add-on. Most US incumbents (MaxMind, ipinfo.io, ipstack) split datacenter/VPN/proxy classification into a paid Security Module or Privacy add-on. IP Geo API ships is_vpn, is_proxy, is_tor, is_hosting, is_relay, and a numeric risk_score on the free tier — critical for blocking residential-proxy carding on hotel-OTAs (Sift 2024: ~78% of OTA carding traffic originates from residential-proxy ASNs) and for geo-rate arbitrage detection on dynamic-pricing engines.
  4. ASN-level granularity for corporate-booking + travel-agency allowlisting. Country-only checks miss the distinction between a leisure-OTA guest-checkout (high carding risk, mandatory threat-gate) and a corporate-travel-platform / IATA-accredited agency booking (low carding risk, GDS-direct ASN, allowlisted at checkout). ASN + is_proxy flag lets the booking engine route corporate (AS-CWT, AS-AMEX-GBT, AS-BCD-TRAVEL, AS-FCM-TRAVEL) to a fast-lane checkout while leisure-guest gets the full threat-eval. We expose asn, asn_org, and is_proxy as first-class fields so the booking engine can fork policies at ASN granularity.
  5. EU residency + GDPR + DAC7 + ePrivacy posture. Traveller IPs cannot be transferred to a US vendor without GDPR §28 DPA + SCCs + TIA (Schrems II); cookieless DAC7-seller-residency-evidence preferred over cookie-based tracking under ePrivacy Directive 2002/58/EC + EU CJEU Planet49 (no consent required for IP-resolve as legitimate-interest §6(1)(f) on fraud-prevention + tax-compliance basis). The entire chain (IP-resolve, geo-rate-tier, OFAC-gate, OSS-VAT-calc, DAC7-residency-log) must be EU-data-residency end-to-end. IP Geo API is EU-only data-flow, signed DPA in 24h, no SCCs required.

The four travel & hospitality control surfaces, in code

1. Geo-rate enforcement + dynamic-pricing per booking origin (anti-arbitrage)

// /api/booking/quote.js — Node 20 / search-results paint, ≤40 ms hard budget
// Resolves IP → origin-country tier → pricebook tier; anti-arbitrage on VPN/proxy.
const fetch = require('undici').fetch;

// Pricebook tiers (multiplier on USD-base rack rate)
const TIER_MULTIPLIERS = {
  T1_EU_LUX:   { mult: 1.00, countries: ['DE','NL','FR','BE','LU','AT','DK','SE','FI','IE','IS','NO','CH','GB'] },
  T2_NA_LUX:   { mult: 1.05, countries: ['US','CA'] },
  T3_APAC_LUX: { mult: 1.10, countries: ['JP','KR','SG','HK','TW','IL','AE','QA','KW','BH'] },
  T4_EU_PER:   { mult: 0.85, countries: ['ES','IT','PT','GR','PL','CZ','HU','SK','RO','BG','HR','SI','EE','LV','LT','CY','MT'] },
  T5_LATAM:    { mult: 0.70, countries: ['BR','MX','AR','CL','CO','PE','UY','EC','CR','PA','DO'] },
  T6_SEA:      { mult: 0.65, countries: ['ID','TH','MY','PH','VN','LK','KH','LA'] },
  T7_INDIA:    { mult: 0.60, countries: ['IN','BD','NP','PK'] },
  T8_AFRICA:   { mult: 0.75, countries: ['ZA','NG','KE','EG','MA','TN','GH','CI','SN'] },
};

const SANCTIONS_HARDSTOP = new Set(['IR','KP','SY','CU','BY','RU','MM','VE','AF','SO']);

async function quoteRate(req, propertyId, baseRateUSD) {
  const ip = req.headers['cf-connecting-ip'] || req.ip;
  let geo;
  try {
    geo = await (await fetch(`https://ipgeo.10b.app/v1/${ip}?fields=country_code,is_vpn,is_proxy,is_tor,asn,risk_score`, {
      headers: { 'Authorization': `Bearer ${process.env.IPGEO_KEY}` },
      signal: AbortSignal.timeout(40)
    })).json();
  } catch {
    // Fail-conservative: on timeout, quote highest-tier rate (no arbitrage exposure)
    return { tier: 'T2_NA_LUX', mult: 1.05, rate: baseRateUSD * 1.05, reason: 'geo_timeout_default_high_tier' };
  }

  // Hard sanctions stop — refuse to render a rate
  if (SANCTIONS_HARDSTOP.has(geo.country_code)) return { error: 'sanctions_jurisdiction_blocked', status: 451 };

  // VPN / proxy / Tor → fall back to highest-tier rate (anti-arbitrage on rate-shopping bots + residential-proxy abuse)
  if (geo.is_vpn || geo.is_proxy || geo.is_tor) {
    return { tier: 'T2_NA_LUX', mult: 1.05, rate: baseRateUSD * 1.05, reason: 'anonymised_origin_anti_arbitrage' };
  }

  // Pin booking-tier to BIN-billing-country at checkout (defence in depth — IP geo is render-time, BIN is settlement-time)
  const tier = pickTier(geo.country_code);
  return { tier: tier.name, mult: tier.mult, rate: baseRateUSD * tier.mult, origin: geo.country_code, asn: geo.asn };
}

function pickTier(cc) {
  for (const [name, t] of Object.entries(TIER_MULTIPLIERS))
    if (t.countries.includes(cc)) return { name, mult: t.mult };
  return { name: 'T1_EU_LUX', mult: 1.00 };   // Default: EU-tier (highest-protection on margin)
}

2. OTA carding + account-takeover defence at booking checkout (hard-fail-closed)

# /api/booking/place-order.py — FastAPI / OTA checkout-place
# Called immediately before payment-authorisation; rejects on score >= 70 or residential-proxy ASN.
from fastapi import FastAPI, HTTPException, Request
import httpx, os

IPGEO_KEY = os.environ["IPGEO_KEY"]

# Residential-proxy ASNs — instant reject on OTA checkout
RES_PROXY_ASNS = {
    212238: 'Bright Data',     401116: 'Bright Data',
    396982: 'Oxylabs',         60068:  'Oxylabs',
    62240:  'Smartproxy',      16276:  'Smartproxy',
    35916:  'IPRoyal',         174:    'IPRoyal',
    21859:  'Tier3/Choopa',    32475:  'Tier3/Choopa',
}

# Corporate-travel-platform ASNs — allowlisted (skip threat-gate, route to fast-lane)
CORP_TRAVEL_ASNS = {
    'AS-CWT':         'Carlson Wagonlit Travel',
    'AS-AMEX-GBT':    'Amex GBT',
    'AS-BCD-TRAVEL':  'BCD Travel',
    'AS-FCM-TRAVEL':  'FCM Travel',
    'AS-EGENCIA':     'Egencia (Expedia)',
    'AS-NAVAN':       'Navan (TripActions)',
    'AS-AMADEUS':     'Amadeus IT Group',
    'AS-SABRE':       'Sabre',
}

async def place_order(request: Request, order: dict) -> dict:
    ip = request.headers.get('cf-connecting-ip') or request.client.host

    async with httpx.AsyncClient(timeout=0.04) as cx:
        r = await cx.get(f'https://ipgeo.10b.app/v1/{ip}',
            params={'fields': 'country_code,region,is_vpn,is_proxy,is_tor,is_hosting,is_relay,asn,asn_org,risk_score'},
            headers={'Authorization': f'Bearer {IPGEO_KEY}'})
    g = r.json()

    # Corporate-travel-platform fast-lane (TMC + agency bookings)
    asn_org = g.get('asn_org', '')
    is_corp = any(c in asn_org for c in CORP_TRAVEL_ASNS.keys())
    if is_corp:
        return {'route': 'corporate_fast_lane', 'origin': g['country_code'], 'asn_org': asn_org}

    # Hard reject — VPN/Tor/relay on consumer-OTA checkout
    if g['is_vpn'] or g['is_tor'] or g['is_relay']:
        raise HTTPException(403, 'anonymised_origin_blocked_on_payment_authorisation')

    # Hard reject — residential-proxy ASN (≥78% of OTA carding fraud per Sift 2024)
    if g['asn'] in RES_PROXY_ASNS:
        raise HTTPException(403, f'residential_proxy_blocked_{RES_PROXY_ASNS[g["asn"]]}')

    # Carding score — BIN-country vs IP-country mismatch
    bin_country = order.get('card_bin_country')
    score = 0
    if bin_country and bin_country != g['country_code']: score += 35
    if g['is_proxy']:    score += 30
    if g['is_hosting']:  score += 25
    if g['country_code'] != order.get('billing_address_country'): score += 20
    if g['country_code'] != order.get('check_in_country', g['country_code']): score += 10
    score += min(g['risk_score'], 30)

    if score >= 70:
        raise HTTPException(403, f'carding_score_{score}_threshold_exceeded')

    return {
        'route': 'consumer_checkout',
        'origin': g['country_code'],
        'carding_score': score,
        'asn': g['asn'],
        'audit_id': _audit_log_id(order, g),
    }

def _audit_log_id(order, geo): return f'ota-{order["id"]}-{geo["country_code"]}'

3. OFAC + EU + UK sanctions screening at booking-init (Node edge)

// /api/booking/sanctions-gate.js — Node edge / search-init + login + checkout
// Called on every booking-action; hard-fail-closed on sanctioned-jurisdiction or SDN.
const fetch = require('undici').fetch;

// OFAC + EU CONSILIUM + UK OFSI hardstop jurisdictions
const SANCTIONS_HARDSTOP = new Set(['IR','KP','SY','CU','BY','RU','MM','VE','AF','SO']);

// US-citizen Cuba-travel exception (OFAC 31 CFR §515 General Licenses 1-12, no tourist-purpose)
const CUBA_OFAC_GL_REQUIRED = new Set(['CU']);

// Luxury-segment AML thresholds (EUR equivalent)
const AML_THRESHOLDS = {
  yacht_charter:    10000,   // EU 4AMLD high-value-services threshold
  private_jet:      20000,
  villa_per_night:   5000,
  helicopter_xfer:   3000,
};

async function sanctionsGate(req, bookingType, valueEUR) {
  const ip = req.headers['cf-connecting-ip'] || req.ip;
  const sessionResidency = req.session?.residency_country;  // From prior KYC (passport scan, ID-verify)

  const geo = await (await fetch(`https://ipgeo.10b.app/v1/${ip}?fields=country_code,is_vpn,is_proxy,is_tor,risk_score`, {
    headers: { 'Authorization': `Bearer ${process.env.IPGEO_KEY}` },
    signal: AbortSignal.timeout(40)
  })).json();

  // Hard stop on sanctioned-jurisdiction origin (regardless of session residency)
  if (SANCTIONS_HARDSTOP.has(geo.country_code)) {
    return { allow: false, status: 451, reason: `sanctioned_origin_${geo.country_code}` };
  }

  // VPN/proxy/Tor on a sanctions-screened booking-flow = AML red-flag (compelled-disclosure under EU 6AMLD)
  if (geo.is_vpn || geo.is_proxy || geo.is_tor) {
    return { allow: false, status: 451, reason: 'anonymised_origin_aml_redflag', aml_log_id: _aml_log(req, geo) };
  }

  // US-resident booking Cuba = OFAC General License required (no tourist-purpose, must select category 1-12)
  if (sessionResidency === 'US' && CUBA_OFAC_GL_REQUIRED.has(req.body.destination_country)) {
    if (!req.body.ofac_general_license_category) {
      return { allow: false, status: 451, reason: 'ofac_general_license_required_for_us_to_cuba_travel',
               required_category: 'category_1_through_12' };
    }
  }

  // Luxury-segment AML — value-threshold + dual-control + EDD (Enhanced Due Diligence) trigger
  const threshold = AML_THRESHOLDS[bookingType];
  if (threshold && valueEUR >= threshold) {
    return {
      allow: true,
      route: 'manual_review_aml_edd',
      reason: `luxury_threshold_${threshold}_exceeded`,
      requires_pep_screen: true,
      requires_source_of_funds: true,
      aml_log_id: _aml_log(req, geo),
    };
  }

  // Default — allow with session-pinned origin for DAC7 + ePrivacy audit
  return { allow: true, route: 'standard_booking', origin: geo.country_code, audit_id: _aml_log(req, geo) };
}

function _aml_log(req, geo) { return `aml-${Date.now()}-${geo.country_code}`; }

4. GDS + inventory routing + EU OSS / DAC7 reporting (FastAPI/Python)

# /api/inventory/route-and-vat.py — FastAPI / inventory-fetch + tax-calc
# Picks GDS based on supplier residency; computes OSS-VAT on booking-fee; logs DAC7 evidence.
from fastapi import HTTPException, Request
import httpx, os

IPGEO_KEY = os.environ["IPGEO_KEY"]

# GDS routing — supplier-residency + traveller-residency drives choice
GDS_ROUTING = {
    'EU': {'gds': 'Amadeus',  'endpoint': 'https://amadeus.eu/v3/'},
    'UK': {'gds': 'Amadeus',  'endpoint': 'https://amadeus.eu/v3/'},
    'US': {'gds': 'Sabre',    'endpoint': 'https://sabre.us/v3/'},
    'CA': {'gds': 'Sabre',    'endpoint': 'https://sabre.us/v3/'},
    'APAC': {'gds': 'Travelport', 'endpoint': 'https://travelport.com/v3/'},
}

# EU OSS distance-sales VAT rates on digital booking-fee (selected; full 27)
OSS_VAT_RATES = {
    'DE': 0.19, 'NL': 0.21, 'FR': 0.20, 'IE': 0.23, 'IT': 0.22, 'ES': 0.21,
    'PL': 0.23, 'SE': 0.25, 'DK': 0.25, 'FI': 0.25, 'AT': 0.20, 'PT': 0.23,
    'CZ': 0.21, 'HU': 0.27, 'GR': 0.24, 'RO': 0.19, 'BE': 0.21, 'BG': 0.20,
    'HR': 0.25, 'CY': 0.19, 'EE': 0.22, 'LV': 0.21, 'LT': 0.21, 'LU': 0.17,
    'MT': 0.18, 'SI': 0.22, 'SK': 0.23,
    'NO': 0.25, 'CH': 0.081, 'GB': 0.20,
}

EU_MS = set(OSS_VAT_RATES.keys()) - {'NO','CH','GB'}

# DAC7 reportable-platform-operator (Council Directive 2021/514)
DAC7_REPORTABLE_PLATFORMS = {'booking_eu', 'airbnb_eu', 'expedia_eu', 'tripcom_eu'}

async def route_and_vat(request: Request, booking: dict) -> dict:
    ip = request.headers.get('cf-connecting-ip') or request.client.host

    async with httpx.AsyncClient(timeout=0.04) as cx:
        r = await cx.get(f'https://ipgeo.10b.app/v1/{ip}',
            params={'fields': 'country_code,region,is_vpn,is_proxy,asn,risk_score'},
            headers={'Authorization': f'Bearer {IPGEO_KEY}'})
    g = r.json()

    # GDS pick
    cc = g['country_code']
    gds_zone = 'EU' if cc in EU_MS or cc in ('NO','CH','GB') else 'APAC' if cc in ('SG','JP','HK','KR','TW','AU','NZ','MY','TH','ID','VN','PH','IN') else 'US' if cc in ('US','CA','MX','BR','AR','CL','CO') else 'EU'
    gds = GDS_ROUTING[gds_zone]

    # OSS-VAT on booking-fee (digital service, destination-VAT rule)
    fee_eur = booking['fee_eur']
    vat_rate = OSS_VAT_RATES.get(cc, 0.0)  # 0% if outside EU/EEA + UK + NO + CH (B2C, no reverse-charge)
    vat_eur = fee_eur * vat_rate

    # DAC7 evidence-log (5-year retention, Jan-31-annual report to lead MS authority)
    if booking.get('platform_id') in DAC7_REPORTABLE_PLATFORMS and cc in EU_MS:
        _dac7_log(booking, g, vat_eur)

    return {
        'gds': gds['gds'],
        'gds_endpoint': gds['endpoint'],
        'origin_country': cc,
        'vat_rate': vat_rate,
        'vat_eur': vat_eur,
        'oss_destination_ms': cc if cc in EU_MS else None,
        'dac7_logged': booking.get('platform_id') in DAC7_REPORTABLE_PLATFORMS and cc in EU_MS,
        'fee_eur_gross': fee_eur + vat_eur,
    }

def _dac7_log(b, g, vat): pass

Pricing math — when does IP Geo API pay for itself for a travel/hospitality operator?

Plan Lookups / month Median search-paint latency Threat fields Equivalent risk-loss reduction
Free (1K/day) 30 K ≤ 40 ms bundled Sandbox / staging — IBE/OTA flow QA, corporate-ASN allowlist tuning
Starter €29 ~1 M ≤ 40 ms bundled Single-brand boutique CRS ≤ 50 K monthly searches
Business €99 ~15 M ≤ 40 ms bundled, SLA, DAC7 + OSS audit log Mid-market OTA / chain CRS ≤ 1 M monthly bookings, full sanctions + AML log
Enterprise (POA) ≥ 50 M dedicated edges full + custom + signed DPA + SCC Tier-1 OTA (Booking/Expedia-class), 5-region GDS routing, DAC7 EU-lead-MS report

At Business €99/mo: a single blocked geo-rate arbitrage attempt on a Maldives villa (€450 margin/night) + a single blocked residential-proxy carding attempt (€350 chargeback) + a single sanctions-gate catch on a yacht-charter booking (€10K+ AML + 4AMLD penalty exposure) = recoups the €99 in well under 1 hour of operations. Most mid-market OTAs report Business-tier ROI in the first booking-week.

Honest limits — when IP geolocation is not the right signal

  1. CG-NAT regions — in MENA, parts of LATAM, and rural India, CG-NAT collapses thousands of subscribers behind one egress IP. Country-resolve stays accurate but city-resolve degrades; never gate a luxury-segment AML decision on city + ASN alone in CG-NAT-heavy markets. We expose city_confidence so the booking engine can fall back to country-only sanctions-gate + explicit traveller-residency attestation before checkout.
  2. iCloud Private Relay + Proxy-on-by-default OS-modes — Apple’s iCloud Private Relay shifts the egress IP to a Cloudflare/Akamai relay-block; we classify these as is_relay=true so the booking engine can prompt the traveller to disable Private Relay for the duration of the booking-checkout (ePrivacy + DAC7 attestation path) instead of hard-rejecting on is_proxy alone.
  3. Mobile-data IP rotation — 4G/5G subscribers can hop between cell-tower egress IPs mid-session; do not invalidate a booking-session on IP-change alone. Pin the booking-session’s geo-rate-tier + sanctions-jurisdiction to the at-search-init snapshot for the duration of the transaction.
  4. MaxMind is_anonymous_proxy deprecation — MaxMind sunset is_anonymous_proxy in 2024 Q3; if your existing fraud-engine Sigma rules reference it, migrate to is_proxy + is_vpn + is_relay + is_hosting composite. We expose all four for forward-compatibility on the carding-engine + AML-engine input contract.
  5. Geo-rate is not absolute — corporate + agency overrides — a NL-headquartered TMC booking on behalf of a US-corporate traveller appears as an EU-IP egress but the booked rate must follow corporate-policy + IATA-accredited-agency-deal codes, not the IP-tier. Always allowlist corporate-travel-platform ASNs (CWT/Amex GBT/BCD/FCM/Egencia/Navan) at checkout, route to fast-lane, and skip the consumer geo-rate-tier override.

Use-cases that compose with travel & hospitality

Every travel + hospitality stack composes 3-5 IP-layer use-cases. The relevant primary deep-dives:

Compare IP Geo API to the providers travel/hospitality teams evaluate

If you’re shortlisting vendors for an OTA / IBE / CRS rebuild, a sanctions-screening posture audit, or a DAC7 rollout, these head-to-heads cover the providers most often shortlisted in the IP-geolocation market:

Read also — narrative deep-dives

Seven 2026-dated comparison articles with code-level migration sketches and latency / pricing math at 100K / 1M / 10M req/mo:

Migration walkthroughs — drop-in code-level guides

Already on an incumbent? These step-by-step migration guides ship with field-by-field maps, code diffs, shadow-mode validation, and rollback notes:

Industry deep-dives

Other vertical-specific surfaces using the same IP Geo API primitives:


Get started — travel & hospitality procurement

Sign up at https://ipgeo.10b.app/pricing and start with a sandbox key today.


Get early access — 50% off for 12 months

First 100 signups lock in 50% off any paid plan for the first year. No credit card required — we’ll email you at launch.