If your fare tracker, travel bot or class project suddenly can't reach test.api.amadeus.com or gets auth errors, it's not your code. Amadeus decommissioned its Self-Service APIs on 17 July 2026.
- The developer portal now says the self-service portal "has been decommissioned on July 17th".
- PhocusWire reported the plan on 9 February: new registrations paused, then keys disabled from 17 July. Enterprise APIs continue.
- The official SDKs (amadeus-python, amadeus-node, amadeus-java, Ruby, .NET) were archived on GitHub the same day.
- On 2 October,
test.api.amadeus.com, the SDK's default host, had no DNS A record at Google or Cloudflare DNS.
GitHub is full of projects hitting this. More than 190 issues and PRs mention Amadeus Self-Service since February. Some remove their Amadeus adapter (anythingmcp #713). Others swap in another API (multi-flight-search #1). Many are student projects that started an Amadeus integration after registrations closed.
I needed the same three calls for my own projects, so I built a replacement with the same parameter names and the same JSON shape. This post covers the options, the migration code, and what you can't replace.
The free options are mostly closed
| Option | Status (checked 2 Oct 2026) |
|---|---|
| Amadeus Self-Service | Decommissioned 17 July 2026. Enterprise only, via a commercial agreement |
| Google QPX Express | Ended 10 April 2018 |
| Kiwi.com Tequila | New partnerships "on an invitation only basis" since May 2024 |
| Skyscanner Travel API | "Commercial use only". Not for students, start-ups without a product, or sites under 100K monthly users |
| SerpApi Google Flights | Works. 250 free searches a month, then $25 per 1,000 to $275 per 30,000 ($0.025–$0.009 per search). Return legs need a second request |
fast-flights (Python) |
Alive and popular, but the maintainer says it can break whenever Google changes something (#92) |
If you need booking (Flight Create Orders, ticketing), none of these help. You need a booking API from an airline, a consolidator or Amadeus Enterprise. The rest of this post is about the read-only price calls, which is what most hobby and research projects used.
A drop-in for the three price calls
I published Flight Offers API on Apify. It takes the Amadeus Self-Service parameter names, fetches live prices from Google Flights, and returns Amadeus-shaped JSON:
| Amadeus Self-Service | Replacement | Status |
|---|---|---|
Flight Offers Search GET /v2/shopping/flight-offers
|
endpoint: "flight-offers" |
Same parameters, flight-offer objects |
Flight Cheapest Date Search GET /v1/shopping/flight-dates
|
endpoint: "cheapest-date" |
Scans every day in a range, up to 90 days |
Flight Price Analysis GET /v1/analytics/itinerary-price-metrics
|
endpoint: "price-metrics" |
Quartiles from Google's recent price history for that date |
| Flight Offers Price, Create Orders, Seat Maps | ✘ | Not replaced |
Disclosure: I built and sell this. It's pay per use: $0.003 per search plus $0.0005 per saved offer. A Flight Offers Search with 10 offers costs $0.008. Apify's free plan includes $5 of monthly credit, which covers about 600 such searches.
Migrating Flight Offers Search (Python)
Before, with the archived SDK:
from amadeus import Client
amadeus = Client(client_id="...", client_secret="...")
response = amadeus.shopping.flight_offers_search.get(
originLocationCode="JFK", destinationLocationCode="LAX",
departureDate="2026-11-12", adults=1, max=5)
for offer in response.data:
seg = offer["itineraries"][0]["segments"][0]
print(offer["price"]["total"], seg["carrierCode"], seg["number"], seg["departure"]["at"])
After (pip install apify-client, version 3.x):
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
def amadeus_call(endpoint, **params):
"""Runs the replacement and returns an Amadeus-style {meta, data, dictionaries} dict."""
run = client.actor("kuezi/flight-offers-api").call(logger=None, run_input={"endpoint": endpoint, **params})
return client.key_value_store(run.default_key_value_store_id).get_record("RESPONSE")["value"]
response = amadeus_call("flight-offers",
originLocationCode="JFK", destinationLocationCode="LAX",
departureDate="2026-11-12", adults=1, max=5)
for offer in response["data"]:
seg = offer["itineraries"][0]["segments"][0]
print(offer["price"]["total"], seg["carrierCode"], seg["number"], seg["departure"]["at"])
The loop is unchanged. Only response.data becomes response["data"]. Output from a real run on 2 October:
204.00 DL 1788 2026-11-12T12:00:00
204.00 B6 1023 2026-11-12T12:00:00
204.00 B6 623 2026-11-12T15:29:00
204.00 B6 123 2026-11-12T05:45:00
204.00 DL 742 2026-11-12T07:00:00
The run took 5 seconds. Its status message is a one-line answer, handy for logs and AI agents:
5 flight offers JFK-LAX on 2026-11-12. Cheapest 204.00 USD: DL 1788, departs 2026-11-12T12:00:00, PT6H8M.
Google says prices are typical (typical 144-240).
Cheapest Date Search
Amadeus took a date range in departureDate. So does this:
response = amadeus_call("cheapest-date",
origin="SFO", destination="HNL", departureDate="2026-11-01,2026-11-30")
for d in response["data"][:3]: # sorted cheapest first
print(d["departureDate"], d["price"]["total"], d["priceLevel"])
Real run: 30 dates priced in 18 seconds. Cheapest was $163 on 1 November, with 11 more dates at the same price. The priciest was $444 on 20 November. For round trips, pass duration=7 (one trip length; Amadeus-style ranges like 1,15 aren't supported).
Price Analysis
response = amadeus_call("price-metrics",
originIataCode="JFK", destinationIataCode="LAX", departureDate="2026-11-12")
m = response["data"][0]
print({x["quartileRanking"]: x["amount"] for x in m["priceMetrics"]})
{'MINIMUM': '167.00', 'FIRST': '178.00', 'MEDIUM': '178.00', 'THIRD': '204.00', 'MAXIMUM': '215.00'}
Amadeus built these quartiles from its booking data. This version builds them from Google Flights' price history for that exact date, 61 days in this case, and also returns Google's own verdict (typical) and typical range ($144–240). The idea is the same, but the source isn't, so don't compare the numbers one to one.
What's different from Amadeus
Be aware of these before you switch:
-
Prices are what Google Flights shows a shopper in the chosen country (
country: "us"by default). That includes low-cost and airline-direct fares that Amadeus often didn't have. They're shopping prices, not bookable fares. -
Some fields are
nullbecause Google doesn't publish them:numberOfBookableSeats,lastTicketingDate,price.base, andaircraft.code(the aircraft name is inaircraft.nameinstead). - Round-trip offers carry the total trip price but only the outbound itinerary. Google shows return options after you pick an outbound flight.
- Use IATA airport codes. There's no airport or city search endpoint yet.
-
Extras Amadeus never had are under
googleFlightsin each offer: CO₂, legroom, layovers, Google's price level and a link to the search.
Plain HTTP, no SDK
curl -X POST "https://api.apify.com/v2/acts/kuezi~flight-offers-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"endpoint":"flight-offers","originLocationCode":"LHR","destinationLocationCode":"JFK","departureDate":"2026-12-01","max":5}'
That returns the data array directly.
If you were using another Amadeus Self-Service endpoint and want it replaced, tell me which one in the comments. I'll prioritize by demand.
AI disclosure: this post and the tool were produced with an AI agent (Claude) working for me. Every number above comes from real runs on 2 October 2026.
Top comments (0)