API setup
This section covers the essential steps for successfully integrating with our APIs. Whether you want to receive push events via Webhooks or pull data from our endpoints, we’ve got you covered.
- Push API: Ideal for TAAP and White Label Template partners, push events deliver near-real-time updates directly to your system. Learn how to set up subscriptions, manage authentication, and handle retries.
- Pull API: Designed for White Label Template partners, this allows you to request data when you need it. We’ll walk you through setting up token-based authentication for secure access.
Follow the guidance below to ensure a smooth integration and secure data transmission.
Push-based delivery
This might be relevant to you if you’re a TAAP or a White Label Template partner interested in Itineraries data. Push events are delivered via Webhook and will be sent as an HTTP POST
message to a URL you provide.
To start receiving events, you’ll need to subscribe to an event type and authenticate Expedia as the sender.
Subscriptions and events
Our Subscriptions API allows you to create and manage the events you’d like to receive through our push-based delivery service. You can currently create and manage subscriptions for Itineraries update events, and we’ll be adding more as they become available.
You’ll need an API client ID and secret, which your commercial contact can provide.
Accessing the Subscriptions API
You’ll include an access token that’s specific to your business in all of your API requests. Request this token using your API credentials via the HTTP Basic Authentication mechanism.
- Add an Authorization header with a Base64-encoded string of your API client ID and secret to the token endpoint
https://analytics.ean.com/*/v1/oauth/token
. Replace the*
in the URL with eithertemplate
ortaap
, depending on your partnership. - The token endpoint will return an access token that you’ll use for subsequent API requests. For more details, refer to the Subscriptions API details.
- Include the access token value in future API endpoint requests.
Initial authorization header example
Authorization: Basic base64.b64encode({client-id}:{client-secret})
Token request example
securitySchemes:
oauth:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://analytics.ean.com/taap/v1/oauth/token
Authenticated authorization header example
Authorization: Bearer {access-token}
Managing your subscriptions
After you’ve authenticated with the Subscription API, you can manage your subscriptions, including making a list of your existing subscriptions, creating new ones, and deleting ones that no longer apply.
Creating subscriptions
When creating a subscription you will need to specify:
- The endpoint URL where you want to receive events.
- The event type you want to subscribe to, including the indicator of your partnership:
taap.itinerary.change
ortemplate.itinerary.change
.
Note: Although you can create multiple subscriptions, duplicate subscriptions will result in duplicate event deliveries. To avoid this, list your existing subscriptions before creating new ones.
When a subscription is created, you’ll receive a unique secret key to validate the HMAC (hash-based message authentication code) included with event deliveries.
To list or delete subscriptions, use the HTTP GET /subscriptions
or HTTP DELETE /subscriptions/{subscription_id}
endpoints, respectively. You must use a valid token.
For additional details, refer to the Subscriptions API details.
Authenticating Expedia as the sender
We’ll send push events to the endpoint you provide, with each event including an HMAC signature in the authorization header. You should validate this signature using the shared secret we’ll provide to ensure secure and trusted data transmission.
Authorization header example
"authorization": "MAC ts='1731524372777',nonce='f88e57ed-aaf5-4edd-8e58-9105817fb4cb',bodyhash='8YLHy71r5dx3PQjdcOkRuVYXaakjhbJSROEnlreQEIA=',mac='bDxvx41INtDxtkbZwTmAMADZGiFl6/xyXC1lE5ixPuY='"
Step 1: Configure validation
Add these HMAC configuration settings to your push API endpoint:
hmac.validator.sharedSecretKey={mySecretKey}
hmac.validator.endpoint=https:{//example.com}
hmac.validator.methodType=POST
Step 2: Add validation module
Validate the HMAC signature by adding this public class code to the endpoint:
@Component
public class HmacValidator {
private static final String HMAC_SHA256 = "HmacSHA256";
private static final String DEFAULT_PORT = "443";
private final String sharedSecretKey;
private final String endpoint;
private final String methodType;
// Constructor for initialization
public HmacValidator(@Value("${hmac.validator.sharedSecretKey}") String sharedSecretKey,
@Value("${hmac.validator.endpoint}") String endpoint,
@Value("${hmac.validator.methodType:POST}") String methodType) {
this.sharedSecretKey = sharedSecretKey;
this.endpoint = endpoint;
this.methodType = methodType; // Default to POST if not provided
}
public boolean validate(String signature) {
//Validation logic here
}
}
Step 3: Implement validation logic
The logic for signature validation should follow these steps:
- Parse the authorization header to extract components.
- Generate an HMAC signature using the extracted components and
sharedSecretKey
. - Compare the generated signature with the one in the authorization header.
Code sample
// Validate the signature
public boolean validate(String signature) {
Map<String, String> components = parseSignature(signature);
if (components == null || components.isEmpty()) {
return false; // Invalid format or empty signature
}
String generatedHmacSignature = generateHmacSignature(components);
System.out.println("Generated HMAC Signature: " + generatedHmacSignature);
System.out.println("Received HMAC Signature: " + components.get("mac"));
return generatedHmacSignature.equals(components.get("mac"));
}
// Parse the signature into its components
private Map<String, String> parseSignature(String signature) {
// Define the pattern for each key-value pair in the format "key='value'"
Pattern pattern = Pattern.compile("([a-zA-Z]+)='([^']*)'");
Matcher matcher = pattern.matcher(signature);
// Store results in a map
Map<String, String> components = new HashMap<>();
// Extract each key-value pair
while (matcher.find()) {
components.put(matcher.group(1), matcher.group(2));
}
return components;
}
// Generate the HMAC signature using components
public String generateHmacSignature(Map<String, String> components) {
try {
URL url = new URL(endpoint);
String signature = String.format("%s/n%s/n%s/n%s/n%s/n%s/n%s/n",
components.get("ts"),
components.get("nonce"),
methodType.toUpperCase(),
url.getPath(),
url.getHost(),
url.getPort() == -1 ? DEFAULT_PORT : String.valueOf(url.getPort()),
components.get("bodyhash"));
return calculateHMAC(signature);
} catch (Exception e) {
throw new RuntimeException("Failed to generate HMAC signature", e);
}
}
// Calculate the HMAC from the signature string
private String calculateHMAC(String signature) {
try {
Mac mac = Mac.getInstance(HMAC_SHA256);
SecretKeySpec secretKeySpec = new SecretKeySpec(sharedSecretKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
mac.init(secretKeySpec);
byte[] hmacBytes = mac.doFinal(signature.getBytes(StandardCharsets.UTF_8));
return bytesToBase64(hmacBytes);
} catch (Exception e) {
throw new RuntimeException("Failed to calculate HMAC", e);
}
}
// Convert byte array to Base64 string
private String bytesToBase64(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
}
Retrying event failures
If an event fails, the system will retry using an exponential backoff pattern over 7 days: first at 5 minutes, then 60 minutes, and every 12 hours thereafter. We’ll retry any failure because of:
- A non-200 HTTP status code
- A timeout
- An exception from your endpoint
Subscriptions API details
For additional details on the Subscriptions API, download the OpenAPI specification.
Pull-based delivery
If you have a White Label Template site, you can implement pull-based delivery for Itineraries and Loyalty Earn data, depending on the APIs you’re using.
To get access to the Loyalty Earn and Itineraries endpoints, you’ll need an API client ID and secret, which you can get from your commercial contact. You’ll include an access token that’s specific to your business in all of your API requests. Request this token using your API credentials via the HTTP Basic Authentication mechanism.
- Add an Authorization header with a Base64-encoded string of your API client ID and secret to the token endpoint
https://analytics.ean.com/template/v1/oauth/token
. - The token endpoint will return an access token that you’ll use for subsequent API requests. For more details, refer to the OpenAPI specification.
- Include the access token value in future API endpoint requests.
Initial authorization header example
Authorization: Basic base64.b64encode({client-id}:{client-secret})
Token request example
securitySchemes:
oauth:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://analytics.ean.com/template/v1/oauth/token
Authenticated authorization header example
Authorization: Bearer {token}
Once you’ve received your token, you can start making requests against any of the Loyalty Earn or Itineraries endpoints.
When requesting the service, you’ll need to specify your API version. Use the servers.url
value found at the top of our downloadable OpenAPI spec files. It will always correspond with the version number for the API service you’re testing.
The URL should follow this structure:
https://analytics.ean.com/[product]/[API version]/[path]
You can switch between endpoints by replacing the path, but be sure to keep the protocol, domain designation, product, and API version number as laid out in the OpenAPI spec.
Endpoint examples
https://analytics.ean.com/template/v1/loyalty/earn/last_update
https://analytics.ean.com/template/v1/itineraries
To explore the data scope and the API configurations, see the schemas for API delivery:
Itineraries API delivery
Loyalty Earn API delivery