I need help with custom API calls for the travel industry. How to use custom APIS using agno
Flight Search
Ticketing
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
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(“ 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(“ 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": []}