From User Prompts to Expedia API Calls: Building a Natural Language Travel Query Framework

Introduction

In the age of conversational AI, users increasingly expect to communicate naturally with travel systems. A request like “Find 4-star romantic hotels in Paris with a pool under $300” should instantly produce accurate, structured results.

Behind the scenes, however, APIs such as Expedia’s Travel Recommendation Service require rigorously defined parameters:

{
  "destination": "Paris",
  "property_types": ["HOTEL"],
  "property_themes": ["ROMANTIC"],
  "amenities": ["POOL"],
  "max_nightly_price": 300
}

Bridging the gap between unstructured human input and structured machine-readable queries requires a well-designed natural language processing (NLP) framework. This article explores how to design such a system — one that turns user prompts into Expedia API calls automatically.

The Problem: Translating Human Language into API Queries

Human language is flexible, nuanced, and often incomplete:

“Show me affordable business hotels near downtown Seattle next week.”

APIs, by contrast, demand precision. They require:

  • Mandatory fields such as destination, check_in, and check_out

  • Enumerated fields for themes and amenities

  • ISO-standardized dates and numeric price limits

The goal of the framework is to interpret, normalize, and structure user input into Expedia-compliant parameters, intelligently filling in any missing information.

Framework Overview

The framework follows a six-step process that transforms a natural-language travel request into a valid Expedia API query.

Step 1. Parse the User Prompt

The system first identifies the intent (e.g., search hotels, book flight, rent car) and extracts key entities such as destinations, dates, price limits, amenities, and property preferences.

Entity TypeExample ExtractionTarget FieldDestination“Paris”, “Seattle”destinationDates“Dec 5–8”, “next weekend”check_in, check_outProperty type“hotel”, “resort”, “vacation rental”property_typesFilters“business-friendly”, “romantic”, “with pool”property_themes, amenitiesPrice“under $300/night”max_nightly_priceRating“4-star”star_ratings

A lightweight keyword extraction and regex-based parser is sufficient for structured travel domains like this.

Step 2. Map Entities to the Expedia Schema

Once extracted, each entity is mapped to Expedia’s standardized schema. For example:

"romantic" → "ROMANTIC"
"pool" → "POOL"
"business" → "BUSINESS_FRIENDLY"
"resort" → "RESORT"

A dictionary of keyword-to-enum mappings ensures user-friendly terms are converted into valid Expedia values:

THEME_KEYWORDS = {
    "business": "BUSINESS_FRIENDLY",
    "romantic": "ROMANTIC",
    "family": "FAMILY_FRIENDLY",
    "eco": "ECO_CERTIFIED"
}

This structure maintains both interpretability and scalability, allowing the system to expand easily across other Expedia endpoints.

Step 3. Fill Mandatory Fields and Defaults

Expedia requires certain parameters for each request. When users omit these, the framework supplies intelligent defaults.

ParameterDefault Behaviorcheck_in30 days from todaycheck_out3 days after check_inroom1_adults2destination“United States” (fallback)sort_type“CHEAPEST”

Default logic example:

if "check_in" not in params:
    params["check_in"] = today + timedelta(days=30)
if "check_out" not in params:
    params["check_out"] = params["check_in"] + timedelta(days=3)

This ensures all mandatory Expedia parameters are always present.

Step 4. Generate Structured Query

After parsing and filling defaults, the framework produces a clean, structured API query object.

Example:

{
  "user_input_in_english": "Find 4-star romantic hotels in Paris with a pool under $300",
  "keywords": "romantic|hotels|pool",
  "destination": "Paris",
  "check_in": "2025-12-10",
  "check_out": "2025-12-13",
  "property_types": ["HOTEL"],
  "property_themes": ["ROMANTIC"],
  "amenities": ["POOL"],
  "max_nightly_price": 300,
  "star_ratings": [4,5]
}

This object can be sent directly to:

apim_expedia_com__jit_plugin.lodgingProducts({...})

Step 5. Execute the Expedia API Call

With the structured query ready, the system calls the appropriate endpoint:

  • lodgingProducts for hotels

  • flightProducts for flights

  • carProducts for car rentals

  • activityProducts for local experiences

Each endpoint follows its own schema, but the same core parsing and mapping logic applies.

Step 6. Post-Process the Response

The response is formatted into human-readable results with fields such as hotel name, rating, price, image, and description. A transparent metadata section is appended for reproducibility.

Example:

Metadata:
  Data Source: Expedia Travel Recommendation Service
  Dataset IDs: [2330513, 11133, 27380703]
  Reference URLs: Expedia direct booking links
  Query Parameters: { destination: "Seattle", theme: "Business-Friendly" }
  Timestamp (UTC): 2025-11-10T16:42:00Z

This allows users and developers to verify how results were generated.

Implementation Example (Python)

A simplified version of the parser is shown below:

import re
from datetime import datetime, timedelta

def parse_user_prompt(prompt: str):
    params = {"user_input_in_english": prompt}
    prompt_lower = prompt.lower()

    # Destination
    match = re.search(r"in ([a-zA-Z\s]+)", prompt_lower)
    if match:
        params["destination"] = match.group(1).strip().title()

    # Themes and amenities
    for key, val in THEME_KEYWORDS.items():
        if key in prompt_lower:
            params.setdefault("property_themes", []).append(val)
    for key, val in AMENITY_KEYWORDS.items():
        if key in prompt_lower:
            params.setdefault("amenities", []).append(val)

    # Price and rating
    if m := re.search(r"under \$?(\d+)", prompt_lower):
        params["max_nightly_price"] = int(m.group(1))
    if m := re.search(r"(\d)-star", prompt_lower):
        params["star_ratings"] = [int(m.group(1)), 5]

    # Default values
    today = datetime.utcnow()
    params["check_in"] = (today + timedelta(days=30)).strftime("%Y-%m-%d")
    params["check_out"] = (today + timedelta(days=33)).strftime("%Y-%m-%d")
    params.setdefault("destination", "United States")
    params.setdefault("property_types", ["HOTEL"])

    return params

Input:

“Find 4-star romantic hotels in Paris with a pool under $300.”

Output:

{
  "destination": "Paris",
  "property_types": ["HOTEL"],
  "property_themes": ["ROMANTIC"],
  "amenities": ["POOL"],
  "max_nightly_price": 300,
  "star_ratings": [4, 5],
  "check_in": "2025-12-10",
  "check_out": "2025-12-13"
}

Extending the Framework

This architecture can easily expand to handle flights, car rentals, and local activities by updating entity mappings and endpoint logic.

For example:

  • Flights: origin, destination, departure_date, cabin_class

  • Cars: pickup_location, pickup_date, car_classes

  • Activities: destination, categories, duration

The parsing engine remains the same; only the output schema changes.

Advantages

  • Modularity: Each stage (parsing, mapping, defaults, API call, formatting) is independent.

  • Transparency: Metadata shows exactly how queries were generated.

  • Scalability: New keywords or endpoints can be added via mapping tables.

  • Conversational Readiness: Works well with chat-based or voice-based assistants.

Enhancing the Natural Language to API Framework

1. Named Entity Recognition (NER) with spaCy or Hugging Face

Purpose

The current framework uses rule-based parsing (e.g., regular expressions) to detect entities like destinations and dates. While effective for structured inputs, this approach struggles with ambiguity and real-world linguistic variety.

For example:

User InputChallenge“I want to go to Paris next spring”Date is vague (“next spring”)“Book something in New York City for three nights starting April 15”Multiple entities (city, duration, start date)“Hotels near LAX for under 200 dollars”Destination is an airport code, not a city

NER models trained on travel-related text can automatically recognize and classify locations, dates, price expressions, and durations — even when phrased differently.

Implementation with spaCy

spaCy provides out-of-the-box entity types like GPE (geopolitical entity), DATE, and MONEY.

Example:

import spacy

nlp = spacy.load("en_core_web_trf")
text = "Find 4-star hotels in Paris next weekend under $300."

doc = nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)

Output:

4-star CARDINAL
Paris GPE
next weekend DATE
$300 MONEY

These entities can then be mapped directly into Expedia parameters:

  • GPEdestination

  • DATEcheck_in / check_out

  • MONEYmax_nightly_price

For relative dates (e.g., “next weekend”), you can use libraries like dateparser to interpret them in ISO format.

Implementation with Hugging Face

For greater accuracy, a custom fine-tuned NER model can be built using the Hugging Face Transformers library.
This allows recognition of domain-specific entities such as:

  • HOTEL_NAME (“Marriott Downtown”)

  • AIRPORT_CODE (“LAX”, “JFK”)

  • ACTIVITY_TYPE (“boat tour”, “wine tasting”)

Training data can consist of annotated travel queries, enabling the model to generalize to complex user prompts.

2. Contextual Memory for Multi-Turn Dialogues

Purpose

Most travel planning is conversational and iterative. Users refine their preferences across multiple exchanges:

User: Show me business hotels in Seattle.
System: Here are three options near downtown.
User: Show me cheaper ones.
System: Filters previous results by price and updates display.

A stateless system would lose context between messages. Contextual memory solves this by maintaining a conversation state that persists relevant parameters across turns.

Implementation Approach

A lightweight session memory object can store the last query parameters and API results:

conversation_state = {
    "last_intent": "lodgingProducts",
    "params": {
        "destination": "Seattle",
        "property_themes": ["BUSINESS_FRIENDLY"],
        "sort_type": "CHEAPEST"
    },
    "results": [ ... ]  # cached from last API response
}

When the user says “Show me cheaper ones,” the system interprets this as a refinement, not a new request.
It updates only the relevant parameter (sort_type: CHEAPEST) or adjusts max_nightly_price relative to the last results.

Techniques for Context Maintenance

  1. Slot Filling: Each conversation maintains “slots” for intent, destination, dates, budget, and so on.

  2. Coreference Resolution: Detects references like “there,” “those,” or “the same city.”

  3. Dialog Policy Management: Determines when to confirm, update, or re-query.

This structure allows truly interactive trip planning, where the assistant behaves more like a human travel agent.

3. Reinforcement Learning from User Feedback

Purpose

Once the system is deployed, user interactions generate valuable feedback data — which hotels users click, book, or ignore; whether they modify or accept default options.

By applying reinforcement learning (RL) principles, the system can learn to optimize its parameter defaults, sorting logic, and recommendation strategies.

Example Scenarios

  • If users consistently prefer slightly more expensive but higher-rated hotels, the model can adjust the weighting of star_ratings versus max_price.

  • If users often refine “next weekend” to specific dates, the system can prompt earlier clarification.

  • If users ignore certain amenities, the system can deprioritize them in default filters.

Implementation Strategy

Step 1. Collect Feedback

Track anonymized metrics such as:

  • Click-through rates on each result

  • Booking conversions

  • Frequency of “show me more” or “cheaper” refinements

Step 2. Define Reward Function

Assign a reward based on user satisfaction proxies:

  • +1 for a booking

  • +0.5 for a click

  • -1 for early exit or “not helpful” feedback

Step 3. Update Policy

Use reinforcement learning techniques such as policy gradient optimization or contextual bandits to gradually improve decision-making.
For example:

  • Selecting between sort strategies (CHEAPEST, WONDERFUL)

  • Adjusting default durations or price assumptions

  • Reordering property recommendations

This creates a self-improving conversational recommender that adapts to user behavior over time.

Integrating All Three Enhancements

Together, these features elevate the framework from a rules-based query transformer into an intelligent travel dialogue agent:

CapabilityBenefitNER IntegrationUnderstands complex and varied natural language inputsContextual MemoryMaintains continuity across multiple conversation turnsReinforcement LearningContinuously refines defaults and rankings from real-world feedback

When combined, the result is a system that can interpret statements like:

“I’m thinking of going to Rome in May. Show me boutique hotels near the Colosseum. Actually, make it cheaper — and add breakfast.”

And convert that conversation into a series of precise, evolving Expedia API queries that reflect both intent and preference learning.

Conclusion

This framework bridges natural conversation and structured API communication in modern travel applications. By combining lightweight NLP with schema-aware logic, developers can transform free-form user queries into precise Expedia API calls.

Enhancing the natural language to Expedia API framework with NER, contextual memory, and reinforcement learning transforms it from a static interpreter into a dynamic, adaptive travel intelligence engine.

  • NER ensures robust and flexible understanding of destinations, dates, and prices.

  • Contextual memory enables fluid, multi-turn dialogues that feel natural and coherent.

  • Reinforcement learning closes the loop, allowing the system to learn from real interactions and improve continuously.

Together, these methods create the foundation for next-generation conversational travel assistants — systems that truly understand, remember, and evolve with their users.

Whether integrated into a chatbot, mobile assistant, or enterprise booking system, this approach enables reliable, transparent, and context-aware travel search experiences.