---
title: "Amadeus Self-Service API Integration and Migration Guide"
description: "Operate and migrate Amadeus Self-Service integrations after the 17 July 2026 decommissioning, with clear OAuth, offer-lifecycle, booking-recovery and coverage boundaries."
slug: "amadeus-self-service"
translationKey: "integration-amadeus-self-service"
locale: "en"
type: "guide"
category: "integration"
tags: ["amadeus","hotel-api","flight-api","oauth","repricing","travel-api"]
vertical: ["hotel","flight"]
platform: "Amadeus for Developers"
domain: "developers.amadeus.com"
publishedAt: "2026-09-20"
updatedAt: "2026-09-20"
reviewedAt: "2026-09-20"
sources:
  - title: "Amadeus Enterprise API Portal"
    url: "https://developers.amadeus.com/self-service"
  - title: "Amadeus Self-Service API FAQ (legacy)"
    url: "https://admin.developers.amadeus.com/self-service/apis-docs/guides/developer-guides/faq/"
  - title: "Self-Service API tutorials (legacy)"
    url: "https://admin.developers.amadeus.com/self-service/apis-docs/guides/developer-guides/resources/"
  - title: "Hotel APIs tutorial (legacy)"
    url: "https://admin.developers.amadeus.com/self-service/apis-docs/guides/developer-guides/resources/hotels/"
  - title: "Self-Service API Postman collection (legacy)"
    url: "https://admin.developers.amadeus.com/self-service/apis-docs/guides/developer-guides/developer-tools/postman/"
---

The Amadeus Self-Service portal was decommissioned on 17 July 2026. A new production integration must therefore not assume that Self-Service access can still be purchased or that new credentials can be created. The current starting point is the Amadeus Enterprise API Portal and Amadeus's commercial access process.

This guide is for operating existing Self-Service connections safely, inventorying their dependencies and migrating to a new Amadeus Enterprise or alternative provider adapter. Legacy endpoint behavior remains useful architectural context; current contracts and portal access are authoritative for entitlement, coverage and commercial availability.

## Production migration scenario

In a realistic migration scenario, flight search may still answer while token refresh or order access has stopped, and existing PNRs may still await consolidator ticketing. Modeling the entire integration as one “Amadeus up/down” state creates both duplicate-booking risk and invisible coverage loss.

## What is the current integration boundary?

The former Self-Service catalog covered several distinct surfaces: flight search, pricing and orders; hotel discovery, shopping and booking; and cached inspiration APIs. They were never one availability source or one lifecycle.

Separate two situations:

- **Existing integration:** verify credentials, production traffic and contractual status with Amadeus; define a change freeze and migration plan.
- **New project:** do not select legacy Self-Service endpoints as the target architecture; evaluate current Enterprise access or another supplier.

The provider adapter must not become the owner of:

- canonical airport, city, hotel or traveler identity,
- the multi-provider normalized search contract,
- offer lineage and price observations,
- order and booking-attempt state,
- ticketing or hotel-confirmation reconciliation,
- coverage and fallback policy.

## How did legacy access and OAuth work?

Self-Service applications used an API key and secret to obtain an OAuth 2.0 client-credentials token, with separate base URLs and credentials for test and production. Official legacy tooling documented a 30-minute token lifetime.

If an existing connection must operate during migration:

- keep the secret only in a backend secret manager,
- cache the token according to response expiry,
- refresh with a safety margin,
- use single-flight for concurrent refresh,
- never mix test and production keys,
- do not assume new credentials or entitlement will be issued.

```text
Legacy Credential
       |
       v
OAuth Token Manager ---> expiry-aware cache
       |
       v
Amadeus Adapter ---> migration telemetry
```

Authentication and business-search failures need different alerts. After decommissioning, an auth rejection should not automatically be treated as a transient outage; entitlement or product retirement may be the cause.

## How should the flight lifecycle be modeled?

The legacy Self-Service booking flow used this lifecycle:

```text
Normalized Search Request
        |
        v
Flight Offers Search
        |
        v
Normalized Offer + Original Source Offer
        |
        v
Flight Offers Price
        |
  +-----+------+
  |            |
valid       changed/unavailable
  |            |
  v            v
Create Order  user reconfirm / re-search
  |
  v
Flight Order Management
  |
  +--> retrieve
  +--> cancel where supported
  +--> consolidator ticketing/reconciliation
```

Flight Offers Price is the transaction boundary that checks the selected offer's current price and availability. Do not reconstruct a pricing request from only flight number and total amount; retain the source offer structure required by pricing and order creation.

Ticket issuance was a separate responsibility in Self-Service production booking. The official FAQ described approved-market and local requirements plus an airline-consolidator relationship for Flight Create Orders. An order created and a ticket issued are different business states.

## How should a flight offer be normalized?

```ts
interface NormalizedFlightOffer {
  provider: "amadeus-self-service";
  sourceOfferId: string;
  origin: string;
  destination: string;
  departureAt: string;
  arrivalAt: string;
  segments: Array<{
    marketingCarrier: string;
    operatingCarrier?: string;
    flightNumber: string;
    bookingClass?: string;
  }>;
  passengerTypes: string[];
  fareBrand?: string;
  baggage?: unknown;
  baseAmount: number;
  taxAmount?: number;
  totalAmount: number;
  currency: string;
  observedAt: string;
  sourcePayloadRef: string;
}
```

An air offer is not a flight number plus a price. Segment order, marketing and operating carrier, passenger types, fare family/class, baggage, refund/change rules and source identity must survive through pricing.

## How should hotel identity and lifecycle be separated?

The legacy hotel flow carried two different classes of data:

```text
City / geocode
      |
      v
Hotel List --------> canonical property mapping
      |
      v
Hotel Search ------> real-time offer and payment policy
      |
      v
Hotel Booking -----> durable confirmation identity
```

Hotel List is identity and discovery data. Hotel Search is a transactional offer tied to dates, adults, room quantity and market context. Store the Amadeus hotel ID as an external identifier, never as the canonical property ID.

Legacy V3 documentation describes Hotel Search as real-time and says it does not require a separate validation step. That does not make an offer permanently valid. If booking is delayed, do not treat an old offer ID as durable inventory; classify booking rejection as expiry, availability or price failure rather than hiding it under a generic provider error.

Normalize payment policy as well. Guarantee, deposit and prepay represent different cash-flow and risk. If Hotel Booking carries cards and guest data, keep the PCI/PII boundary on the backend.

## What should normalized search contracts look like?

Use separate flight and hotel contracts; a generic travel-search object erases important provider semantics.

```json
{
  "origin": "IST",
  "destination": "FRA",
  "departureDate": "2026-10-12",
  "returnDate": "2026-10-16",
  "travelers": [{ "type": "ADULT", "count": 1 }],
  "cabin": "ECONOMY",
  "currency": "EUR",
  "market": "TR"
}
```

```json
{
  "canonicalPropertyIds": ["..."],
  "checkIn": "2026-10-12",
  "checkOut": "2026-10-14",
  "adults": 2,
  "roomQuantity": 1,
  "currency": "EUR"
}
```

The adapter translates canonical airport or property mappings into Amadeus IDs and request syntax. Response normalization must retain the original offer or a replayable source reference.

## How should cached discovery differ from transactional data?

Legacy discovery APIs such as Flight Inspiration Search and Flight Cheapest Date Search used a precomputed cache for selected origin-destination pairs. An empty response did not prove there was no flight in the market. Mark those sources as `indicative`.

```text
Inspiration / cheapest date -> indicative, incomplete coverage
Flight Offers Search        -> live shopping context
Flight Offers Price         -> selected-offer validation
Flight Create Orders        -> transactional state change
```

During migration, do not assign cached discovery and a replacement provider's live results the same confidence or freshness class.

## Why is coverage limitation a product state?

The legacy FAQ documented that the Self-Service flight dataset excluded some carriers, low-cost content, negotiated fares and special fares. Do not interpret that list as a 2026 supply guarantee; after portal decommissioning it is historical evidence of the old scope.

Preserve these internal outcomes:

```text
NO_AVAILABILITY
UNSUPPORTED_MARKET_OR_CONTENT
PROVIDER_ACCESS_RETIRED
PROVIDER_TIMEOUT
QUOTA_EXHAUSTED
```

Collapsing all five into an empty results array makes supply loss look like lack of user demand.

## Which data is durable and which is ephemeral?

### Persist durably

- canonical-to-Amadeus airport, city and hotel mappings,
- normalized search context and offer observations,
- source payload reference and schema version,
- displayed and repriced amounts,
- internal booking/order attempt ID,
- provider order or hotel confirmation ID,
- order, ticket and booking lifecycle events,
- coverage and migration audit results.

### Treat as ephemeral

- OAuth access tokens,
- cached inspiration responses,
- live-search offer IDs and booking input state,
- temporary traveler/session context,
- raw payment data.

Ephemeral offer data can be retained briefly for debugging; it is not a durable booking record.

## How should idempotency and unknown state work?

A flight order or hotel booking call can time out after the provider has created state. Blindly retrying the same create operation risks a duplicate booking.

Create an internal attempt first:

```text
booking_attempt
- internal_attempt_id
- provider
- product_type
- source_offer_id
- traveler_fingerprint
- displayed_amount
- confirmed_amount
- status
- provider_confirmation_id
- created_at
```

```text
READY -> SUBMITTED -> CONFIRMED
                  \-> REJECTED
                  \-> UNKNOWN -> retrieve/reconcile/manual review
```

`UNKNOWN` is not `FAILED`. Retrieve the provider outcome where order or booking lookup remains available; otherwise block duplicate submission and route the attempt for operational review.

## What should the error, timeout and retry policy look like?

```text
AUTH_FAILED
ACCESS_RETIRED_OR_DISABLED
QUOTA_EXHAUSTED
INVALID_SEARCH_CONTEXT
UNSUPPORTED_CONTENT
NO_AVAILABILITY
OFFER_EXPIRED
PRICE_CHANGED
PROVIDER_TIMEOUT
PROVIDER_5XX
ORDER_REJECTED
BOOKING_STATE_UNKNOWN
TICKETING_PENDING
CONFIRMATION_RETRIEVE_FAILED
```

Search and read operations may retry network failures and selected 5xx responses with bounded exponential backoff. Validation, unsupported content, price change, retired access and business rejection should not be retried blindly. A `429` is not only a backoff concern; check legacy test quota or access state.

Give the adapter only part of the interactive search deadline. Use a longer but bounded deadline for create operations and start unknown-state recovery after timeout.

## How should reconciliation and migration coexist?

Inventory the existing integration:

- endpoints and API versions in use,
- test/production credentials and last successful call,
- traffic, revenue and booking ownership,
- flight and hotel provider-ID mappings,
- open order, booking and ticketing states,
- cached-discovery dependencies,
- downstream dependencies on response fields.

Add the replacement adapter behind the normalized contract. Compare mappings and offer semantics with shadow traffic or recorded-payload tests. Provider offer IDs cannot be translated into one another; active booking lifecycle must continue reconciling against its original provider identity.

## Which failure modes matter?

### Treating retired access as a transient outage

This creates endless retries and noisy alerts. Model entitlement and retirement explicitly.

### Lossy offer reconstruction

Pricing or order creation loses required segment and fare data. Retain the original source payload or reference.

### Treating cached discovery as live inventory

Unsupported routes appear unavailable or stale prices look transaction-ready.

### Equating an order with a ticket

A PNR/order exists but consolidator ticketing is incomplete. Track separate states and SLAs.

### Hotel identity collision

An Amadeus hotel ID is used as the canonical ID and merges the wrong property from another supplier.

### Blind booking retry

A timeout is followed by a second create call and produces a duplicate reservation.

## What should be monitored?

### Access and migration

- last successful legacy call,
- authentication and retired-access failures,
- remaining endpoint traffic,
- migration coverage by use case,
- count of legacy dependencies.

### Shopping and pricing

- search success and empty-result rate,
- unsupported-content rate,
- provider latency p50/p95,
- offer-to-price success,
- price-change/unavailable rate,
- indicative/live share.

### Booking and fulfillment

- create-order and hotel-booking success,
- unknown-state rate,
- duplicate-prevented count,
- confirmation retrieval success,
- order-to-ticket time and pending-ticket age,
- reconciliation gaps.

### Coverage

- demand coverage by route/property,
- fallback-provider usage,
- provider-specific no-result share,
- conversion by source and freshness class.

## Go-live or migration checklist

- Is the Self-Service decommission status visible to stakeholders?
- Has existing production entitlement been verified with Amadeus?
- Does new development avoid relying on legacy portal access?
- Are test and production credentials separate?
- Are OAuth secrets and tokens backend-only?
- Are flight and hotel normalized contracts separate?
- Are canonical IDs independent of Amadeus IDs?
- Is the original flight offer retained through pricing and order creation?
- Are hotel search context and payment policy retained?
- Are indicative cache and live/transactional results distinct?
- Does a price change require traveler reconfirmation?
- Are booking attempts and unknown-state recovery implemented?
- Are order and ticketing lifecycle separate?
- Are coverage limitations distinct from no availability?
- Is the legacy endpoint inventory and replacement plan complete?
- Do active bookings and orders still reconcile against original provider IDs?
- Are PII/payment logging and retention safe?

## Meta Search takeaway

The Self-Service decommissioning makes the central architecture lesson unusually clear: a provider endpoint must not become the product domain. When canonical identity, normalized requests, source-offer lineage, booking attempts and coverage state remain outside the adapter, a supply source can be replaced. The current engineering question is not how to add another legacy call; it is how to remove the dependency measurably and safely.
