diff --git a/.github/workflows/generate-and-publish-sdk-sources.yaml b/.github/workflows/generate-and-publish-sdk-sources.yaml
index 5dec341342..5b9a0bac51 100644
--- a/.github/workflows/generate-and-publish-sdk-sources.yaml
+++ b/.github/workflows/generate-and-publish-sdk-sources.yaml
@@ -23,6 +23,6 @@ jobs:
with:
name: rapid
version: ${{ inputs.version }}
- transformations: "-th -te /v3 --operationIdsToTags"
+ transformations: "-th --operationIdsToTags"
repository: 'ExpediaGroup/rapid-java-sdk'
sdk_repo_ref: ${{ inputs.sdk_repo_ref || 'v20250304' }}
diff --git a/examples/pom.xml b/examples/pom.xml
index 120fe4cd80..0d01772a02 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -11,7 +11,7 @@
1.8
1.8
1.8
- 5.3.2
+ 5.3.2+ads-SNAPSHOT
diff --git a/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkDemoApplication.java b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkDemoApplication.java
index 45e6f2915a..0385f97c81 100644
--- a/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkDemoApplication.java
+++ b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkDemoApplication.java
@@ -1,19 +1,12 @@
package com.expediagroup.sdk.rapid.examples;
import com.expediagroup.sdk.rapid.examples.salesprofiles.DefaultRapidPartnerProfile;
+import com.expediagroup.sdk.rapid.examples.scenarios.addelivery.GetAdsScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.booking.AsyncSingleRoomBookScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.booking.MultiRoomHoldAndResumeBookScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.booking.SingleRoomBookScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.content.GetPropertyContentInAdditionalLanguageScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.content.GetPropertyContentScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetListOfRegionNamesScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetRegionByAncestorIdScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetRegionDetailsAndPropertyIdsScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionAncestorsScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionCategoriesScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionCoordinatesScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionDescendantsScenario;
-import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionWithMultiPolygonCoordinatesScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.managebooking.CancelHeldBookingScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.managebooking.ChangeRoomDetailsScenario;
import com.expediagroup.sdk.rapid.examples.scenarios.managebooking.DeleteRoomScenario;
@@ -186,90 +179,19 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc
logger.info(
"========================== End of Property Content Scenarios ===========================");
- logger.info(
- "============================= Running Geography Scenarios =============================");
-
- /* Run Get List of Region Names Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting all regions with details in a paginated manner
- 2. Filtering region names
- */
- GetListOfRegionNamesScenario getListOfRegionNamesScenario = new GetListOfRegionNamesScenario();
- getListOfRegionNamesScenario.setProfile(new DefaultRapidPartnerProfile());
- getListOfRegionNamesScenario.run();
-
- /* Run Get Region Name of Region Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting region details by region id
- 2. Accessing region details
- */
- GetRegionDetailsAndPropertyIdsScenario getRegionNameOfRegionScenario =
- new GetRegionDetailsAndPropertyIdsScenario();
- getRegionNameOfRegionScenario.setProfile(new DefaultRapidPartnerProfile());
- getRegionNameOfRegionScenario.run();
-
- /* Run Get Region By Ancestor Id Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting paginated regions details by ancestor id
- 2. Accessing region details
- */
- GetRegionByAncestorIdScenario getRegionByAncestorIdScenario =
- new GetRegionByAncestorIdScenario();
- getRegionByAncestorIdScenario.setProfile(new DefaultRapidPartnerProfile());
- getRegionByAncestorIdScenario.run();
-
- /* Run Get Region With MultiPolygon Coordinates Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting region details with multipolygon coordinates by region id
- 2. Accessing region coordinates of type multipolygon
- 3. Accessing every polygon list of coordinates.
- */
- ParseRegionWithMultiPolygonCoordinatesScenario parseRegionWithMultiPolygonCoordinatesScenario =
- new ParseRegionWithMultiPolygonCoordinatesScenario();
- parseRegionWithMultiPolygonCoordinatesScenario.setProfile(new DefaultRapidPartnerProfile());
- parseRegionWithMultiPolygonCoordinatesScenario.run();
-
- /* Run Parse Region Ancestors Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting region details with ancestors by region id
- 2. Parsing region ancestors
- */
- ParseRegionAncestorsScenario parseRegionAncestorsScenario = new ParseRegionAncestorsScenario();
- parseRegionAncestorsScenario.setProfile(new DefaultRapidPartnerProfile());
- parseRegionAncestorsScenario.run();
-
- /* Run Parse Region Descendants Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting region details with descendants by region id
- 2. Parsing region descendants
- */
- ParseRegionDescendantsScenario parseRegionDescendantsScenario =
- new ParseRegionDescendantsScenario();
- parseRegionDescendantsScenario.setProfile(new DefaultRapidPartnerProfile());
- parseRegionDescendantsScenario.run();
-
- /* Run Parse Region Coordinates Scenario using the default profile
- This scenario demonstrates the following:
- 1. Getting region details with coordinates by region id
- 2. Parsing region coordinates
- */
- ParseRegionCoordinatesScenario parseRegionCoordinatesScenario =
- new ParseRegionCoordinatesScenario();
- parseRegionCoordinatesScenario.setProfile(new DefaultRapidPartnerProfile());
- parseRegionCoordinatesScenario.run();
+ logger.info("======================== Running Ad Delivery Scenarios =========================");
- /* Run Parse Region Categories Scenario using the default profile
+ /* Run Get Ads Scenario using the default profile
This scenario demonstrates the following:
- 1. Getting region details with property ids by region id
- 2. Parsing region categories
+ 1. Shopping for properties
+ 2. Getting property availability for test property
+ 3. Getting sponsored listings for the property
*/
- ParseRegionCategoriesScenario parseRegionCategoriesScenario =
- new ParseRegionCategoriesScenario();
- parseRegionCategoriesScenario.setProfile(new DefaultRapidPartnerProfile());
- parseRegionCategoriesScenario.run();
+ GetAdsScenario getAdsScenario = new GetAdsScenario();
+ getAdsScenario.setProfile(new DefaultRapidPartnerProfile());
+ getAdsScenario.run();
- logger.info(
- "=============================== End of Geography Scenarios ===========================");
+ logger.info("=========================== End of Ad Delivery Scenarios ======================");
logger.info(
"=======================================================================================");
diff --git a/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkGeographyDemoApp.java b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkGeographyDemoApp.java
new file mode 100644
index 0000000000..3bfa3ce274
--- /dev/null
+++ b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/RapidSdkGeographyDemoApp.java
@@ -0,0 +1,133 @@
+package com.expediagroup.sdk.rapid.examples;
+
+import com.expediagroup.sdk.rapid.examples.salesprofiles.DefaultRapidPartnerProfile;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetListOfRegionNamesScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetRegionByAncestorIdScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.GetRegionDetailsAndPropertyIdsScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionAncestorsScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionCategoriesScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionCoordinatesScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionDescendantsScenario;
+import com.expediagroup.sdk.rapid.examples.scenarios.geography.ParseRegionWithMultiPolygonCoordinatesScenario;
+import java.util.concurrent.ExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the main class for the Rapid SDK Geography demonstration.
+ */
+public class RapidSdkGeographyDemoApp {
+
+ private static final Logger logger = LoggerFactory.getLogger(RapidSdkGeographyDemoApp.class);
+
+ /**
+ * Main method to run the Rapid SDK Geography demonstration.
+ *
+ * @param args the arguments
+ * @throws ExecutionException the execution exception
+ * @throws InterruptedException the interrupted exception
+ */
+ public static void main(String[] args) throws ExecutionException, InterruptedException {
+
+ logger.info("================================================================================");
+ logger.info("================================================================================");
+ logger.info("== ==");
+ logger.info(
+ "== Howdy! This is a demonstration of Expedia Group RAPID SDK Geography, Enjoy! ==");
+ logger.info("== ==");
+ logger.info("================================================================================");
+ logger.info("================================================================================");
+
+ logger.info("============================ Running Geography Scenarios =======================");
+
+ /* Run Get List of Region Names Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting all regions with details in a paginated manner
+ 2. Filtering region names
+ */
+ GetListOfRegionNamesScenario getListOfRegionNamesScenario = new GetListOfRegionNamesScenario();
+ getListOfRegionNamesScenario.setProfile(new DefaultRapidPartnerProfile());
+ getListOfRegionNamesScenario.run();
+
+ /* Run Get Region Name of Region Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details by region id
+ 2. Accessing region details
+ */
+ GetRegionDetailsAndPropertyIdsScenario getRegionNameOfRegionScenario =
+ new GetRegionDetailsAndPropertyIdsScenario();
+ getRegionNameOfRegionScenario.setProfile(new DefaultRapidPartnerProfile());
+ getRegionNameOfRegionScenario.run();
+
+ /* Run Get Region By Ancestor Id Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting paginated regions details by ancestor id
+ 2. Accessing region details
+ */
+ GetRegionByAncestorIdScenario getRegionByAncestorIdScenario =
+ new GetRegionByAncestorIdScenario();
+ getRegionByAncestorIdScenario.setProfile(new DefaultRapidPartnerProfile());
+ getRegionByAncestorIdScenario.run();
+
+ /* Run Get Region With MultiPolygon Coordinates Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details with multipolygon coordinates by region id
+ 2. Accessing region coordinates of type multipolygon
+ 3. Accessing every polygon list of coordinates.
+ */
+ ParseRegionWithMultiPolygonCoordinatesScenario parseRegionWithMultiPolygonCoordinatesScenario =
+ new ParseRegionWithMultiPolygonCoordinatesScenario();
+ parseRegionWithMultiPolygonCoordinatesScenario.setProfile(new DefaultRapidPartnerProfile());
+ parseRegionWithMultiPolygonCoordinatesScenario.run();
+
+ /* Run Parse Region Ancestors Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details with ancestors by region id
+ 2. Parsing region ancestors
+ */
+ ParseRegionAncestorsScenario parseRegionAncestorsScenario = new ParseRegionAncestorsScenario();
+ parseRegionAncestorsScenario.setProfile(new DefaultRapidPartnerProfile());
+ parseRegionAncestorsScenario.run();
+
+ /* Run Parse Region Descendants Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details with descendants by region id
+ 2. Parsing region descendants
+ */
+ ParseRegionDescendantsScenario parseRegionDescendantsScenario =
+ new ParseRegionDescendantsScenario();
+ parseRegionDescendantsScenario.setProfile(new DefaultRapidPartnerProfile());
+ parseRegionDescendantsScenario.run();
+
+ /* Run Parse Region Coordinates Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details with coordinates by region id
+ 2. Parsing region coordinates
+ */
+ ParseRegionCoordinatesScenario parseRegionCoordinatesScenario =
+ new ParseRegionCoordinatesScenario();
+ parseRegionCoordinatesScenario.setProfile(new DefaultRapidPartnerProfile());
+ parseRegionCoordinatesScenario.run();
+
+ /* Run Parse Region Categories Scenario using the default profile
+ This scenario demonstrates the following:
+ 1. Getting region details with property ids by region id
+ 2. Parsing region categories
+ */
+ ParseRegionCategoriesScenario parseRegionCategoriesScenario =
+ new ParseRegionCategoriesScenario();
+ parseRegionCategoriesScenario.setProfile(new DefaultRapidPartnerProfile());
+ parseRegionCategoriesScenario.run();
+
+ logger.info("============================ End of Geography Scenarios ========================");
+
+ logger.info("================================================================================");
+ logger.info("================================================================================");
+ logger.info("== ==");
+ logger.info("== That's all folks! That was the demonstration of RAPID SDK Geography. ==");
+ logger.info("== ==");
+ logger.info("================================================================================");
+ logger.info("================================================================================");
+ System.exit(0);
+ }
+}
diff --git a/examples/src/main/java/com/expediagroup/sdk/rapid/examples/scenarios/addelivery/GetAdsScenario.java b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/scenarios/addelivery/GetAdsScenario.java
new file mode 100644
index 0000000000..95e5cf2d25
--- /dev/null
+++ b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/scenarios/addelivery/GetAdsScenario.java
@@ -0,0 +1,65 @@
+package com.expediagroup.sdk.rapid.examples.scenarios.addelivery;
+
+import com.expediagroup.sdk.core.model.Response;
+import com.expediagroup.sdk.rapid.examples.Constants;
+import com.expediagroup.sdk.rapid.examples.salesprofiles.RapidPartnerSalesProfile;
+import com.expediagroup.sdk.rapid.examples.scenarios.RapidScenario;
+import com.expediagroup.sdk.rapid.examples.services.AdDeliveryService;
+import com.expediagroup.sdk.rapid.examples.services.ShopService;
+import com.expediagroup.sdk.rapid.models.AdsResponse;
+import com.expediagroup.sdk.rapid.models.Property;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This scenario demonstrates the GetAds operation.
+ */
+public class GetAdsScenario implements RapidScenario {
+
+ private static final Logger logger = LoggerFactory.getLogger(GetAdsScenario.class);
+ private AdDeliveryService adDeliveryService = new AdDeliveryService();
+ private ShopService shopService = new ShopService();
+ private RapidPartnerSalesProfile rapidPartnerSalesProfile;
+
+ /**
+ * Sets the profile.
+ *
+ * @param rapidPartnerSalesProfile the profile
+ */
+ @Override
+ public void setProfile(RapidPartnerSalesProfile rapidPartnerSalesProfile) {
+ this.rapidPartnerSalesProfile = rapidPartnerSalesProfile;
+ }
+
+ @Override
+ public void run() {
+
+ logger.info("Running Get Lodging Ads...");
+
+ // Shopping for properties
+ logger.info("Getting property availability for test property: {}", Constants.TEST_PROPERTY_ID);
+
+ List propertyAvailabilityList = shopService.getPropertiesAvailability(
+ Arrays.asList("2"), this.rapidPartnerSalesProfile).getData();
+
+ if (propertyAvailabilityList == null || propertyAvailabilityList.isEmpty()) {
+ throw new IllegalStateException("No property availability found for the test property.");
+ }
+
+ // Get the property ids from response
+ ArrayList propertyIds = new ArrayList<>();
+ propertyAvailabilityList.forEach(property -> propertyIds.add(property.getPropertyId()));
+
+ // call Ad Delivery API
+ logger.info("Calling GetAdsOperation for property ids:");
+ propertyIds.forEach(propertyId -> logger.info("Property Id: [{}]", propertyId));
+
+ Response adsResponse = adDeliveryService.getAds(propertyIds);
+ logger.info("Get ads response status: [{}]", adsResponse.getStatusCode());
+ logger.info("Get ads response, number of sponsored listings: {}", adsResponse.getData()
+ .getSponsoredListings().size());
+ }
+}
diff --git a/examples/src/main/java/com/expediagroup/sdk/rapid/examples/services/AdDeliveryService.java b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/services/AdDeliveryService.java
new file mode 100644
index 0000000000..c0b9982060
--- /dev/null
+++ b/examples/src/main/java/com/expediagroup/sdk/rapid/examples/services/AdDeliveryService.java
@@ -0,0 +1,65 @@
+package com.expediagroup.sdk.rapid.examples.services;
+
+import com.expediagroup.sdk.core.model.Response;
+import com.expediagroup.sdk.rapid.examples.Constants;
+import com.expediagroup.sdk.rapid.models.AdsRequest;
+import com.expediagroup.sdk.rapid.models.AdsResponse;
+import com.expediagroup.sdk.rapid.models.GuestCounts;
+import com.expediagroup.sdk.rapid.models.PageType;
+import com.expediagroup.sdk.rapid.models.ProductLine;
+import com.expediagroup.sdk.rapid.models.SalesChannel;
+import com.expediagroup.sdk.rapid.models.SortType;
+import com.expediagroup.sdk.rapid.operations.GetAdsOperation;
+import com.expediagroup.sdk.rapid.operations.GetAdsOperationParams;
+import java.time.LocalDate;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This service handles ad delivery operations.
+ */
+public class AdDeliveryService extends RapidService {
+
+ /**
+ * Calls the GetAds operation.
+ *
+ * @param propertyIds the list of property ids
+ * @return the response
+ */
+ public Response getAds(List propertyIds) {
+ GetAdsOperationParams getAdsOperationParams = getAdsOperationParams();
+
+ AdsRequest adsRequest = AdsRequest.builder()
+ .checkin(LocalDate.now().plusDays(20).toString())
+ .checkout(LocalDate.now().plusDays(23).toString())
+ .occupancies(Arrays.asList(GuestCounts.builder().adultCount(2).childCount(0).build()))
+ .searchProductLines(Arrays.asList(ProductLine.LODGING))
+ .propertyIds(propertyIds)
+ .pageType(PageType.SEARCH_RESULTS)
+ .salesChannel(SalesChannel.WEBSITE)
+ .countryCode("US")
+ .experimentIds(Arrays.asList("1234"))
+ .language("en-US")
+ .sortType(SortType.DEFAULT)
+ .build();
+
+ GetAdsOperation getAdsOperation =
+ new GetAdsOperation(getAdsOperationParams, adsRequest);
+
+ return rapidClient.execute(getAdsOperation);
+ }
+
+ /**
+ * Creates the GetAdsOperationParams.
+ *
+ * @return the GetAdsOperationParams
+ */
+ private GetAdsOperationParams getAdsOperationParams() {
+ return GetAdsOperationParams
+ .builder()
+ .customerIp(Constants.CUSTOMER_IP)
+ .customerSessionId(Constants.CUSTOMER_SESSION_ID)
+ .customerId("12345678")
+ .build();
+ }
+}
diff --git a/specs/ad-delivery-specs.yaml b/specs/ad-delivery-specs.yaml
new file mode 100644
index 0000000000..563f930629
--- /dev/null
+++ b/specs/ad-delivery-specs.yaml
@@ -0,0 +1,425 @@
+openapi: 3.0.1
+info:
+ title: Ad Delivery API
+ version: v1
+ description: Retrieves ads.
+ contact:
+ name: 'Media Solutions'
+ email: 'MediaSolutionsAPI1@expedia.com'
+ url: 'https://test.developers.expediagroup.com/docs/'
+tags:
+ - name: Ad Delivery
+ description: API to retrieve ads
+servers:
+ - url: https://test.ean.com/v1
+ - url: https://api.ean.com/v1
+paths:
+ /ads:
+ post:
+ tags:
+ - Ad Delivery
+ description: Returns relevant ads.
+ operationId: getAds
+ parameters:
+ - name: Accept
+ in: header
+ description: Specifies the response format that the client would like to receive back. This must be application/json
+ required: true
+ schema:
+ type: string
+ example: 'application/json'
+ - name: Accept-Encoding
+ in: header
+ description: Specifies the response encoding that the client would like to receive back. This must be gzip.
+ required: true
+ schema:
+ type: string
+ example: 'gzip'
+ - name: User-Agent
+ in: header
+ description: The User-Agent header string from the customer's request, as captured by your integration.
+ required: true
+ schema:
+ type: string
+ example: 'Mozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36'
+ - name: Customer-Ip
+ in: header
+ description: IP address of the customer, as captured by your integration.
+ Ensure your integration passes the customer's IP, not your own. Used for fraud recovery and other important analytics.
+ required: false
+ schema:
+ type: string
+ example: '192.168.123.132'
+ - name: Customer-Session-Id
+ in: header
+ description: Insert your own unique value for each user session, beginning with the first API call.
+ Continue to pass the same value for each subsequent API call during the user's session, using a new value for every new customer session.
+ required: false
+ schema:
+ type: string
+ example: '7f9a24ea-2145-4819-a7b7-2a4cbe1165ab'
+ - name: Customer-Id
+ in: header
+ description: An obfuscated unique identifier for each customer. This should not contain any personal information such as email, first or last name.
+ required: true
+ schema:
+ type: string
+ example: '7f9a24ea-2145-4819-a7b7-2a4cbe1165ab'
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AdsRequest'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AdsResponse'
+ '400':
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'invalid_input'
+ message: 'An invalid request was sent in, please check the nested errors for details.'
+ errors:
+ - type: 'language.required'
+ message: 'A language is required. Supported languages are:
+ [ar-SA, cs-CZ, da-DK, de-DE, el-GR, en-US, es-ES, es-MX, fi-FI, fr-CA, fr-FR, hr-HR, hu-HU, id-ID,
+ is-IS, it-IT, ja-JP, lt-LT, ko-KR, ms-MY, nb-NO, nl-NL, pl-PL, pt-BR, pt-PT, ru-RU, sk-SK, sv-SE,
+ th-TH, tr-TR, uk-UA, vi-VN, zh-CN, zh-TW]'
+ fields:
+ - name: 'language'
+ type: 'request'
+ '401':
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'request_unauthenticated'
+ message: 'Data required to authenticate your request is missing or inaccurate.
+ Ensure that your request follows the guidelines in our documentation.'
+ fields:
+ - name: 'apikey'
+ type: 'header'
+ value: 'jaj3982k239dka328e'
+ - name: 'signature'
+ type: 'header'
+ value: '129d75332614a5bdbe0c7eb540e95a65f9d85a5b53dabb38d19b37fad6312a2bd25c12ee5a82831d55112087e1b'
+ - name: 'timestamp'
+ type: 'header'
+ value: '198284729'
+ - name: 'servertimestamp'
+ type: 'server'
+ value: '198284729'
+ '403':
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'request_unauthorized'
+ message: 'Your request could not be authorized.'
+ '426':
+ description: Upgrade Required
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'upgrade_required'
+ message: 'This service requires the use of TLS.'
+ '429':
+ description: Too Many Requests
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'too_many_requests'
+ message: 'You have reached your capacity for this type of request.'
+ '500':
+ description: Unknown Internal Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'unknown_internal_error'
+ message: 'An internal server error has occurred.'
+ '503':
+ description: Service Unavailable
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ example:
+ type: 'service_unavailable'
+ message: 'This service is currently unavailable.'
+components:
+ schemas:
+ PageType:
+ type: string
+ enum:
+ - other
+ - search_results
+ - details
+ - confirmation
+ example: 'search_results'
+ description: The type of page the ads will be rendered on.
+ SortType:
+ type: string
+ enum:
+ - default
+ example: default
+ description: The sort type selected for the organic results.
+ ProductLine:
+ type: string
+ enum:
+ - car
+ - flight
+ - lodging
+ example: lodging
+ description: The different types of travel product lines a traveler can search for.
+ SalesChannel:
+ type: string
+ enum:
+ - website
+ - mobile_app
+ - mobile_web
+ example: 'mobile_app'
+ description: The sales channel for the request.
+ GuestCounts:
+ type: object
+ required:
+ - adult_count
+ properties:
+ adult_count:
+ type: integer
+ format: int32
+ example: 2
+ child_count:
+ type: integer
+ format: int32
+ example: 1
+ AdsRequest:
+ type: object
+ required:
+ - sales_channel
+ - language
+ - country_code
+ - page_type
+ - search_product_lines
+ - checkin
+ - checkout
+ - occupancies
+ - property_ids
+ properties:
+ country_code:
+ type: string
+ example: 'US'
+ pattern: '^[A-Z]{2}$'
+ description: "The country code of the traveler's point of sale, in ISO 3166-1 alpha-2 format.
+ This should represent the country where the shopping transaction is taking place.
+ For more information see: https://www.iso.org/obp/ui/#search/code/"
+ language:
+ type: string
+ example: 'en-US'
+ pattern: '^[a-z]{2}-[A-Z]{2}$'
+ description: 'Desired language for the response as a subset of BCP47 format that only uses hyphenated pairs of two-digit language and country codes.
+ Use only ISO 639-1 alpha-2 language codes and ISO 3166-1 alpha-2 country codes.
+ See https://www.w3.org/International/articles/language-tags/
+ Language Options: https://developers.expediagroup.com/docs/rapid/resources/reference/language-options'
+ sales_channel:
+ $ref: '#/components/schemas/SalesChannel'
+ page_type:
+ $ref: '#/components/schemas/PageType'
+ sort_type:
+ $ref: '#/components/schemas/SortType'
+ search_product_lines:
+ example: [ 'lodging', 'flight' ]
+ description: The product lines the traveler is searching for. lodging indicates hotel_standalone. lodging and
+ flight would indicate a lodging_package.
+ type: array
+ items:
+ $ref: '#/components/schemas/ProductLine'
+ checkin:
+ type: string
+ description: Check-in date, in ISO 8601 format (YYYY-MM-DD).
+ pattern: '^\d{4}-\d{2}-\d{2}$'
+ example: '2025-01-01'
+ checkout:
+ type: string
+ description: Check-out date, in ISO 8601 format (YYYY-MM-DD).
+ pattern: '^\d{4}-\d{2}-\d{2}$'
+ example: '2025-01-05'
+ occupancies:
+ type: array
+ items:
+ $ref: '#/components/schemas/GuestCounts'
+ description: Each array item represents guests of one room.
+ focused_property_id:
+ type: string
+ description: The property id the ranking of ads should be based on. Examples of a focused property are a
+ customer searching for a specific property and it being pinned to the top of a page or the property
+ recommendation carousel based on the currently or previously viewed property. The focused_property_id itself
+ will be excluded from the ranking.
+ example: '23433'
+ property_ids:
+ type: array
+ items:
+ type: string
+ example: [ '2717582', '16159546', '2025453' ]
+ description: The list of property ids eligible for returning sponsored listings. These are the potential
+ candidates that could be included in the auction.
+ experiment_ids:
+ description: A list of experiment ids that can be used for testing different behavior. The ids can be associated
+ with different tests ran by the publisher and are completely arbitrary. The experiment ids will
+ be included reports back to the publisher.
+ type: array
+ items:
+ type: string
+ example: [ '324324.1', '2423423.3', '3242343.5' ]
+ additionalProperties: false
+ Image:
+ type: object
+ properties:
+ caption:
+ type: string
+ description: The image caption.
+ example: 'Hotel Lobby'
+ link:
+ type: object
+ additionalProperties:
+ $ref: '#/components/schemas/Link'
+ description: The url to retrieve the image.
+ example:
+ "70px":
+ method: GET
+ href: https://i.travelapi.com/hotels/1000000/20000/15300/15237/bef1b976_t.jpg
+ description: An individual image.
+ Creative:
+ type: object
+ properties:
+ image:
+ $ref: '#/components/schemas/Image'
+ description: The image to be rendered for the sponsored listing.
+ additionalProperties: false
+ Link:
+ type: object
+ properties:
+ method:
+ type: string
+ description: The request method used to access the link.
+ example: 'POST'
+ href:
+ type: string
+ description: The URL for the link. This can be absolute or relative. Placeholders will be need to be populated by the client.
+ example: 'https://advertising.expedia.com/sponsoredcontent/v1/View?position=[position]&data=AAAAAQAAAAEAAA'
+ expires:
+ type: string
+ description: If the link expires, this will be the UTC date the link will expire, in ISO 8601 format.
+ example: '2025-07-10 15:00:00.000'
+ description: An individual link.
+ Beacons:
+ type: object
+ required:
+ - view
+ - render
+ - click
+ properties:
+ view:
+ $ref: '#/components/schemas/Link'
+ render:
+ $ref: '#/components/schemas/Link'
+ click:
+ $ref: '#/components/schemas/Link'
+ SponsoredListing:
+ description: The sponsored listing which advertises a specific property.
+ type: object
+ required:
+ - rank
+ - property_id
+ - beacons
+ properties:
+ rank:
+ type: integer
+ pattern: int32
+ minimum: 0
+ example: 1
+ description: The sponsored listing should adhere to the rank and not be re-ranked. This field is 0-based.
+ property_id:
+ type: string
+ example: '13243534'
+ creative:
+ $ref: '#/components/schemas/Creative'
+ beacons:
+ $ref: '#/components/schemas/Beacons'
+ ad_transparency_url:
+ type: string
+ example: 'https://advertising.expedia.com/sponsoredcontent/dsa/id=123'
+ description: The url used to retrieve digital services act information regarding why the ad was selected.
+ additionalProperties: false
+ AdsResponse:
+ type: object
+ properties:
+ sponsored_listings:
+ type: array
+ items:
+ $ref: '#/components/schemas/SponsoredListing'
+ additionalProperties: false
+ Error:
+ type: object
+ properties:
+ type:
+ type: string
+ description: The error type.
+ message:
+ type: string
+ description: A human readable message giving details about this error.
+ fields:
+ type: array
+ description: Details about the specific fields that had an error.
+ items:
+ $ref: '#/components/schemas/Field'
+ errors:
+ type: array
+ description: An array of all the actual errors that occured.
+ items:
+ $ref: '#/components/schemas/ErrorIndividual'
+ description: The overall class of error that occured.
+ Field:
+ type: object
+ properties:
+ name:
+ type: string
+ description: The field that had an error.
+ type:
+ type: string
+ description: The type of the field that had an error.
+ value:
+ type: string
+ description: The value of the field that had an error.
+ description: An individual field that had an error.
+ ErrorIndividual:
+ type: object
+ properties:
+ type:
+ type: string
+ description: The error type.
+ message:
+ type: string
+ description: A human readable message giving details about this error.
+ fields:
+ type: array
+ description: Details about the specific fields that had an error.
+ items:
+ $ref: '#/components/schemas/Field'
+ description: An individual error.
\ No newline at end of file
diff --git a/specs/openapi-merge.json b/specs/openapi-merge.json
new file mode 100644
index 0000000000..e1afeae52d
--- /dev/null
+++ b/specs/openapi-merge.json
@@ -0,0 +1,17 @@
+{
+ "inputs": [
+ {
+ "inputFile": "./rapid-specs.yaml",
+ "pathModification": {
+ "prepend": "/v3"
+ }
+ },
+ {
+ "inputFile": "./ad-delivery-specs.yaml",
+ "pathModification": {
+ "prepend": "/v1"
+ }
+ }
+ ],
+ "output": "./specs.yaml"
+}
diff --git a/specs.yaml b/specs/rapid-specs.yaml
similarity index 99%
rename from specs.yaml
rename to specs/rapid-specs.yaml
index 99ea261fb6..073c223067 100644
--- a/specs.yaml
+++ b/specs/rapid-specs.yaml
@@ -18523,4 +18523,5 @@ components:
\ authentication](https://developers.expediagroup.com/docs/rapid/resources/reference/signature-authentication)\
\ page for full details."
name: Authorization
- in: header
\ No newline at end of file
+ in: header
+