Activity Variants
Activity variant mode presents several real activities under a commercial container product. The container provides the public name and commercial information; each variant is a real product with its own availability, concepts and booking codes.
The new catalog and availability representation is returned only when this capability has been activated for your integration's API user. iNeedTours controls this through APIModoVariantes; it is not a request parameter. Confirm activation for the credentials and environment you use.
Even with the capability enabled, only configured Activities are grouped. Ordinary products retain their existing representation. Your integration must therefore support both ordinary products and containers with variants in the same response.
Catalog and activation
| Operation | Mode disabled | Mode enabled |
|---|---|---|
StaticData DEFAULT | Real products remain independent. Containers of active profiles applicable to the channel are excluded; variant suppression is not applied. | Accessible containers are included; variants configured for suppression are excluded as independent products. Non-suppressed variants remain visible. |
StaticData PRODUCTCONTENTS | Contents of the independent real products. | Contents of containers and of remaining independent products. |
Avail | Existing response without Variants. | Containers with available variants, and independent products where applicable. |
Book | Existing booking contract. | Same booking contract: book the real variant, not the container. |
An inactive profile or a profile outside the user's sales channel has no grouping or suppression effect. Its former container is an ordinary product, subject to normal filters and its own inventory. Container visibility and suppression are independent: a hidden container can coexist with suppressed independent variants, leaving no offer for that profile.
Activation changes both catalog and availability representation. Coordinate a fresh catalog import and application-cache refresh with iNeedTours; do not mix catalogs from users with different modes.
Product and content organization
For an ordinary product, its commercial information and bookable concepts belong to the same product. For a grouped activity, these responsibilities are separated:
| Information | Where to obtain it | How to use it |
|---|---|---|
| Commercial identity and catalog metadata | Container product in DEFAULT | Present the activity using the container's product code, name and catalog information. |
| Descriptions and images | PRODUCTCONTENTS, associated by the container's ProductCode | Present the container's commercial content; do not substitute the selected variant's description for it. |
| Available choices | Container's Variants/Variant in Avail | Display each VariantName in Order; the real product name is the fallback. |
| Concepts, dates, hours, service languages and booking requirements | Selected variant's existing Concepts, Details and BookOptions | Let the customer choose a valid selection from the real activity. |
| Reservation identity | Real product in Book, Commit and Read | Keep the real booked service identity; do not replace it with the container code. |
Containers do not merge their variants' descriptions or static concepts. The connection between the commercial container and its currently available variants is supplied by Avail, not by a static list of variants.
STATIC DATA
Use the existing DestServicesStaticDataV2 method with the same API credentials used for Avail. Only the DEFAULT and PRODUCTCONTENTS catalogs are adapted to variant mode; the method and request format are unchanged.
- Query DEFAULT to import the products visible to your API user and their catalog metadata.
- Query PRODUCTCONTENTS with matching service and geographical filters to import descriptions and images. Match
ProductContent.ProductCodeto theProductCodefrom DEFAULT; use the returned content languages and ordering. - Obtain availability and the real variants from Avail when the customer searches. Do not build bookable selections from the container's static record.
Catalog request
This template requests Activities for a destination. Replace the credentials and destination with values for your integration. The geographical filter is optional; use the existing catalog filters appropriate to your import.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<DestServicesStaticDataV2 xmlns="http://xml.ineedtours.com/ws/">
<objCredentials>
<Source>
<RequestorID Type="DSP" ID="{{User}}" MessagePassword="{{Pass}}"/>
</Source>
</objCredentials>
<objRequest>
<ServiceTypeCode>
<DestServiceType>A</DestServiceType>
</ServiceTypeCode>
<StaticMasterData>DEFAULT</StaticMasterData>
<StaticMasterDataFilters>
<DestinationCode>{{DestinationCode}}</DestinationCode>
</StaticMasterDataFilters>
</objRequest>
</DestServicesStaticDataV2>
</soap:Body>
</soap:Envelope>
For contents and images, repeat that method with the same credentials and replace objRequest with:
<objRequest>
<ServiceTypeCode>
<DestServiceType>A</DestServiceType>
</ServiceTypeCode>
<StaticMasterData>PRODUCTCONTENTS</StaticMasterData>
<StaticMasterDataFilters>
<DestinationCode>{{DestinationCode}}</DestinationCode>
</StaticMasterDataFilters>
</objRequest>
Interpreting the catalogs
When the capability is enabled, accessible containers are included and independently offered variants depend on the suppression configuration described above. When it is disabled, applicable containers are excluded and the real products remain independent. Sending DEFAULT or PRODUCTCONTENTS does not itself enable variant mode.
A container in DEFAULT has an empty <Concepts />; it does not publish its own concepts or combine the concepts of its variants. This does not mean its variants have no availability: availability must be requested through Avail.
Static data does not publish Variants, VariantName, variant ordering or profile composition. Discover the currently available variants through Avail. Absence of a variant from the independent catalog does not prevent booking it using valid codes returned inside Variants.
Flow overview
- Import
DEFAULTandPRODUCTCONTENTSfor the configured API user, and associate catalog metadata and commercial content byProductCode. - Call
DestServicesAvailV2with the requested products or destination and dates. - For a container, present its commercial information and let the customer choose from
Variants. For an ordinary product, use its direct concepts as before. - Call
DestServicesBookV2with the real product and concept booking codes of the selected activity. - Complete the questions and passenger information returned by Book, then confirm with
DestServicesCommitV2. - Use
DestServicesReadV2to check the real booked service, its selections and status.
The container is a commercial presentation, not a bookable service. The booking flow does not introduce a new endpoint or a new Commit schema.
AVAIL request
Use ServiceType=A and the existing product or destination search fields. ProductCodes may contain a container identifier or a real product identifier. Requesting a shared real variant can return more than one applicable container.
The following template searches one container. Replace all placeholders with the values assigned for your integration; dates must match the available inventory. Do not send APIModoVariantes in the XML.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<DestServicesAvailV2 xmlns="http://xml.ineedtours.com/ws/">
<objCredentials>
<Source>
<RequestorID Type="DSP" ID="{{User}}" MessagePassword="{{Pass}}"/>
</Source>
</objCredentials>
<objRequest PrimaryLangID="ES">
<ServiceType>A</ServiceType>
<StayDateRange Start="{{DateFrom}}" End="{{DateTo}}"/>
<ProductCodes>
<ProductCode>{{ContainerProductCode}}</ProductCode>
</ProductCodes>
<DataOptions>
<Contents>true</Contents>
<Images>true</Images>
<Attributes>false</Attributes>
</DataOptions>
</objRequest>
</DestServicesAvailV2>
</soap:Body>
</soap:Envelope>
| Field | Use |
|---|---|
PrimaryLangID | Response language, including the variant title or its fallback. |
ServiceType | A for Activities. |
StayDateRange | Dates to evaluate. Only variants available for the search are returned. |
ProductCodes | Public product identifiers, not ProductBookingCode values. |
DataOptions | Existing flags for optional data; they do not activate variant mode. |
AVAIL response
With variant mode enabled, applicable grouped activities use the hierarchy below. Ordinary products continue to expose their direct Concepts without Variants. With the capability disabled, responses keep that existing organization without Variants.
Products
AvailResponseV2Product (container)
ProductBookingCode = 0
Variants
Variant (real product)
ProductCode
ProductName
ProductBookingCode
VariantName
Order
Concepts
AvailResponseV2Concept
ConceptBookingCode
Details
| Field | Meaning |
|---|---|
Container ProductCode | Public identifier of the commercial container. |
Container ProductBookingCode | Always 0; it must not be selected for booking. |
Variants | Optional collection, emitted for applicable visible containers with available variants. |
Variant ProductCode | Real product identifier, with the existing integer type. |
Variant ProductName | Real product name. |
Variant ProductBookingCode | Real product booking code. Send this value to Book. |
VariantName | Profile-specific translated title; falls back to the real product name. |
Order | Display order within the profile. |
Concepts | Existing concept structure and booking codes, unchanged. |
PriceFrom is calculated from the available variant concepts. The container is omitted if there are no available variants or it is not visible. It has no directly bookable concepts.
The following response fragment is illustrative. Codes are invented and cannot be booked:
<AvailResponseV2Product>
<ProductCode>900001</ProductCode>
<ProductName>City experience</ProductName>
<ProductBookingCode>0</ProductBookingCode>
<Variants>
<Variant>
<VariantName>Guided visit</VariantName>
<Order>10</Order>
<ProductCode>910001</ProductCode>
<ProductName>Provider guided tour</ProductName>
<ProductBookingCode>11</ProductBookingCode>
<Concepts>
<AvailResponseV2Concept>
<ConceptCode>920001</ConceptCode>
<ConceptName>Adult</ConceptName>
<ConceptBookingCode>EXAMPLE-NOT-BOOKABLE</ConceptBookingCode>
<!-- Details and BookOptions use the existing Avail contract. -->
</AvailResponseV2Concept>
</Concepts>
</Variant>
</Variants>
</AvailResponseV2Product>
A product can belong to several profiles. A query for a shared variant can return multiple containers, each with its available variants; it may also return the product independently if suppression is disabled. Profile priority does not select a single winning container in Avail.
The same booking-code pair may therefore appear more than once in a response. These are representations of the same priced selection, not instructions to book it repeatedly. Choose the intended quantity once.
A request for multiple ProductCodes is not itself an activation of variant mode; it is the existing multi-product search capability.
Contents and images
Use the existing DataOptions.Contents and DataOptions.Images flags to request directly configured container contents and images. The variant concepts retain their existing details and booking codes.
Do not assume that Avail reproduces all content inheritance rules of PRODUCTCONTENTS: inherited provider or related-product content/image resolution is not covered by the direct-container behavior described here. Validate your content setup with iNeedTours. The returned image URL is a resource reference, not an availability guarantee for the image server.
BOOK
Use Book without changing its schema:
- Use
EchoTokenfrom the current Avail response. - Each selection carries the variant's
ProductBookingCodeand itsConceptBookingCode. - Keep the chosen date, hour, language and quantity consistent with
DetailsandBookOptions. - Do not send the container's
ProductBookingCode=0or attempt to reserve the container through its publicProductCode. - The service and customer documents identify the real product, not the container or the profile's display title.
Selected activity example
This request fragment books one selection from the chosen variant. Replace the placeholders with current Avail values and use the standard Book envelope and credentials described in the method reference. No container identifier is sent as a bookable product.
<objRequest PrimaryLangID="ES" EchoToken="{{AvailEchoToken}}">
<Date>{{SelectedDate}}</Date>
<Concepts>
<BookRequestV2Concept>
<ProductBookingCode>{{VariantProductBookingCode}}</ProductBookingCode>
<Quantity>1</Quantity>
<Hour>{{SelectedHour}}</Hour>
<LangID>{{SelectedServiceLanguage}}</LangID>
<ConceptBookingCode>{{VariantConceptBookingCode}}</ConceptBookingCode>
</BookRequestV2Concept>
</Concepts>
</objRequest>
COMMIT
Build Commit from the current Book responses, using their locator, EchoToken and concept booking codes. Include the selections to confirm and their required passenger details.
Questions belong to each concept. Answer every mandatory question using its returned Code, the required data type and a permitted response where provided. Include RPH when the question requires a passenger reference; do not invent it. Questions of different variants need not have the same codes.
Check BookingExpirationDate before confirming. Do not reuse expired codes or replay examples from an earlier reservation. If Commit times out or returns an ambiguous result, do not retry blindly: check Read and the reservation state first.
Confirming the selected activity
This template confirms the selected activity using the current Book response, not the container identifier. Include every selected concept and its required answers and passengers. The example shows one concept and one passenger; adapt it to the actual Book requirements. Add RPH only when the returned question requires it.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<DestServicesCommitV2 xmlns="http://xml.ineedtours.com/ws/">
<objCredentials>
<Source>
<RequestorID Type="DSP" ID="{{User}}" MessagePassword="{{Pass}}"/>
</Source>
</objCredentials>
<objRequest PrimaryLangID="ES" EchoToken="{{BookEchoToken}}"
TransactionIdentifier="{{TransactionIdentifier}}"
ClientReference="{{ClientReference}}">
<Concepts>
<CommitRequestV2Concept>
<ConceptBookingCode>{{ConceptBookingCode_1}}</ConceptBookingCode>
<Answers>
<Answer Code="{{QuestionCode_1}}">{{Answer_1}}</Answer>
</Answers>
<Guests>
<Guest>
<GivenName>{{GivenName_1}}</GivenName>
<Surname>{{Surname_1}}</Surname>
<BirthDate>{{BirthDate_1}}</BirthDate>
<Age>{{Age_1}}</Age>
<IsChild>false</IsChild>
</Guest>
</Guests>
</CommitRequestV2Concept>
</Concepts>
</objRequest>
</DestServicesCommitV2>
</soap:Body>
</soap:Envelope>
The response uses the existing DestServicesCommitV2Result and BookResponseV2Product structures, not Variants. A successful response must identify the real booked products and their distinct BookingItemIdentifier values.
READ and cancellation
Read must return a separate service for each real product with the expected dates, quantities, amounts and status. Use Cancellation Fees before any authorized Cancel; verify the final state afterwards.
Optional: additional services
Adding more services follows the existing Book contract, not a new requirement of variant mode. Subsequent Books must reuse the first locator in TransactionIdentifier to stay in the same reservation. Keep each response's selected concepts until confirmation; a Book response may describe only the service just added. The existing one-internal-tariff-per-Book restriction still applies: equal RateCode values do not prove a shared internal tariff. See Book.
Validation rules
- Variant mode is configured per API user by iNeedTours, never by a request field.
- Use the same configured API user for static data and Avail; refresh the catalog when activation changes.
- Handle both ordinary products with direct concepts and containers with variants. Not all Activities are grouped.
- Associate commercial content by the container's ProductCode, but book the selected real variant using its returned booking codes.
- Profiles must be active and applicable to the sales channel; an empty channel selection means all channels, not none.
- Suppression removes the independent product representation, not the available variant inside a visible container.
- A hidden container is not returned, even when its variants have availability.
- A container's
ProductBookingCode=0is not usable for booking; its publicProductCodemust not be used as a fallback to book it. - Book selections use current real product/concept codes from Avail. Equal public
RateCodevalues do not prove compatibility with the single-tariff rule. - Complete each concept's mandatory questions and passenger information from its Book response.
- Check expiration and do not retry an ambiguous Commit without checking reservation state.