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