T
TOMO
Developer Docs
BETA These docs are under partner review. Some features described are roadmap items, not yet shipped. Verify against your sandbox before relying on any contract.
● DRAFTv1.0.0mobility.book_airport_transfer

mobility.book_airport_transfer — Full Intent Specification

INTENT NAMESPACE: mobility
INTENT NAME:      book_airport_transfer
FULL ID:          mobility.book_airport_transfer
VERSION:          v1.0.0
STATUS:           draft
LAST UPDATED:     2026-05-10
TTBS WEIGHTS:     time 0.40 · taste 0.10 · budget 0.20 · safety 0.30

Airport transfer is a specialization of intracity ride with four locked structural additions: (a) flight_context block — airline, flight_number, scheduled_iso, terminal — drives intelligent dispatch; (b) meet_and_greet block — signage, placard name, meeting point — for arrivals; (c) flight_delay_handling semantics — partner MUST track flight and dispatch dynamically, not against scheduled_pickup_iso blindly; (d) free wait window for arrivals with explicit per-minute overage. Time weight rises to 0.40 (you cannot miss a flight) and safety to 0.30 (luggage + airport security context).


1. NATURAL LANGUAGE COVERAGE

Classifies IN

  • "ride to RGI airport tomorrow 4 AM"
  • "airport pickup from arrivals at 11pm Friday"
  • "cab to BLR airport for 6am flight"
  • "schedule airport drop for 2 days from now"
  • "pickup me from Mumbai airport when I land Tuesday"
  • "early morning airport cab"
  • "airport transfer with meet and greet"
  • "Indigo flight 6E-432 arrival pickup"
  • "round trip airport transfer for next weekend"

Classifies OUT — borderline NO

  • "ride to MG Road" → mobility.book_intracity_ride
  • "Hyderabad to Bangalore cab" → mobility.book_intercity_ride
  • "Goa package with airport transfers included" → mobility.book_outstation_package
  • "I'm at the airport, need a ride home" → mobility.book_intracity_ride (ASAP, no flight tracking value)
  • "rent self-drive from airport" → mobility.book_self_drive

MULTI-INTENT TRIGGERS

  • "airport pickup tomorrow 4am for my Indigo flight, also FASTag top-up" → mobility.book_airport_transfer + pay.fastag_topup
  • "airport drop for 6am flight and book hotel near terminal" → mobility.book_airport_transfer + travel.book_hotel
  • "Indigo 6E-432 arrival pickup and book a restaurant near airport" → mobility.book_airport_transfer + food.book_dine_in

2. INPUT — TOMO → PROVIDER

{
  "intent":          "mobility.book_airport_transfer",
  "intent_version":  "v1.0.0",
  "request_id":      "req_apt_8g2k_2026-05-10T03:30:00Z",
  "user_session_id": "anon_user_token_or_uid",

  "direction":       "pickup_to_airport",

  "pickup": {
    "lat":            17.4435,
    "lng":            78.3772,
    "address":        "HITEC City Main Road, Madhapur",
    "neighborhood":   "Madhapur",
    "city":           "Hyderabad",
    "pincode":        "500081",
    "state_code":     "TS",
    "country_code":   "IN",
    "place_kind":     "home",
    "instructions":   "Building gate B; second tower"
  },

  "airport": {
    "iata_code":     "HYD",
    "icao_code":     "VOHS",
    "airport_name":  "Rajiv Gandhi International Airport",
    "city":          "Hyderabad",
    "terminal":      "T1",
    "is_international": false,
    "drop_zone":     "departures_curbside",
    "pickup_zone":   "arrivals_curbside_a"
  },

  "flight_context": {
    "airline_code":           "6E",
    "airline_name":           "IndiGo",
    "flight_number":          "6E-432",
    "scheduled_iso":          "2026-05-11T06:00:00+05:30",
    "departure_or_arrival":   "departure",
    "flight_status":          "on_time",
    "real_time_tracking_consent_given": true,
    "pnr_number_optional":    "ABCDEF",
    "pnr_provided":           true
  },

  "intent_kind":         "scheduled",
  "scheduled_pickup_iso": "2026-05-11T03:30:00+05:30",
  "buffer_minutes_before_flight": 150,

  "party": {
    "passenger_count":  2,
    "luggage_pieces":   4,
    "luggage_size":     "checkin",
    "minor_count":      0,
    "senior_count":     1
  },

  "preferences": {
    "vehicle_kinds_acceptable":   ["sedan", "suv", "premium_sedan"],
    "budget_band":                "good",
    "budget_max_inr":              1200,
    "max_eta_minutes":             10,
    "ac_required":                 true,
    "female_driver_required":      false,
    "ev_only":                     false,
    "wheelchair_accessible_required": false,
    "child_seat_required":         false,
    "pet_friendly_required":       false,
    "no_pool":                     true,
    "include_meet_and_greet":     true,
    "placard_name":                "K. Krishna",
    "include_porter_assistance":  true,
    "max_seat_capacity_min":       4
  },

  "route_context": {
    "estimated_distance_km":   28.5,
    "estimated_duration_min":  47,
    "involves_toll":           true,
    "toll_count":              1,
    "involves_highway":        true,
    "weather_celsius":         24,
    "rain_probability_pct":    20,
    "current_aqi":             142,
    "is_late_night_pickup":    true,
    "is_late_night_arrival":   false,
    "is_surge_window":         false
  },

  "context": {
    "user_locale":          "en-IN",
    "user_currency_pref":   "INR",
    "trip_purpose":         "airport_dropoff",
    "trust_signals": {
      "is_repeat_customer":          true,
      "prior_airport_transfers_with_partner": 5,
      "user_account_age_days":       312,
      "fastag_present":              true,
      "fastag_balance_inr":          245
    }
  }
}
Field Type Constraint Notes
intent string REQUIRED, equals "mobility.book_airport_transfer"
direction enum REQUIRED, STRICT pickup_to_airport | airport_to_destination | round_trip
airport.iata_code string REQUIRED, 3 chars ISO 8601
airport.icao_code string REQUIRED, 4 chars
airport.terminal string REQUIRED "T1" / "T2" / "T3" / "T1A" etc.
airport.is_international bool REQUIRED drives buffer_minutes default
airport.drop_zone enum REQUIRED, see §5 only relevant if direction=pickup_to_airport
airport.pickup_zone enum REQUIRED, see §5 only relevant if direction=airport_to_destination
flight_context.airline_code string REQUIRED IATA 2-char
flight_context.flight_number string REQUIRED "6E-432" canonical form
flight_context.scheduled_iso ISO_DATETIME REQUIRED flight time, not pickup time
flight_context.departure_or_arrival enum REQUIRED, STRICT departure | arrival matches direction
flight_context.real_time_tracking_consent_given bool REQUIRED gates dynamic dispatch
flight_context.pnr_provided bool REQUIRED enables flight-data lookup
intent_kind enum REQUIRED, STRICT scheduled airport ALWAYS scheduled, never asap
scheduled_pickup_iso ISO_DATETIME REQUIRED for departures: flight - buffer; for arrivals: scheduled flight ETA + buffer
buffer_minutes_before_flight int REQUIRED, ≥0 for departures: how early to reach airport
preferences.include_meet_and_greet bool REQUIRED drives signage requirement
preferences.placard_name string REQUIRED empty string if not requesting M&G
preferences.include_porter_assistance bool REQUIRED luggage assist
route_context.is_late_night_pickup bool REQUIRED pickup_local_time in [22:30, 05:30)

Anti-fabrication preamble (universal): no paid placement, no urgency text, no commission-influenced fields.


3. PROVIDER TOOLS

Tool 1: get_airport_transfer_estimates

PURPOSE:        return options for airport transfer
INPUT:          §2 request body
OUTPUT:         { options: AirportTransferOption[], result_token, expires_at }
SLA:            p50 < 500ms, p95 < 1200ms
RATE LIMIT:     ≤ 2/sec per user

Tool 2: book_airport_transfer

PURPOSE:        commit transfer
INPUT:          { option_id, payment_token, request_id, idempotency_key, user_phone, otp_required }
OUTPUT:         { ride_ref, status, driver, vehicle, fare_quote, otp_for_driver, meet_and_greet_kit }
SLA:            p95 < 4000ms
IDEMPOTENCY:    REQUIRED on idempotency_key

Tool 3: track_airport_transfer

PURPOSE:        live state including flight-aware dispatch state
INPUT:          { ride_ref, request_id }
OUTPUT:         AirportTransferTrack (§4)
SLA:            p95 < 400ms
RATE LIMIT:     ≤ 1 every 5s

Tool 4: cancel_airport_transfer

PURPOSE:        cancel
INPUT:          { ride_ref, reason, request_id }
OUTPUT:         { status, cancellation_charge_inr, refund_amount_inr }
SLA:            p95 < 2000ms

Tool 5: update_pickup_for_flight_delay

PURPOSE:        adjust pickup automatically when partner detects flight delay (arrivals only)
INPUT:          { ride_ref, new_flight_eta_iso, request_id }
OUTPUT:         { revised_pickup_iso, free_wait_extension_minutes, status }
SLA:            p95 < 1500ms

Tool 6: confirm_meet_and_greet

PURPOSE:        confirm driver has set up signage at meeting point
INPUT:          { ride_ref, photo_url_signage, request_id }
OUTPUT:         { acknowledged: true, meeting_point_address }
SLA:            p95 < 1500ms

Tool 7: rate_airport_transfer

PURPOSE:        post-trip rating
INPUT:          { ride_ref, rating_5star, comment, tip_inr, request_id }
OUTPUT:         { acknowledged: true }
SLA:            p95 < 800ms

Tool 8: share_trip_status

PURPOSE:        tokenized live tracking URL
INPUT:          { ride_ref, recipient_phone_optional, request_id }
OUTPUT:         { share_url, expires_at }
SLA:            p95 < 500ms

All eight REQUIRED.


4. RESPONSE SHAPE

AirportTransferOption (returned by get_airport_transfer_estimates)

id:                               string, REQUIRED
option_token:                     string, REQUIRED
expires_at:                       ISO_DATETIME, REQUIRED

vehicle_kind:                     STRICT ENUM, REQUIRED       # see §5
vehicle_class:                    STRICT ENUM, REQUIRED
display_label:                    string, REQUIRED
seat_capacity:                    int, REQUIRED, ≥1
luggage_capacity:                 STRICT ENUM, REQUIRED       # airport luggage tends large

eta:
  pickup_minutes:                 int, REQUIRED               # against scheduled_pickup_iso
  trip_minutes:                   int, REQUIRED
  total_minutes:                  int, REQUIRED
  drivers_within_radius_count:    int, REQUIRED, ≥0
  closest_driver_km:              float, REQUIRED, ≥0
  airport_arrival_eta_iso:        ISO_DATETIME, REQUIRED       # for departures: when user reaches terminal
  buffer_minutes_actual:          int, REQUIRED                # actual buffer vs requested

flight_dispatch:
  real_time_tracking_active:      boolean, REQUIRED            # tracks live flight if consent given
  flight_status_observed:         STRICT ENUM, REQUIRED        # see §5
  observed_flight_iso:            ISO_DATETIME, REQUIRED       # latest tracked time
  pickup_auto_adjusts_on_delay:   boolean, REQUIRED            # arrivals only
  free_wait_minutes_arrivals:     int, REQUIRED, ≥0            # 0 if departures
  per_minute_wait_charge_inr:     INR_INTEGER, REQUIRED        # 0 within free window

fare:
  total_inr:                      INR_INTEGER, REQUIRED
  base_inr:                       INR_INTEGER, REQUIRED
  per_km_inr:                     float, REQUIRED
  per_minute_inr:                 float, REQUIRED
  airport_pickup_charge_inr:      INR_INTEGER, REQUIRED        # 0 if departures (only for arrivals direction)
  airport_drop_charge_inr:        INR_INTEGER, REQUIRED        # 0 if arrivals
  airport_entry_charge_inr:       INR_INTEGER, REQUIRED        # some airports (BLR T2)
  surge_multiplier:               float, REQUIRED, ≥1.0
  surge_reason:                   STRICT ENUM, REQUIRED
  toll_inr:                       INR_INTEGER, REQUIRED
  toll_count:                     int, REQUIRED, ≥0
  late_night_inr:                 INR_INTEGER, REQUIRED
  highway_charge_inr:             INR_INTEGER, REQUIRED
  parking_charge_inr:             INR_INTEGER, REQUIRED
  meet_and_greet_charge_inr:      INR_INTEGER, REQUIRED        # 0 if not requested
  porter_assistance_inr:          INR_INTEGER, REQUIRED        # 0 if not requested
  platform_fee_inr:               INR_INTEGER, REQUIRED
  gst_inr:                        INR_INTEGER, REQUIRED
  rider_tip_optional_inr:         INR_INTEGER, REQUIRED
  fare_breakdown_text:            string, REQUIRED
  is_upfront_fare:                boolean, REQUIRED
  fare_locked_until_iso:          ISO_DATETIME, REQUIRED

meet_and_greet:
  available:                      boolean, REQUIRED
  placard_supported:              boolean, REQUIRED
  placard_format:                 STRICT ENUM, REQUIRED        # see §5
  meeting_point_kind:             STRICT ENUM, REQUIRED        # see §5
  meeting_point_address:          string, REQUIRED
  meeting_point_lat:              float, REQUIRED
  meeting_point_lng:              float, REQUIRED
  porter_available:               boolean, REQUIRED
  porter_languages:               array<RFC_3066_LOCALE>, REQUIRED, ≥1
  signage_photo_required:         boolean, REQUIRED            # before user arrives

vehicle_amenities:
  ac:                             boolean, REQUIRED
  music_on_demand:                boolean, REQUIRED
  charging_port:                  boolean, REQUIRED
  wifi_in_cab:                    boolean, REQUIRED
  bottled_water:                  boolean, REQUIRED
  newspaper:                      boolean, REQUIRED
  pet_friendly:                   boolean, REQUIRED
  child_seat_available:           boolean, REQUIRED
  child_seat_kind:                STRICT ENUM, REQUIRED
  wheelchair_accessible:          boolean, REQUIRED
  oversized_luggage_supported:    boolean, REQUIRED            # for international travel

vehicle_meta:
  age_years:                      int, REQUIRED
  fuel_kind:                      STRICT ENUM, REQUIRED
  ev_battery_charge_pct:          int, REQUIRED, 0-100
  ev_range_km_remaining:          int, REQUIRED
  emission_norm:                  STRICT ENUM, REQUIRED
  registration_state_code:        string, REQUIRED
  vehicle_class_certification:    STRICT ENUM, REQUIRED
  comprehensive_insurance:        boolean, REQUIRED
  insurance_valid_until_iso:      ISO_DATE, REQUIRED
  fitness_certificate_valid_until_iso: ISO_DATE, REQUIRED
  puc_valid_until_iso:            ISO_DATE, REQUIRED
  permit_kind:                    STRICT ENUM, REQUIRED
  airport_entry_permit_held:      boolean, REQUIRED            # required for airport pickup
  airport_entry_permit_number:    string, REQUIRED             # state RTO airport permit
  commercial_aggregator_permit_number: string, REQUIRED
  vehicle_color:                  string, REQUIRED

driver_meta:
  driver_id:                      string, REQUIRED
  display_name:                   string, REQUIRED
  photo_url:                      URL, REQUIRED
  rating_avg:                     float, REQUIRED, 0-5
  rides_completed_total:          int, REQUIRED, ≥0
  airport_transfers_completed:    int, REQUIRED, ≥0
  partner_account_age_days:       int, REQUIRED, ≥0
  languages_spoken:               array<RFC_3066_LOCALE>, REQUIRED, ≥1
  female_driver:                  boolean, REQUIRED
  age_band:                       STRICT ENUM, REQUIRED
  experience_years_driving:       int, REQUIRED, ≥0
  airport_route_familiarity:      STRICT ENUM, REQUIRED        # see §5
  on_time_arrival_rate_30d:       float, REQUIRED, 0-1         # honest, audited

driver_kyc:
  dl_verified:                    boolean, REQUIRED
  dl_number_masked:               string, REQUIRED
  dl_valid_until_iso:             ISO_DATE, REQUIRED
  rc_verified:                    boolean, REQUIRED
  aadhaar_verified:               boolean, REQUIRED
  pan_verified:                   boolean, REQUIRED
  background_check_passed:        boolean, REQUIRED
  background_check_iso:           ISO_DATETIME, REQUIRED
  badge_id_displayed:             boolean, REQUIRED
  airport_security_clearance_held: boolean, REQUIRED            # for some airports

safety_features:
  sos_button_in_app:              boolean, REQUIRED
  trip_share_supported:           boolean, REQUIRED
  in_app_chat_supported:          boolean, REQUIRED
  in_app_call_supported:          boolean, REQUIRED
  emergency_contact_alerts:       boolean, REQUIRED
  cctv_in_cab:                    boolean, REQUIRED
  panic_alert_to_local_police:    boolean, REQUIRED
  driver_drowsiness_detection:    boolean, REQUIRED
  speed_limit_governing:          boolean, REQUIRED
  flight_delay_auto_adjusts:      boolean, REQUIRED            # arrivals

route_quality:
  estimated_distance_km:          float, REQUIRED
  estimated_duration_min:         int, REQUIRED
  highway_kms:                    float, REQUIRED
  inner_road_kms:                 float, REQUIRED
  toll_passes:                    array, REQUIRED, may be empty
  airport_access_road_quality:    STRICT ENUM, REQUIRED        # see §5

cancellation:
  free_cancel_within_minutes:     int, REQUIRED
  cancel_charge_after_grace_inr:  INR_INTEGER, REQUIRED
  no_show_charge_inr:             INR_INTEGER, REQUIRED
  driver_cancel_compensation_inr: INR_INTEGER, REQUIRED
  cancel_charge_post_dispatch_inr: INR_INTEGER, REQUIRED        # if cancel after driver dispatched

fastag_check:
  toll_count_on_route:            int, REQUIRED, ≥0
  fastag_required:                boolean, REQUIRED
  estimated_toll_total_inr:       INR_INTEGER, REQUIRED
  user_fastag_balance_sufficient: boolean, REQUIRED

freshness:
  data_last_synced_iso:           ISO_DATETIME, REQUIRED

_provider:
  name:                           string, REQUIRED
  tomo_partner_id:                string, REQUIRED
  partner_tier:                   STRICT ENUM, REQUIRED
  deep_link:                      URL, REQUIRED
  customer_support_phone:         string, REQUIRED
  customer_support_24x7:          boolean, REQUIRED
  in_app_chat_supported:          boolean, REQUIRED
  partner_airport_transfer_volume_30d: int, REQUIRED, ≥0
  partner_airport_on_time_rate_30d:    float, REQUIRED, 0-1     # honest, audited

AirportTransferTrack (returned by track_airport_transfer)

ride_ref:                         string, REQUIRED
status:                           STRICT ENUM, REQUIRED
status_updated_iso:               ISO_DATETIME, REQUIRED
status_history:                   array, REQUIRED, ≥1

flight_dispatch:
  current_flight_status:          STRICT ENUM, REQUIRED
  current_flight_eta_iso:         ISO_DATETIME, REQUIRED
  pickup_iso_current:             ISO_DATETIME, REQUIRED        # may differ from scheduled_pickup_iso after auto-adjust
  pickup_auto_adjusted_count:     int, REQUIRED, ≥0
  free_wait_remaining_minutes:    int, REQUIRED, ≥0

driver:
  driver_id:                      string, REQUIRED
  display_name:                   string, REQUIRED
  phone_masked:                   string, REQUIRED
  photo_url:                      URL, REQUIRED
  rating_avg:                     float, REQUIRED, 0-5
  in_app_chat_supported:          boolean, REQUIRED
  in_app_call_supported:          boolean, REQUIRED

vehicle:
  vehicle_kind:                   STRICT ENUM, REQUIRED
  display_label:                  string, REQUIRED
  color:                          string, REQUIRED
  plate_masked:                   string, REQUIRED

location:
  current_lat:                    float, REQUIRED
  current_lng:                    float, REQUIRED
  heading_degrees:                float, REQUIRED, 0-360
  speed_kmh:                      float, REQUIRED, ≥0
  location_updated_iso:           ISO_DATETIME, REQUIRED
  status:                         STRICT ENUM, REQUIRED

eta:
  to_pickup_minutes:              int, REQUIRED
  to_drop_minutes:                int, REQUIRED                # 0 for arrivals
  airport_arrival_eta_iso:        ISO_DATETIME, REQUIRED
  revised_fare_inr:               INR_INTEGER, REQUIRED
  detour_minutes:                 int, REQUIRED

meet_and_greet:
  status:                         STRICT ENUM, REQUIRED        # see §5
  signage_setup_iso:              ISO_DATETIME, REQUIRED       # may equal future iso if pending
  signage_photo_url:              URL, REQUIRED                # may be empty until set up

ride_safety:
  on_route:                       boolean, REQUIRED
  unusual_stop_detected:          boolean, REQUIRED
  trip_share_active:              boolean, REQUIRED
  trip_share_url:                 URL, REQUIRED

fastag:
  next_toll_distance_km:          float, REQUIRED
  next_toll_amount_inr:           INR_INTEGER, REQUIRED
  user_fastag_balance_sufficient_for_remaining_tolls: boolean, REQUIRED

support_phone:                    string, REQUIRED
support_email:                    string, REQUIRED

Forbidden fields

paid_placement_score | sponsored_rank | promotion_priority |
artificial_demand_text | fake_recent_booking_text |
auto_inflate_on_time_arrival_rate | partner_paid_for_top_listing |
fake_airport_security_clearance | hidden_airport_entry_charge

5. CONTROLLED VOCABULARIES

direction

pickup_to_airport | airport_to_destination | round_trip

airport.drop_zone

departures_curbside | departures_garage | premium_lounge_drop |
international_departures | domestic_departures | private_terminal_drop

airport.pickup_zone

arrivals_curbside_a | arrivals_curbside_b | arrivals_curbside_c |
arrivals_premium_pickup | international_arrivals | domestic_arrivals |
private_terminal_pickup | hotel_shuttle_pickup

flight_context.departure_or_arrival

departure | arrival

flight_context.flight_status (input + observed)

on_time | delayed_minor | delayed_major | rerouted | cancelled |
diverted | landed | departed | scheduled

vehicle_kind

sedan | suv | premium_sedan | premium_suv | luxury_sedan | luxury_suv |
xl_van | wheelchair_accessible_van | ev_sedan | ev_suv

vehicle_class

economy | comfort | premium | luxury | xl

AirportTransferOption.luggage_capacity

small | medium | large | xl | xxl

pickup.place_kind

home | office | hotel | restaurant | mall | hospital | landmark | other

meet_and_greet.placard_format

none | digital_tablet | physical_paper | electronic_led | branded_partner_signage

meet_and_greet.meeting_point_kind

arrivals_gate | premium_lounge | terminal_a_curbside | terminal_b_curbside |
international_arrivals_hall | domestic_arrivals_hall | private_terminal |
hotel_shuttle_zone | parking_level

vehicle_meta.fuel_kind

petrol | diesel | cng | lpg | ev_full | hybrid | bs6_petrol | bs6_diesel

vehicle_meta.emission_norm

bs3 | bs4 | bs6 | ev | unknown_legacy

vehicle_meta.permit_kind

contract_carriage | aggregator_permit | tourist | airport_aggregator

Airport REQUIRES aggregator_permit OR airport_aggregator (BLR/HYD/DEL airport-specific) OR tourist.

vehicle_meta.vehicle_class_certification

commercial_yellow_plate | aggregator_white_with_yellow_strip | tourist

vehicle_amenities.child_seat_kind

none | infant | toddler | booster | universal

driver_meta.airport_route_familiarity

new | familiar_50_to_200_trips | expert_200_plus_trips

driver_meta.age_band

21-30 | 31-40 | 41-55 | 56+

route_quality.airport_access_road_quality

expressway | highway | mixed | inner_road

AirportTransferOption.fare.surge_reason

none | rain | weekend_evening | morning_peak | late_night | major_event |
festival | airport_demand | rider_shortage | flight_arrival_burst

AirportTransferTrack.status

scheduled | tracking_flight | driver_assigned | driver_dispatched |
driver_arriving | arrived_at_pickup | otp_required | trip_started |
en_route_to_airport | nearby_airport | reached_airport_drop |
en_route_from_airport | nearby_drop | reached_drop |
flight_delayed_pickup_adjusted | meeting_user_at_arrivals |
completed | cancelled_by_user | cancelled_by_driver | failed

AirportTransferTrack.location.status

heading_to_pickup | at_pickup | trip_in_progress | nearby_airport |
in_airport_holding_zone | at_arrivals_gate | at_meeting_point |
nearby_drop | reached_drop

AirportTransferTrack.meet_and_greet.status

not_requested | scheduled | signage_set_up | greeted_user | escorted_to_vehicle |
not_applicable_departures

cancel_airport_transfer.reason

user_changed_mind | flight_cancelled_by_airline | wrong_address |
driver_too_far | driver_unresponsive | safety_concern | weather_block |
no_longer_needed | found_alternative | emergency

context.trip_purpose

airport_dropoff | airport_pickup | business_trip | leisure | family_visit |
medical_visit | religious_pilgrimage | wedding_event | emergency | other

6. TTBS DIMENSIONS

Per-domain weights (locked; airport override)

mobility (airport_transfer): { time: 0.40, taste: 0.10, budget: 0.20, safety: 0.30 }

Time stays high (cannot miss flight). Budget down to 0.20 (users will pay more for airport reliability). Safety up to 0.30 (luggage handling + airport security context).

TIME

SIGNALS USED:
  - eta.airport_arrival_eta_iso ≤ flight_iso − buffer  HARD FILTER (departures)
  - flight_dispatch.real_time_tracking_active=true     weight 0.20
  - flight_dispatch.pickup_auto_adjusts_on_delay (arrivals) weight 0.20
  - driver_meta.airport_route_familiarity (expert)    weight 0.15
  - driver_meta.on_time_arrival_rate_30d              weight 0.25
  - eta.pickup_minutes                                weight 0.20

USER BAND HANDLING:
  - higher buffer_minutes → loosen filter
  - "international flight" → buffer auto-bumped to 180 min if user gave less

TASTE

SIGNALS USED:
  - vehicle.year_of_manufacture (newer = better)       weight 0.15
  - vehicle_amenities match w/ user prefs              weight 0.30
  - meet_and_greet.placard_format quality              weight 0.15
  - vehicle_amenities.oversized_luggage_supported (international) weight 0.20
  - vehicle_amenities.bottled_water + newspaper        weight 0.10
  - languages_spoken match user_locale                 weight 0.10

HARD FILTERS:
  - ac_required + ac=false → drop
  - oversized_luggage_supported=false AND luggage_size=oversized → drop

BUDGET

SIGNALS USED:
  - fare.total_inr vs band:
      ok    → sedan / hatchback
      good  → premium_sedan / suv
      great → luxury_sedan / luxury_suv / private_terminal pickup
  - fare.is_upfront_fare=true                           weight 0.20
  - surge_multiplier (lower=better)                     weight 0.15
  - airport_entry_charge_inr disclosed up-front         weight 0.10

HARD FILTERS:
  - fare.total_inr > preferences.budget_max_inr → drop

SAFETY

SIGNALS USED:
  - driver_kyc.background_check_passed                 HARD FILTER
  - driver_kyc.airport_security_clearance_held         HARD FILTER (some airports require)
  - driver_kyc.dl_verified                             HARD FILTER
  - vehicle_meta.comprehensive_insurance               HARD FILTER
  - vehicle_meta.airport_entry_permit_held             HARD FILTER
  - vehicle_meta.permit_kind in (aggregator|airport_aggregator|tourist) HARD FILTER
  - safety_features.sos_button_in_app                  weight 0.10
  - safety_features.flight_delay_auto_adjusts          weight 0.20  (arrivals)
  - safety_features.cctv_in_cab                        weight 0.10
  - safety_features.driver_drowsiness_detection        weight 0.10
  - driver_meta.airport_transfers_completed (≥50)      weight 0.20
  - driver_meta.female_driver
      (boosted if female_driver_required)              weight 0.20
  - is_late_night_pickup → safety weight scales 1.4x

HARD FILTERS:
  - female_driver_required → drop male drivers
  - wheelchair_accessible_required → drop non-wheelchair
  - child_seat_required → drop without seat

Hidden ranking factor

information_completeness_score weight 0.10.

FASTag check

Per universal rule: surface FASTag balance vs estimated_toll_total_inr if route_context.involves_toll.


7. COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/{tomo_partner_id}
X-TOMO-Timestamp: <ms>
X-TOMO-Signature: sha256=<hex>

{
  "intent":            "mobility.book_airport_transfer",
  "intent_version":    "v1.0.0",
  "external_id":       "UBER-APT-XYZ",
  "amount_inr":         1140,
  "closed_at":         "2026-05-11T05:48:00+05:30",
  "request_id":        "req_apt_8g2k_...",
  "status":            "completed",
  "ride_ref":          "UBER-APT-XYZ",
  "started_at":        "2026-05-11T03:35:00+05:30",
  "completed_at":      "2026-05-11T04:32:00+05:30",
  "airport_iata":      "HYD",
  "flight_number":     "6E-432",
  "flight_actual_iso": "2026-05-11T06:15:00+05:30",
  "buffer_minutes_actual": 103,
  "distance_traveled_km": 28.7,
  "duration_minutes":   57,
  "promised_arrival_iso": "2026-05-11T04:30:00+05:30",
  "actual_arrival_iso":   "2026-05-11T04:32:00+05:30",
  "free_wait_used_minutes": 0,
  "wait_overage_charge_inr": 0,
  "currency":          "INR",
  "fare_breakdown_total_inr": 1140,
  "rider_tip_inr":       0,
  "ratings_pending":     true,
  "notes":              ""
}

Status enum: completed | cancelled_by_user | cancelled_by_driver | failed | rerouted_with_extra_charge | flight_cancelled_refunded


8. WIDGET

WIDGET TYPE:        airport_transfer_options
SOURCE:             src/widgets/types.ts
TYPE NAME:          AirportTransferOptionsPayload
RENDERED IN:        components/widgets/AirportTransferOptionsWidget.tsx

Default: 3 stacked rows showing vehicle_kind, eta-to-airport, fare with airport-charge + meet-and-greet line callouts, on-time-arrival-rate badge. Tap row → confirmation card with full fare breakdown including airport entry + porter + meet-and-greet rates → "Book". Then AirportTransferTrackingCard with live driver location + flight tracking strip + meet-and-greet status.


9. CACHING POLICY

Call TTL Rationale
get_airport_transfer_estimates 30s demand + surge move fast at peak
track_airport_transfer 0s always live
book_airport_transfer 0s
cancel_airport_transfer 0s
update_pickup_for_flight_delay 0s
confirm_meet_and_greet 0s
Failure responses 0s

10. ERROR CODES

Code HTTP Meaning TOMO behavior
NO_DRIVERS_AVAILABLE 503 none with airport permit retry or fall back
OUT_OF_SERVICE_AREA 400 pickup outside coverage surface
AIRPORT_PERMIT_NOT_HELD 403 partner not authorized for airport pickup surface alternate
OPTION_EXPIRED 410 option_token invalid re-quote
FLIGHT_NOT_FOUND 400 flight_number lookup failed proceed without tracking
FLIGHT_TRACKING_REJECTED 401 airline data API rejected dispatch on scheduled_pickup_iso
PAYMENT_DECLINED 402 gateway rejection surface
OTP_FAILED 401 OTP-at-pickup mismatch surface
RIDE_NOT_FOUND 404 ride_ref doesn't exist surface
ALREADY_CANCELLED 409 duplicate cancel idempotent return
MEET_AND_GREET_FAILED 503 driver couldn't set up signage surface, attempt rebook
WAIT_OVERAGE 200 user exceeded free wait charge captured automatically
FASTAG_INSUFFICIENT 400 balance low top-up CTA
WEATHER_BLOCK 503 weather closure suggest reschedule

11. SANDBOX → PRODUCTION CHECKLIST

[ ] All §2 inputs validated, request_id echoed
[ ] get_airport_transfer_estimates returns ≥3 options for major airports (HYD, BLR, DEL, BOM)
[ ] All §4 required fields populated with REAL data
[ ] Real-time flight tracking integration verified (FlightAware, FlightStats, or equivalent)
[ ] pickup_auto_adjusts_on_delay tested with simulated 60min delay
[ ] driver_kyc + vehicle_meta truthful + verifiable
[ ] airport_entry_permit_number verified per state RTO
[ ] airport_security_clearance verified for airports requiring (DEL T3, BOM T2)
[ ] book_airport_transfer returns ride_ref + driver assignment within SLA
[ ] track_airport_transfer returns location ≤5s old + flight strip live
[ ] cancel respects free_cancel_within_minutes window
[ ] Meet-and-greet flow tested with photo confirmation in sandbox
[ ] Free wait window enforced; overage charged precisely
[ ] CPC webhook arrives within 60s of trip completion
[ ] HMAC verification passes
[ ] No forbidden fields anywhere
[ ] partner_airport_on_time_rate_30d audited against TOMO sample
[ ] SOS button tested with TOMO ops monitoring
[ ] No paid placement / sponsored signals
[ ] customer_support_24x7 verified by TOMO field call
[ ] Aggregator + airport-aggregator permit certificates uploaded

12. ANTI-FABRICATION RULES

RULE 1 — No paid placement signals.

RULE 2 — No fake driver ratings.

RULE 3 — No fake on_time_arrival_rate_30d.
  rate must come from partner's own CPC ledger of completed airport transfers.
  TOMO samples 1% rides and validates against airport gate-camera ETAs where
  available. Mismatch >5% = breach.

RULE 4 — Vehicle plate must match dispatched vehicle.

RULE 5 — Fare displayed must be honored.
  is_upfront_fare=true means fare_locked_until_iso. Free-wait overage is the
  ONLY post-trip increase allowed (and must be displayed live during wait).

RULE 6 — Driver KYC + airport permit claims must be verifiable.

RULE 7 — Flight tracking must be real.
  real_time_tracking_active=true requires actual airline data feed. Fake
  tracking that doesn't auto-adjust on real delays = breach + safety hazard.

RULE 8 — No surge gaming during flight_arrival_burst.
  surge_multiplier > 1.0 with reason=flight_arrival_burst must be backed by
  arrivals-volume telemetry. Inflating surge for arrivals demand = breach.

RULE 9 — Cancel charges must match displayed thresholds.

RULE 10 — No commission-based response shaping.

RULE 11 — Meet-and-greet signage must actually appear.
  signage_photo_url at meet_and_greet status=signage_set_up MUST show actual
  signage at the meeting point (not a stock photo). TOMO ops samples.

RULE 12 — Wait charge cannot start before user's flight has actually landed
  (for arrivals). free_wait_minutes_arrivals starts AFTER actual_landed_iso,
  not after scheduled_pickup_iso. Charging wait for flight delays = breach.

RULE 13 — No silent driver swap pre-airport.
  Any driver_id change after dispatch must trigger user notification +
  consent. Silent swap = breach.

VERSION HISTORY

v1.0.0 — 2026-05-10 — Initial spec