Need Help on Custom API calls for Travel Industry

I need help with custom API calls for the travel industry. How to use custom APIS using agno

Flight Search
Ticketing

Hey @hi.satishbabu87
Thank you for reaching out and supporting Agno
You can refer our docs to get started : Custom API - Agno

please let me know incase you have any doubts

This is my custom API request and flight search agent

curl --location ‘https://test.test.com/resources/v2/Flights/search
–header ‘Content-Type: application/json’
–header ‘Accept: application/json’
–header ‘showDebugInfo: true’
–header ‘SearchAccessToken: 12234566’
–data '{
“OtherInfo”: {
“RequestedIP”: “111.0.0.0”,
“TransactionId”: “12345”
},
“CurrencyInfo”: {
“CurrencyCode”: “USD”
},
“PaxDetails”: {
“NoOfAdults”: {
“count”: “1”
},
“NoOfInfants”: {
“count”: “0”,
“age”: “0”
},
“NoOfChildren”: {
“count”: “0”,
“age”: “0”
}
},

"OriginDestination": [
    {
        "DepartureTime": "21/05/2025",
        "DepartureLocationCode": "LAX",
        "ArrivalLocationCode": "MNL",
        "CabinClass": "E"
    },
    {
        "DepartureTime": "31/05/2025",
        "DepartureLocationCode": "MNL",
        "ArrivalLocationCode": "LAX",
        "CabinClass": "E"
    }
],
"Incremental": "false"

}’

flight search agent

“Flight Search”: Agent(
name=“Flight Search Agent”,
role=“Searches, analyzes, and compares flights to deliver personalized recommendations with clear pricing, duration, and convenience trade-offs”,
agent_id=“flight-search-agent”,
model=OpenAIChat(id=selected_models),
tools=[flight_search], # Now using the class instead of hardcoded values
description=(
"You are an expert flight booking assistant that finds the optimal travel options. "
"Specializes in parsing travel queries, comparing airline offerings, and presenting choices with actionable insights. "
“Always prioritize: 1) Accuracy 2) Cost savings 3) Travel convenience.\n\n”
“When a user asks about flights, you should ask for the following information:\n”
“- Origin airport code (e.g., SFO)\n”
“- Destination airport code (e.g., LAX)\n”
“- Departure date (YYYY-MM-DD)\n”
“- [Optional] Return date (YYYY-MM-DD)\n”
“- [Optional] Number of adults (default: 1)\n\n”
“Once you have all required information, use the FlightSearchTool to find flights.”
),
instructions=[
“First, ask the user for all required flight search parameters if not provided.”,
“Validate that dates are in the correct format (YYYY-MM-DD) and in the future.”,
“When presenting flight options, include:\n”
“- Airline name\n”
“- Flight number\n”
“- Departure and arrival times\n”
“- Duration\n”
“- Price\n”
“- Any other relevant details”,
“Present the information in a clear, organized table format.”,
“Always show the currency for prices.”,
“If no flights are found, suggest alternative dates or nearby airports.”
],

            # storage=SqliteStorage("flight_search_agent", f"sqlite:///{agent_storage_file}"),
            # memory=memory,
            # enable_user_memories=True,
            # add_history_to_messages=True,
            # num_history_responses=5,
            show_tool_calls=True,
            markdown=True,
            debug_mode=True
        )

Hi @hi.satishbabu87 , thanks for reaching out . Are you facing any error while running this ?

airports.”
],

            # storage=SqliteStorage("flight_search_agent", f"sqlite:///{agent_storage_file}"),
            # memory=memory,
            # enable_user_memories=True,
            # add_history_to_messages=True,
            # num_history_responses=5,

I’m getting error on me memory management I’m output is different like airline name , flight no, depart date, arrive date, total fare but system not accepting the result to store in above file. It asking me

Error

agno.exceptions.ModelProviderError: Invalid schema for function ‘add_memory’: In context=(‘properties’, ‘topics’), schema must have a ‘type’ key.

Individual memory schema like this I think

memory_schema = {
“properties”: {
“topics”: {
“items”: {“type”: “string”}
}
}
}

But for my case expecting this I think

memory_schema = {
“type”: “object”,
“properties”: {
“topics”: {
“type”: “array”, # ← this is what was missing
“items”: {“type”: “string”}
}
}
}

Please advise how to handle custom api calls agents memory

I have few more custom apis

Cancel pnr
Refund
Reissue

output maybe different for my cases

Hi @hi.satishbabu87 I was able to handle memory with custom api tool. Also you need to initialise memory.

memory = Memory(db=memory_db)

Please refer to this doc to see how to initialise memory .Agentic Memory - Agno
Also can you confirm if you are using the latest version of Agno sdk?

I added all the initialization but still getting this error

agno.exceptions.ModelProviderError: Invalid schema for function ‘add_memory’: In context=(‘properties’, ‘topics’), schema must have a ‘type’ key.

Agno SDK version

Name: agno
Version: 1.4.5
Summary: Agno: a lightweight library for building Reasoning Agents

This is my code

Set up database with proper file paths (without sqlite:// prefix)

agent_storage_file = os.path.abspath(“tmp/agents.db”)
memory_storage_file = os.path.abspath(“tmp/memory.db”)
image_agent_storage_file = os.path.abspath(“tmp/image_agent.db”)
flight_agent_storage_file = os.path.abspath(“tmp/flight_search.db”)
cancel_pnr_storage_file = os.path.abspath(“tmp/cancel_pnr.db”)

memory_db = SqliteMemoryDb(table_name=“memory”, db_file=memory_storage_file)
memory = Memory(db=memory_db)

“Flight Search”: Agent(
name=“Flight Search Agent”,
role=“Searches, analyzes, and compares flights to deliver personalized recommendations with clear pricing, duration, and convenience trade-offs”,
agent_id=“flight-search-agent”,
model=OpenAIChat(id=selected_models),
tools=[flight_search],
description=(
“Once you have all required information, use the flight_search to find flights.”
),
instructions=[
“If no flights are found, suggest alternative dates or nearby airports.”
],

        storage=SqliteStorage("flight_search_agent", f"sqlite:///{agent_storage_file}"),
        memory=memory,
        enable_user_memories=True,
        add_history_to_messages=True,
        num_history_responses=5,
        show_tool_calls=True,
        markdown=True,
        debug_mode=True
		
		),

Hi @hi.satishbabu87 i can see you’re using flight_search as tool? Have made a custom tool function for it? Can i see that function, could not find in the above code.

Also can’t you just use our CustomApiTools here- Custom API - Agno

and pass it like tools=[CustomApiTools(base_url=)]

if any more headers or params are required you can override the CustomApiTools class and add them accordingly.

@kausmos This is my flight_search tool code

from datetime import datetime
import requests

def validate_date(date_string):
try:
return datetime.strptime(date_string, “%Y-%m-%d”) > datetime.now()
except ValueError:
return False

def convert_date_format(date_str):
“”“Convert from YYYY-MM-DD to DD/MM/YYYY”“”
try:
return datetime.strptime(date_str, “%Y-%m-%d”).strftime(“%d/%m/%Y”)
except Exception:
return date_str

def search_flights(origin, destination, departure_date, return_date, adults=1):
try:
print(“:bullseye: Inside search_flights()”)
if not validate_date(departure_date):
raise ValueError(“Invalid departure date. Must be in the future.”)
if return_date and not validate_date(return_date):
raise ValueError(“Invalid return date. Must be in the future.”)
return_date = return_date or departure_date

    response = search_flights_custom_api(origin, destination, departure_date, return_date, adults)
    print("📊 API Response Received:", response)

    itineraries = response.get("FlightItinerary", [])
    flights = []

    for itinerary in itineraries[:3]:
        fare = itinerary.get("Fares", [{}])[0]
        total_price = fare.get("currencyExchange", {}).get("customer", {}).get("totalFare", "N/A")
        # currency = fare.get("CurrencyCode", "N/A")

        for citypair in itinerary.get("Citypairs", []):
            for segment in citypair.get("FlightSegment", []):
                flights.append({
                    "airline": segment.get("MarketingAirlineName", "N/A"),
                    "flight_no": segment.get("FlightNumber", "N/A"),
                    "depart": segment.get("DepartureDateTime", "N/A"),
                    "return": segment.get("ArrivalDateTime", "N/A"),
                    "price": total_price,

                })

        return flights[:3]

    # fallback dummy
    return [{
        "airline": "Test Airline",
        "flight_no": "Test 6E123",
        "depart": departure_date,
        "return": return_date,
        "price": "₹ Test  12,345"
    }]



except Exception as error:
    print("❌ Search Error:", error)
    return []

def search_flights_custom_api(origin, destination, date, return_date, adults):
print(“:white_check_mark: CUSTOM API CALLED”)
url = “https://test.test.com/sources/v2/Flights/search

headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "SearchAccessToken": "44563frghht2",
    "showDebugInfo": "true"
}

payload = {
    "OtherInfo": {
        "RequestedIP": "111.0.0.0",
        "TransactionId": "1234"
    },
    "CurrencyInfo": {
        "CurrencyCode": "USD"
    },
    "PaxDetails": {
        "NoOfAdults": {"count": adults},
        "NoOfInfants": {"count": "0", "age": "0"},
        "NoOfChildren": {"count": "0", "age": "0"}
    },
    "OriginDestination": [
        {
            "DepartureTime": convert_date_format(date),
            "DepartureLocationCode": origin,
            "ArrivalLocationCode": destination,
            "CabinClass": "E"
        },
        {
            "DepartureTime": convert_date_format(return_date),
            "DepartureLocationCode": destination,
            "ArrivalLocationCode": origin,
            "CabinClass": "E"
        }
    ],
    "Incremental": "false"
}

print("📦 Payload:", payload)

try:
    response = requests.post(url, json=payload, headers=headers, timeout=15, verify=False)
    response.raise_for_status()
    json_response = response.json()
    print("📬 API Response:", json_response)
    if "flights" not in json_response or not json_response["flights"]:
        print("⚠️ No flights in API response — falling back to dummy.")

    return json_response


except requests.RequestException as e:
    print("❌ Custom API call failed:", e)
    return {"flights": []}