{"openapi":"3.1.0","info":{"title":"Axel Agent API","description":"Flight prices and saved offers for AI agents and partner integrations.\n\nEvery fare row leads with the Axel price, which any traveler can book with a free Axel account (no membership needed), the airline's own price on Google Flights, and the difference. Prices are whole-party totals in minor units (cents) with a currency code. Sign-up is a phone number and a text code; nothing is charged until the traveler confirms, and the price is re-checked first. An optional paid Membership gives frequent travelers deeper discounts; this API never quotes member prices or membership fees. Booking always finishes on helloaxel.com.\n\nSaved fares (GET /agent/fares/saved) are free for any caller. Live searches need a partner key (X-Axel-Agent-Key) or a linked Axel account (OAuth 2.1 bearer; discovery at https://api.helloaxel.com/.well-known/oauth-authorization-server). Account routes need a linked account with the axel:read, axel:quotes or axel:trips scope.\n\nAxel is operated by Gordian Software, Inc. (Y Combinator W19).","version":"1.0.0"},"servers":[{"url":"/v1"},{"url":"https://api.helloaxel.com/v1"}],"paths":{"/agent/fares/saved":{"get":{"tags":["flights"],"summary":"Saved Fares","description":"Freshest saved observations (under 7 days) for exact dates; never a supplier call.\n\nFree for every caller. Rows lead with the Axel price without membership,\nthe airline's price on Google Flights, and the difference.","operationId":"saved_fares_agent_fares_saved_get","parameters":[{"name":"origin","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":259,"description":"IATA airport code(s), comma-separated","title":"Origin"},"description":"IATA airport code(s), comma-separated"},{"name":"destination","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":259,"description":"IATA airport code(s), comma-separated","title":"Destination"},"description":"IATA airport code(s), comma-separated"},{"name":"departure_date","in":"query","required":true,"schema":{"type":"string","format":"date","title":"Departure Date"}},{"name":"return_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Return Date"}},{"name":"adults","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":9,"minimum":1},{"type":"null"}],"title":"Adults"}},{"name":"children","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":8,"minimum":0},{"type":"null"}],"title":"Children"}},{"name":"max_stops","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":3,"minimum":0},{"type":"null"}],"title":"Max Stops"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedFaresResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent/flight-searches":{"post":{"tags":["flights"],"summary":"Search","description":"Live outbound search; same request as POST /conv/agent-flight-searches.\n\nNeeds a partner key (X-Axel-Agent-Key) or a linked Axel account bearer.","operationId":"search_agent_flight_searches_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-Axel-Quote-Session","in":"header","required":true,"schema":{"type":"string","format":"uuid","title":"X-Axel-Quote-Session"}},{"name":"X-Axel-Agent-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Partner key for live searches; the SHA-256 must match a configured partner.","title":"X-Axel-Agent-Key"},"description":"Partner key for live searches; the SHA-256 must match a configured partner."},{"name":"X-Axel-Flight-Source","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional percent-encoded FlightCheckSource JSON (2048 characters maximum). Invalid telemetry is ignored.","title":"X-Axel-Flight-Source"},"description":"Optional percent-encoded FlightCheckSource JSON (2048 characters maximum). Invalid telemetry is ignored."},{"name":"X-Axel-Flight-Source-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional HMAC-SHA256 (hex) of X-Axel-Flight-Source by the Axel web server. Only a signed source naming an assistant can place the search in an assistant budget pot.","title":"X-Axel-Flight-Source-Signature"},"description":"Optional HMAC-SHA256 (hex) of X-Axel-Flight-Source by the Axel web server. Only a signed source naming an assistant can place the search in an assistant budget pot."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFlightQuoteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent/flight-searches/{observation_id}/select":{"post":{"tags":["flights"],"summary":"Select","description":"Select an option: a live return search (identity required) or the final saved offer.","operationId":"select_agent_flight_searches__observation_id__select_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Observation Id"}},{"name":"airline","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[A-Z0-9]{2}$"},{"type":"null"}],"title":"Airline"}},{"name":"max_stops","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2,"minimum":0},{"type":"null"}],"title":"Max Stops"}},{"name":"X-Axel-Quote-Session","in":"header","required":true,"schema":{"type":"string","format":"uuid","title":"X-Axel-Quote-Session"}},{"name":"X-Axel-Agent-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Partner key for live searches; the SHA-256 must match a configured partner.","title":"X-Axel-Agent-Key"},"description":"Partner key for live searches; the SHA-256 must match a configured partner."},{"name":"X-Axel-Flight-Source","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional percent-encoded FlightCheckSource JSON (2048 characters maximum). Invalid telemetry is ignored.","title":"X-Axel-Flight-Source"},"description":"Optional percent-encoded FlightCheckSource JSON (2048 characters maximum). Invalid telemetry is ignored."},{"name":"X-Axel-Flight-Source-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional HMAC-SHA256 (hex) of X-Axel-Flight-Source by the Axel web server. Only a signed source naming an assistant can place the search in an assistant budget pot.","title":"X-Axel-Flight-Source-Signature"},"description":"Optional HMAC-SHA256 (hex) of X-Axel-Flight-Source by the Axel web server. Only a signed source naming an assistant can place the search in an assistant budget pot."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent/flight-quotes/{token}":{"get":{"tags":["flights"],"summary":"Read Offer","description":"Read a saved offer (the helloaxel.com/r/<token> snapshot) without claiming it.","operationId":"read_offer_agent_flight_quotes__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentOfferResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent/flight-quotes/{token}/claim":{"post":{"tags":["flights"],"summary":"Claim Offer","description":"Attach the saved offer to the linked traveler's trip; booking finishes on helloaxel.com.","operationId":"claim_offer_agent_flight_quotes__token__claim_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"fare_index","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"Fare Index"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agent/me":{"get":{"tags":["account"],"summary":"Me","description":"The linked traveler behind this bearer and what the agent may do.","operationId":"me_agent_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/agent/trips":{"get":{"tags":["account"],"summary":"Trips","description":"The linked traveler's upcoming trips (the app's trips list, summarized).","operationId":"trips_agent_trips_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AgentTripSummary"},"type":"array","title":"Response Trips Agent Trips Get"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"AgentClaimResponse":{"properties":{"trip_id":{"type":"string","format":"uuid","title":"Trip Id"},"quote_id":{"type":"string","format":"uuid","title":"Quote Id"},"checkout_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Token"},"checkout_url":{"type":"string","title":"Checkout Url","description":"Absolute helloaxel.com URL where the linked traveler finishes booking."}},"additionalProperties":false,"type":"object","required":["trip_id","quote_id","checkout_url"],"title":"AgentClaimResponse"},"AgentFlightPassengers":{"properties":{"adults":{"type":"integer","maximum":9.0,"minimum":1.0,"title":"Adults"},"children":{"type":"integer","maximum":8.0,"minimum":0.0,"title":"Children","default":0},"infants_in_seat":{"type":"integer","maximum":8.0,"minimum":0.0,"title":"Infants In Seat","default":0},"infants_on_lap":{"type":"integer","maximum":8.0,"minimum":0.0,"title":"Infants On Lap","default":0}},"additionalProperties":false,"type":"object","required":["adults"],"title":"AgentFlightPassengers","description":"Anonymous pricing needs counts/types, never traveler identities."},"AgentFlightQuoteRequest":{"properties":{"origin":{"type":"string","maxLength":120,"minLength":1,"title":"Origin","description":"Airport code, city/metro name or code, or comma-separated airport codes. Resolves to searchable airport codes before search."},"destination":{"type":"string","maxLength":120,"minLength":1,"title":"Destination","description":"Airport code, city/metro name or code, or comma-separated airport codes. Resolves to searchable airport codes before search."},"departure_date":{"type":"string","format":"date","title":"Departure Date"},"return_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Return Date"},"passengers":{"$ref":"#/components/schemas/AgentFlightPassengers"},"airline":{"anyOf":[{"type":"string","pattern":"^[A-Z0-9]{2}$"},{"type":"null"}],"title":"Airline"},"max_stops":{"anyOf":[{"type":"integer","maximum":2.0,"minimum":0.0},{"type":"null"}],"title":"Max Stops","description":"Maximum stops per direction; null leaves stops unrestricted."},"cabin":{"type":"string","enum":["economy","business"],"title":"Cabin","default":"economy"},"currency":{"type":"string","const":"USD","title":"Currency","default":"USD"}},"additionalProperties":false,"type":"object","required":["origin","destination","departure_date","passengers"],"title":"AgentFlightQuoteRequest","description":"Route search using existing airport resolution and traveler types."},"AgentMeResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"membership_active":{"type":"boolean","title":"Membership Active"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"client_id":{"type":"string","title":"Client Id","description":"The OAuth client this token was issued to; axel-app for a signed-in app session."}},"additionalProperties":false,"type":"object","required":["user_id","membership_active","scopes","client_id"],"title":"AgentMeResponse"},"AgentOfferFareOption":{"properties":{"fare_name":{"type":"string","title":"Fare Name"},"axel_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"airline_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"savings_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"baggage":{"items":{"type":"string"},"type":"array","title":"Baggage"},"baggage_policy":{"anyOf":[{"$ref":"#/components/schemas/FareBaggagePolicy"},{"type":"null"}]},"features":{"items":{"type":"string"},"type":"array","title":"Features"},"separate_tickets":{"type":"boolean","title":"Separate Tickets","default":false}},"additionalProperties":false,"type":"object","required":["fare_name"],"title":"AgentOfferFareOption","description":"A supplier fare on a saved offer, priced for the whole party."},"AgentOfferResponse":{"properties":{"quote_id":{"type":"string","format":"uuid","title":"Quote Id"},"token":{"type":"string","title":"Token"},"request":{"$ref":"#/components/schemas/AgentFlightQuoteRequest"},"checked_at":{"type":"string","format":"date-time","title":"Checked At"},"passenger_count":{"type":"integer","minimum":1.0,"title":"Passenger Count"},"ticketed_passenger_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ticketed Passenger Count"},"fare_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fare Label"},"legs":{"items":{"$ref":"#/components/schemas/FlightShareLeg"},"type":"array","title":"Legs"},"axel_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Whole-party Axel price without any membership; null on older offers that stored no such price."},"airline_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"savings_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}]},"fare_options":{"items":{"$ref":"#/components/schemas/AgentOfferFareOption"},"type":"array","title":"Fare Options"},"fare_options_retrieved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fare Options Retrieved At"},"fare_options_incomplete":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Fare Options Incomplete"},"continue_url":{"type":"string","title":"Continue Url","description":"Where the traveler finishes on helloaxel.com; also what the claim endpoint attaches to a linked account."},"pricing_note":{"type":"string","title":"Pricing Note","default":"Axel prices are bookable with a free Axel account; no membership is needed. Sign-up is a phone number and a text code. Nothing is charged until the traveler confirms, and the price is re-checked first. An optional paid Membership gives frequent travelers deeper discounts. Booking finishes on helloaxel.com."}},"additionalProperties":false,"type":"object","required":["quote_id","token","request","checked_at","passenger_count","legs","continue_url"],"title":"AgentOfferResponse","description":"A saved flight offer (the /r/<token> snapshot) read without claiming it."},"AgentSearchOption":{"properties":{"option_id":{"type":"string","format":"uuid","title":"Option Id","description":"Existing Axel flight observation id; select it with POST /agent/flight-searches/{option_id}/select."},"summary":{"$ref":"#/components/schemas/FlightShareLeg"},"axel_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Axel price without any membership, bookable with a free account. On a round-trip outbound row it is the starting total; choose a return for the pair total. Null when Axel's stored price for this itinerary is unavailable."},"airline_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"The airline's own price on Google Flights for the same party and itinerary."},"savings_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"airline_price_total minus axel_price_total when positive."},"price_is_starting":{"type":"boolean","title":"Price Is Starting","description":"True on round-trip outbound rows: totals are starting prices until a return is chosen."}},"additionalProperties":false,"type":"object","required":["option_id","summary","price_is_starting"],"title":"AgentSearchOption","description":"One selectable itinerary from a live search, priced for the whole party."},"AgentSearchOptionsResponse":{"properties":{"stage":{"type":"string","enum":["outbound","return"],"title":"Stage"},"session_id":{"type":"string","format":"uuid","title":"Session Id"},"request":{"$ref":"#/components/schemas/AgentFlightQuoteRequest"},"options":{"items":{"$ref":"#/components/schemas/AgentSearchOption"},"type":"array","title":"Options"},"selected_outbound":{"anyOf":[{"$ref":"#/components/schemas/FlightShareLeg"},{"type":"null"}]},"origin_airports":{"items":{"type":"string"},"type":"array","title":"Origin Airports"},"destination_airports":{"items":{"type":"string"},"type":"array","title":"Destination Airports"},"pricing_note":{"type":"string","title":"Pricing Note","default":"Axel prices are bookable with a free Axel account; no membership is needed. Sign-up is a phone number and a text code. Nothing is charged until the traveler confirms, and the price is re-checked first. An optional paid Membership gives frequent travelers deeper discounts. Booking finishes on helloaxel.com."}},"additionalProperties":false,"type":"object","required":["stage","session_id","request","options"],"title":"AgentSearchOptionsResponse","description":"Outbound or return choices; no supplier tokens, no member prices."},"AgentSearchQuoteResponse":{"properties":{"stage":{"type":"string","const":"quote","title":"Stage","default":"quote"},"session_id":{"type":"string","format":"uuid","title":"Session Id"},"url":{"type":"string","title":"Url","description":"The offer page on helloaxel.com."},"offer":{"$ref":"#/components/schemas/AgentOfferResponse"}},"additionalProperties":false,"type":"object","required":["session_id","url","offer"],"title":"AgentSearchQuoteResponse","description":"The final selection: a saved offer the traveler finishes on helloaxel.com."},"AgentSearchResponse":{"oneOf":[{"$ref":"#/components/schemas/AgentSearchOptionsResponse"},{"$ref":"#/components/schemas/AgentSearchQuoteResponse"}],"discriminator":{"propertyName":"stage","mapping":{"outbound":"#/components/schemas/AgentSearchOptionsResponse","quote":"#/components/schemas/AgentSearchQuoteResponse","return":"#/components/schemas/AgentSearchOptionsResponse"}}},"AgentTripSummary":{"properties":{"trip_id":{"type":"string","title":"Trip Id"},"headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headline"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"},"status":{"type":"string","enum":["planning","booked"],"title":"Status"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"destination":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Destination"},"flight_booking_count":{"type":"integer","minimum":0.0,"title":"Flight Booking Count","default":0},"hotel_booking_count":{"type":"integer","minimum":0.0,"title":"Hotel Booking Count","default":0}},"additionalProperties":false,"type":"object","required":["trip_id","status"],"title":"AgentTripSummary","description":"A compact, read-only view of one of the traveler's upcoming trips."},"FareBaggagePolicy":{"properties":{"source":{"type":"string","enum":["serpapi_google_flights","unknown"],"title":"Source","default":"unknown"},"quotes":{"items":{"$ref":"#/components/schemas/FareBaggageQuote"},"type":"array","title":"Quotes"}},"type":"object","title":"FareBaggagePolicy","description":"Structured fare baggage policy, with raw supplier text preserved."},"FareBaggageQuote":{"properties":{"bag_type":{"type":"string","enum":["personal_item","carry_on","checked","checked_first","checked_second","unknown"],"title":"Bag Type","default":"unknown"},"quantity":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Quantity","description":"Bag count when the supplier text states one; 0 for explicit restrictions."},"is_included":{"type":"boolean","title":"Is Included","default":false},"is_restriction":{"type":"boolean","title":"Is Restriction","default":false},"fee_amount":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Fee Amount"},"fee_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fee Currency"},"fee_basis":{"type":"string","enum":["round_trip","one_way","per_segment","unknown"],"title":"Fee Basis","default":"unknown"},"pax_basis":{"type":"string","enum":["per_pax","total","unknown"],"title":"Pax Basis","default":"unknown"},"fee_amount_per_direction":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Fee Amount Per Direction","description":"Per-passenger one-way fee amount when it can be normalized from the supplier quote. For round-trip totals, this is half of fee_amount."},"source_key":{"type":"string","enum":["together","departing","returning","unknown"],"title":"Source Key","default":"unknown"},"raw_text":{"type":"string","title":"Raw Text"}},"type":"object","required":["raw_text"],"title":"FareBaggageQuote","description":"A single baggage policy quote from a fare-shopping supplier."},"FlightShareLeg":{"properties":{"airline_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Airline Name"},"airline_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Airline Code"},"origin":{"type":"string","title":"Origin"},"destination":{"type":"string","title":"Destination"},"departure_date":{"type":"string","title":"Departure Date"},"departure_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departure Time"},"arrival_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arrival Date"},"arrival_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arrival Time"},"duration_minutes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Duration Minutes"},"stops":{"type":"integer","minimum":0.0,"title":"Stops"},"connection_airports":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Connection Airports","description":"Ordered connection airport codes when every segment boundary is known and stays at the same airport. Null when unavailable, incomplete, or requiring an airport change; an empty list means a confirmed nonstop leg."},"flight_numbers":{"items":{"type":"string"},"type":"array","title":"Flight Numbers"},"segments":{"items":{"$ref":"#/components/schemas/FlightShareSegment"},"type":"array","title":"Segments"}},"additionalProperties":false,"type":"object","required":["origin","destination","departure_date","stops"],"title":"FlightShareLeg","description":"Public-safe itinerary facts for one ordered leg of a flight."},"FlightShareSegment":{"properties":{"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"destination":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Destination"},"departure_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departure Date"},"departure_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Departure Time"},"arrival_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arrival Date"},"arrival_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arrival Time"},"flight_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flight Number"},"duration_minutes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Duration Minutes"},"layover_after_minutes":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Layover After Minutes","description":"Elapsed time until the next segment at the same airport; null when unknown or on the last segment."}},"additionalProperties":false,"type":"object","title":"FlightShareSegment","description":"Schedule facts only; no booking tokens or traveler details."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Money":{"properties":{"amount":{"type":"integer","title":"Amount"},"currency":{"type":"string","title":"Currency"}},"type":"object","required":["amount","currency"],"title":"Money","description":"Immutable money value stored as integer minor units.\n\nAmount is always stored in the smallest currency unit (cents, yen, pesos, etc).\nThis avoids floating-point precision issues and matches payment processor standards.\n\nExamples:\n    $19.99 USD -> Money(amount=1999, currency=\"USD\")\n    ¥1000 JPY -> Money(amount=1000, currency=\"JPY\")\n    $1000.00 CLP -> Money(amount=1000, currency=\"CLP\")\n\nSerializes to {\"amount\": 1999, \"currency\": \"USD\"}.\n\nIMPORTANT: Use Money.from_decimal() for user-facing amounts like \"$19.99\".\nThe constructor expects integer minor units (cents).","x-currency-minor-unit-factors":{"ADP":1,"AED":100,"AFA":100,"AFN":100,"ALK":1,"ALL":100,"AMD":100,"ANG":100,"AOA":100,"AOK":1,"AON":1,"AOR":1,"ARA":100,"ARL":100,"ARM":100,"ARP":100,"ARS":100,"ATS":100,"AUD":100,"AWG":100,"AZM":100,"AZN":100,"BAD":100,"BAM":100,"BAN":1,"BBD":100,"BDT":100,"BEC":1,"BEF":100,"BEL":1,"BGL":100,"BGM":1,"BGN":100,"BGO":1,"BHD":1000,"BIF":1,"BMD":100,"BND":100,"BOB":100,"BOL":1,"BOP":100,"BOV":100,"BRB":100,"BRC":100,"BRE":100,"BRL":100,"BRN":100,"BRR":100,"BRZ":100,"BSD":100,"BTN":100,"BUK":1,"BWP":100,"BYB":100,"BYN":100,"BYR":1,"BZD":100,"CAD":100,"CDF":100,"CHE":100,"CHF":100,"CHW":100,"CLE":1,"CLF":10000,"CLP":1,"CNH":100,"CNX":100,"CNY":100,"COP":100,"COU":100,"CRC":100,"CSD":100,"CSK":1,"CUC":100,"CUP":100,"CVE":100,"CYP":100,"CZK":100,"DDM":1,"DEM":100,"DJF":1,"DKK":100,"DOP":100,"DZD":100,"ECS":1,"ECV":100,"EEK":100,"EGP":100,"ERN":100,"ESA":1,"ESB":1,"ESP":1,"ETB":100,"EUR":100,"FIM":100,"FJD":100,"FKP":100,"FRF":100,"GBP":100,"GEK":1,"GEL":100,"GHC":100,"GHS":100,"GIP":100,"GMD":100,"GNF":1,"GNS":1,"GQE":1,"GRD":100,"GTQ":100,"GWE":1,"GWP":100,"GYD":100,"HKD":100,"HNL":100,"HRD":100,"HRK":100,"HTG":100,"HUF":100,"IDR":100,"IEP":100,"ILP":100,"ILR":100,"ILS":100,"IMP":100,"INR":100,"IQD":1000,"IRR":100,"ISJ":100,"ISK":1,"ITL":1,"JMD":100,"JOD":1000,"JPY":1,"KES":100,"KGS":100,"KHR":100,"KMF":1,"KPW":100,"KRH":1,"KRO":1,"KRW":1,"KWD":1000,"KYD":100,"KZT":100,"LAK":100,"LBP":100,"LKR":100,"LRD":100,"LSL":100,"LTL":100,"LTT":100,"LUC":1,"LUF":100,"LUL":1,"LVL":100,"LVR":100,"LYD":1000,"MAD":100,"MAF":100,"MCF":100,"MDC":1,"MDL":100,"MGA":100,"MGF":1,"MKD":100,"MKN":1,"MLF":1,"MMK":100,"MNT":100,"MOP":100,"MRO":100,"MRU":100,"MTL":100,"MTP":1,"MUR":100,"MVP":1,"MVR":100,"MWK":100,"MXN":100,"MXP":1,"MXV":100,"MYR":100,"MZE":100,"MZM":100,"MZN":100,"NAD":100,"NGN":100,"NIC":100,"NIO":100,"NLG":100,"NOK":100,"NPR":100,"NZD":100,"OMR":1000,"PAB":100,"PEI":1,"PEN":100,"PES":100,"PGK":100,"PHP":100,"PKR":100,"PLN":100,"PLZ":100,"PTE":1,"PYG":1,"QAR":100,"RHD":100,"ROL":1,"RON":100,"RSD":100,"RUB":100,"RUR":100,"RWF":1,"SAR":100,"SBD":100,"SCR":100,"SDD":100,"SDG":100,"SDP":1,"SEK":100,"SGD":100,"SHP":100,"SIT":100,"SKK":100,"SLE":100,"SLL":100,"SOS":100,"SRD":100,"SRG":100,"SSP":100,"STD":100,"STN":100,"SUR":1,"SVC":100,"SYP":100,"SZL":100,"THB":100,"TJR":1,"TJS":100,"TMM":100,"TMT":100,"TND":1000,"TOP":100,"TPE":1,"TRL":1,"TRY":100,"TTD":100,"TVD":100,"TWD":100,"TZS":100,"UAH":100,"UAK":100,"UGS":1,"UGX":1,"USD":100,"USN":100,"USS":100,"UYI":1,"UYP":100,"UYU":100,"UYW":10000,"UZS":100,"VEB":100,"VED":100,"VEF":100,"VES":100,"VND":1,"VNN":1,"VUV":1,"WST":100,"XAF":1,"XAG":1,"XAU":1,"XBA":1,"XBB":1,"XBC":1,"XBD":1,"XCD":100,"XDR":1,"XEU":1,"XFO":1,"XFU":1,"XOF":1,"XPD":1,"XPF":1,"XPT":1,"XRE":1,"XSU":1,"XTS":1,"XUA":1,"XXX":1,"YDD":1,"YER":100,"YUD":100,"YUM":100,"YUN":100,"YUR":100,"ZAL":100,"ZAR":100,"ZMK":100,"ZMW":100,"ZRN":100,"ZRZ":100,"ZWD":100,"ZWL":100,"ZWN":100,"ZWR":100}},"PassengerCount":{"properties":{"adults":{"type":"integer","title":"Adults","default":1},"children":{"type":"integer","title":"Children","default":0},"infants_in_seat":{"type":"integer","title":"Infants In Seat","default":0},"infants_on_lap":{"type":"integer","title":"Infants On Lap","default":0}},"additionalProperties":false,"type":"object","title":"PassengerCount","description":"Passenger breakdown for offers/searches.\n\nSimple counts by type."},"SavedFareJourney":{"properties":{"airline":{"type":"string","title":"Airline"},"airline_code":{"type":"string","title":"Airline Code"},"flight_numbers":{"items":{"type":"string"},"type":"array","title":"Flight Numbers"},"depart_local":{"type":"string","title":"Depart Local","description":"Local departure timestamp at the origin"},"arrive_local":{"type":"string","title":"Arrive Local","description":"Local arrival timestamp at the destination"},"duration_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Minutes"},"stops":{"type":"integer","minimum":0.0,"title":"Stops"},"stop_airports":{"items":{"type":"string"},"type":"array","title":"Stop Airports"}},"additionalProperties":false,"type":"object","required":["airline","airline_code","flight_numbers","depart_local","arrive_local","stops"],"title":"SavedFareJourney","description":"One direction of a saved fare: schedule facts only."},"SavedFareOption":{"properties":{"airline":{"type":"string","title":"Airline"},"airline_code":{"type":"string","title":"Airline Code"},"flight_numbers":{"items":{"type":"string"},"type":"array","title":"Flight Numbers"},"depart_local":{"type":"string","title":"Depart Local","description":"Local departure timestamp at the origin"},"arrive_local":{"type":"string","title":"Arrive Local","description":"Local arrival timestamp at the destination"},"duration_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Minutes"},"stops":{"type":"integer","minimum":0.0,"title":"Stops"},"stop_airports":{"items":{"type":"string"},"type":"array","title":"Stop Airports"},"return_journey":{"anyOf":[{"$ref":"#/components/schemas/SavedFareJourney"},{"type":"null"}]},"departure_date":{"type":"string","format":"date","title":"Departure Date"},"return_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Return Date"},"passengers":{"$ref":"#/components/schemas/PassengerCount"},"price_basis":{"type":"string","enum":["one_way_total","round_trip_starting_total","round_trip_total"],"title":"Price Basis"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"},"axel_price_total":{"$ref":"#/components/schemas/Money","description":"Whole-party Axel price without any membership, bookable with a free account."},"airline_price_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"The airline's own price on Google Flights, same party."},"savings_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"airline_price_total minus axel_price_total when positive."}},"additionalProperties":false,"type":"object","required":["airline","airline_code","flight_numbers","depart_local","arrive_local","stops","departure_date","passengers","price_basis","observed_at","axel_price_total"],"title":"SavedFareOption","description":"A saved observation of a bookable itinerary; display only.\n\nSaved fares carry no selectable id. To book, run a live search and select\nan option from it, or continue on helloaxel.com."},"SavedFaresResponse":{"properties":{"route":{"type":"string","title":"Route","description":"ORIGIN-DESTINATION airport codes, e.g. SEA-DEN"},"origin":{"type":"string","title":"Origin"},"destination":{"type":"string","title":"Destination"},"departure_date":{"type":"string","format":"date","title":"Departure Date"},"return_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Return Date"},"status":{"type":"string","enum":["available","no_sample","temporarily_unavailable"],"title":"Status"},"observed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Observed At","description":"Newest observation among the options; null when empty."},"fresh":{"type":"boolean","title":"Fresh","description":"True when at least one option observed within the last 7 days is listed."},"options":{"items":{"$ref":"#/components/schemas/SavedFareOption"},"type":"array","title":"Options"},"live_search_hint":{"type":"string","title":"Live Search Hint"},"pricing_note":{"type":"string","title":"Pricing Note","default":"Axel prices are bookable with a free Axel account; no membership is needed. Sign-up is a phone number and a text code. Nothing is charged until the traveler confirms, and the price is re-checked first. An optional paid Membership gives frequent travelers deeper discounts. Booking finishes on helloaxel.com."}},"additionalProperties":false,"type":"object","required":["route","origin","destination","departure_date","status","fresh","options","live_search_hint"],"title":"SavedFaresResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}