Comparison · observed state retrieved 2026-08-24
Amadeus Self-Service vs FlightPowers, and when to migrate
If your Amadeus Self-Service integration stopped working, this page is a migration path. It shows you how to verify the situation yourself, maps the calls you were making to their equivalents, and is explicit about the things we do not replace.
The observable state
Check it yourself, don’t take our word
We are not going to assert a shutdown date, because we could not find one on an Amadeus page. Here is what was observable on 2026-08-24, with the commands.
The Self-Service portal and pricing pages redirect to the homepage.
curl -sS -o /dev/null -w "%{http_code} -> %{redirect_url}\n" \
https://developers.amadeus.com/self-service
# 301 -> https://developers.amadeus.com/
curl -sS -o /dev/null -w "%{http_code} -> %{redirect_url}\n" \
https://developers.amadeus.com/pricing
# 301 -> https://developers.amadeus.com/The Enterprise portal is still live.
curl -sS -o /dev/null -w "%{http_code}\n" \
https://developers.amadeus.com/enterprise
# 200The Self-Service sandbox host no longer resolves.
curl -sS -m 15 \
https://test.api.amadeus.com/v1/security/oauth2/token
# curl: (6) Could not resolve host: test.api.amadeus.comEvery Amadeus developer SDK repository is archived.
gh api "orgs/amadeus4dev/repos?per_page=100" \
--jq '"archived \([.[]|select(.archived)]|length) of \(length)"'
# archived 20 of 20That includes amadeus-node, amadeus-python and amadeus-java. The developer-guides repository README now opens with:
“# [DEPRECATED] Developer Guides”. “The Amadeus for Developers Self-Service offer has been deprecated.”
Honesty first
First: you may not want us
Amadeus Enterprise still exists and is fully available. If you are an accredited travel business (you hold IATA or ARC accreditation, or you work through a consolidator), Enterprise is the appropriate path and it is a serious platform. Nothing on this page argues otherwise, and no data API is a substitute for a GDS if a GDS is what you need.
This guide is for the people Enterprise is not designed to serve: the indie developers, early-stage startups, internal tooling teams, researchers and AI-agent builders who chose Self-Service precisely because it was self-serve. If your blocker is that the remaining route requires accreditation and an account manager, read on.
Scope, honestly
What we do not replace
Being clear about this up front saves you an afternoon.
| What you may have been using | Do we replace it? | Go here instead |
|---|---|---|
| Flight Create Orders: issuing a ticket, PNR creation | No | Amadeus Enterprise, or Duffel |
| Hotel Booking API: confirmed reservations | No | Amadeus Enterprise, or Duffel Stays |
| Flight Offers Price: confirming an offer is bookable | No | A booking platform |
| Seat maps, baggage, airline ancillaries | No | A booking platform |
| GDS content, published/negotiated fares, corporate contracts | No | Amadeus Enterprise |
| Post-booking lifecycle: changes, cancellations, refunds | No | A booking platform |
| Multi-city / open-jaw itineraries | No | We support one-way and round-trip only |
| Reference data: airports, airlines, cities, POI, transfers, activities | No | Not part of our product |
| Flight Offers Search: shopping for prices | Yes | /v1/flights/oneway, /v1/flights/roundtrip |
| Hotel List + Hotel Search: shopping for room rates | Yes | /v1/hotels/search, /v1/hotels/by-name |
Short version: if the purchase happened inside your product, we are the wrong answer. We return prices and a deep link; the booking happens elsewhere. If you were using Self-Service to shop, monitor, compare or analyse prices (which is what most Self-Service projects did), keep reading.
One more honest note on data: Amadeus served GDS-sourced content. We return live Google Flights consumer pricing. These are genuinely different datasets with different carrier coverage, and neither is a superset of the other. Test your own routes before you commit.
The migration
Auth: delete the token dance
Amadeus used OAuth2 client credentials: fetch a token, watch it expire, refresh it. Here it is one static header.
ACCESS_TOKEN=$(curl -H "Content-Type: application/x-www-form-urlencoded" \
https://test.api.amadeus.com/v1/security/oauth2/token \
-d "grant_type=client_credentials&client_id=$AMADEUS_CLIENT_ID\
&client_secret=$AMADEUS_CLIENT_SECRET" \
| grep access_token | sed 's/"access_token": "\(.*\)"\,/\1/' \
| tr -d '[:space:]')-H "x-api-key: $FLIGHTPOWERS_API_KEY"Get the key by subscribing on RapidAPI. There is a free tier (10 requests/month, hard cap). You can delete your token-refresh code and its cache. Confirm a key authenticates with GET /v1/verify before running real searches.
The migration
Flight Offers Search → /v1/flights
curl -X GET "https://test.api.amadeus.com/v2/shopping/flight-offers?\
originLocationCode=SYD&destinationLocationCode=BKK&\
departureDate=2022-08-01&returnDate=2022-08-05&\
adults=2&includedAirlineCodes=TG&max=3" \
-H "Authorization: Bearer $ACCESS_TOKEN"curl -X POST https://api.flightpowers.com/v1/flights/roundtrip \
-H "x-api-key: $FLIGHTPOWERS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_airport": "SYD",
"to_airport": "BKK",
"departure_date": "2026-08-01",
"return_date": "2026-08-05",
"passengers": [1, 1],
"departure_airline_codes": ["TG"],
"limit": 3
}'Parameter mapping
| Amadeus Flight Offers Search | FlightPowers |
|---|---|
originLocationCode | from_airport |
destinationLocationCode | to_airport |
departureDate | departure_date |
returnDate | return_date, and use /v1/flights/roundtrip |
adults | passengers, one entry per traveller: 1 adult, 2 child, 3 infant on lap, 4 infant in seat. Two adults is [1, 1] |
includedAirlineCodes | airline_codes (round-trip: departure_airline_codes / return_airline_codes) |
excludedAirlineCodes | exclude_airline_codes |
max | limit (default 10) |
currencyCode | currency (default usd) |
maxPrice | max_price |
nonStop=true | max_stops: 0 |
travelClass | seat_type: only 1 Economy and 3 Business. Premium economy and first are not supported |
Both APIs handle round-trip in a single request, so there is no gain to claim there. The difference is that ours is a dedicated endpoint that returns paired legs with a combined total (total_price_as_number, total_duration_seconds, total_stops) plus separate departure_flight_* and return_flight_* blocks, and it accepts per-leg filters. “Leave after 6pm Friday, return before noon Sunday” is one call.
Self-Service had no cheapest-date search on Flight Offers Search: you looped. The REST API here works the same way, but the per-minute rate limits are published so you can parallelise deliberately: a 31-date scan is one burst, not a serial crawl (how that works). If you are building an AI agent, the hosted MCP server at https://flights.flightpowers.com/mcp does the fan-out for you: its flight search accepts a date range and a list of destinations and expands the combinations server-side. That is an MCP-layer feature, not a REST parameter; on REST you loop. See MCP setup.
The migration
Hotel Search → /v1/hotels
# 1. get hotelIds for a city
curl -X GET "https://test.api.amadeus.com/v1/reference-data/\
locations/hotels/by-city?cityCode=PAR" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# 2. price those specific hotels
curl -X GET "https://test.api.amadeus.com/v3/shopping/hotel-offers?\
hotelIds=MCLONGHM&adults=2&checkInDate=2026-09-10\
&checkOutDate=2026-09-14" \
-H "Authorization: Bearer $ACCESS_TOKEN"curl -X POST https://api.flightpowers.com/v1/hotels/search \
-H "x-api-key: $FLIGHTPOWERS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "Paris",
"checkin_date": "2026-09-10",
"checkout_date": "2026-09-14",
"adults": 2,
"currency": "EUR"
}'| Amadeus Hotel Search v3 | FlightPowers |
|---|---|
hotelIds (via Hotel List by-city/by-geocode) | not needed: destination takes free text like “Paris” or “Tokyo Shibuya” |
checkInDate | checkin_date |
checkOutDate | checkout_date |
adults | adults (default 2) |
roomQuantity | not supported |
currency | currency (default usd) |
priceRange | budget_per_night: max per night, in your currency |
boardType, paymentPolicy, bestRateOnly | partially covered by filters; not a 1:1 mapping |
countryOfResidence | proxy_country: related in intent, different mechanism. Amadeus’s field is a declared attribute passed to the supplier; ours routes the request through a residential proxy in that country, so you see the rates a real visitor from that market sees. Geo-pricing → |
To look up one named property instead of searching a city, use POST /v1/hotels/by-name with hotel_name, checkin_date, checkout_date, and optionally area to disambiguate generic names.
What you gain
What the move buys you
Only claims we can point at. Each links to the page that proves it.
A price verdict, not just a price
Every flight result carries Google’s historical band (price_insights_low / price_insights_high) plus a low | typical | high verdict. Rebuilding a fare-alert feature? That field is the trigger condition, and you don’t accumulate months of history first. It can be null when Google shows no band. Handle that. Proven here →
An honest empty result
X-Search-Status separates “Google genuinely has no itineraries” from “the search did not complete,” and opt-in strict: true turns a degraded search into an HTTP 503 instead of a misleading []. Search status →
A working buy_link on every result
Every itinerary deep-links into Google Flights, so a comparison or alert product can hand off to a bookable page without reconstructing URLs. One-way API →
No OAuth, published rate limits
One static header instead of a token lifecycle, and per-minute rate limits published per plan so parallel date scanning is a documented capability, not a guess. Plans →
Checklist
A migration checklist
- Subscribe on RapidAPI (free tier) and confirm the key authenticates with
GET /v1/verify. - Delete the OAuth token fetch, cache and refresh logic. Replace with one header.
- Rename request fields per the tables above. Watch
adults→passengers(a list) andtravelClass→seat_type(only two cabins). - Rewrite response parsing: the shape is flat JSON, not Amadeus’s
data[]/dictionariesenvelope. - Drop the hotel ID-resolution step; pass
destinationas free text. - Re-point anything that booked to a booking platform. That work does not migrate.
- Run your three hardest routes on both datasets before you cut over. GDS content and Google Flights content are not identical.
Questions, answered plainly
- Did Amadeus Self-Service shut down?
- We are not going to assert a shutdown date, because we could not find one on an Amadeus page. What is observable as of 2026-08-24: the Self-Service portal and pricing pages 301-redirect to the Amadeus homepage, the test sandbox host no longer resolves, all 20 repositories in the amadeus4dev GitHub organisation are archived, and their developer-guides README opens with “The Amadeus for Developers Self-Service offer has been deprecated.” The commands to check each of these yourself are on this page.
- Should I move to Amadeus Enterprise instead?
- If you are an accredited travel business (you hold IATA or ARC accreditation, or work through a consolidator), yes, Enterprise is the appropriate path and it is a serious platform. This page is for the people Enterprise is not designed to serve: indie developers, early-stage startups, internal tooling teams, researchers and AI-agent builders who chose Self-Service precisely because it was self-serve.
- Does FlightPowers replace Flight Create Orders or the Hotel Booking API?
- No. Nothing on our side issues tickets, creates PNRs, or confirms reservations. If the purchase happened inside your product, we are the wrong answer. Go to Amadeus Enterprise or a booking platform like Duffel. We replace the shopping endpoints: Flight Offers Search and Hotel List + Hotel Search.
- Is the data the same as what Amadeus served?
- No, and pretending otherwise would waste your afternoon. Amadeus served GDS-sourced content; we return live Google Flights consumer pricing and live Booking.com hotel rates. These are genuinely different datasets with different carrier coverage, and neither is a superset of the other. Run your three hardest routes on both before you cut over.
- How does authentication change?
- Amadeus used OAuth2 client credentials: fetch a token, watch it expire, refresh it. Here there is no token step: one static x-api-key header, with the key issued by RapidAPI when you subscribe. You can delete your token-refresh code and its cache.
Self-serve, like Self-Service was
Subscribe, get a key, make a call. No account manager, no accreditation. Free tier: 10 requests/month, hard cap.
Free tier: 10 requests/month. No card to try.