# Products

## Get Product List

## Get Products

> Fetch the list of products.

```json
{"openapi":"3.1.0","info":{"title":"OCTO API Specification","version":"0.0.0"},"tags":[{"name":"Products"}],"servers":[{"url":"http://localhost:8080/api/octo","description":"","variables":{}},{"url":"https://ventrata-api-1011165921260.us-central1.run.app/api/octo","description":"","variables":{}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"Bearer"}},"parameters":{"RequestHeaders.octoCapabilities":{"name":"Octo-Capabilities","in":"header","required":true,"description":"A list of the Capabilities (their IDs) initialized with your request.","schema":{"type":"string"}},"RequestHeadersContent":{"name":"Accept-Language","in":"header","required":false,"description":"This optional request header allows to specify preferred languages for content in the response. A language code that specifies the language of the product content. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain). This header supports a comma-separated list of language tags with optional quality values (q) to indicate priority, such as en-US, fr-CA;q=0.8, fr;q=0.7, which prioritizes U.S. English, followed by Canadian French, and general French. This header is defined in the HTTP/1.1 specification (RFC 7231) and is commonly used for internationalized websites and services to enhance user experience. For more details, visit MDN Web Docs: Accept-Language - HTTP | MDN. Note this only determines preference and does not guarantee location has content available in the desired language.","schema":{"type":"string"}}},"schemas":{"Product":{"type":"object","required":["id","internalName","reference","locale","allowFreesale","instantConfirmation","instantDelivery","availabilityRequired","availabilityType","deliveryFormats","deliveryMethods","redemptionMethod","options"],"properties":{"id":{"type":"string","description":"The unique identifier for the product, used across the platform to check availability, create bookings, etc. This identifier must be unique within the scope of the supplier’s system to ensure accurate referencing and operations."},"internalName":{"type":"string","description":"The internal name used by the supplier to refer to the product. This name is for internal or operational purposes and may differ from the public, customer-facing name. The customer-facing name is defined separately in the title field under the octo/content capability."},"reference":{"type":"string","nullable":true,"description":"An optional internal code used by the supplier to refer to the product. This field is useful for supplier-specific workflows or cross-referencing. It can be null if no reference code exists for the product."},"locale":{"type":"string","description":"The language code specifying the primary language in which the product operates. It must conform to the IETF BCP 47 standard, which defines language tags for localization (e.g., en-US for American English, fr-FR for French (France), es-ES for Spanish (Spain))."},"timeZone":{"type":"string","description":"The IANA Time Zone identifier indicating the product's location (e.g., America/New_York, Europe/London)."},"allowFreesale":{"type":"boolean","description":"Indicates whether an availabilityId is required when creating a booking. If set to false, bookings can be made without specifying a travel date, creating open-dated bookings."},"instantConfirmation":{"type":"boolean","description":"Indicates whether the customer’s tickets or vouchers are delivered immediately after the booking is confirmed. If false, resellers must manage delayed ticket delivery processes."},"instantDelivery":{"type":"boolean","description":"This indicates whether the Reseller can expect immediate delivery of the customer's tickets. If `false` then the Reseller MUST be able to delay delivery of the tickets to the customer."},"availabilityRequired":{"type":"boolean","description":"Indicates whether an availabilityId is required when creating a booking. If set to false, bookings can be made without specifying a travel date, creating open-dated bookings."},"availabilityType":{"allOf":[{"$ref":"#/components/schemas/AvailabilityType"}],"description":"Specifies the type of availability for the product:\nSTART_TIME: For products with fixed departure times (e.g., walking tour at set times during the day).\nOPENING_HOURS: For products where customers select a date and can visit anytime during operating hours (e.g., museums general admission ticket valid at any time when museum is open)."},"deliveryFormats":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryFormat"},"description":"Lists the formats in which tickets or vouchers for this product are delivered. Each format specifies how the tickets or vouchers will be represented:\nQRCODE: A code presented as a QR Code, commonly used for scanning at entry points.\nCODE128: A linear barcode format widely used for retail and ticketing purposes.\nAZTECCODE: A two-dimensional barcode format similar to QR codes but more compact. It is optimized for small spaces and often used in transportation and event ticketing.\nPDF_URL: A URL linking to a downloadable PDF containing the complete ticket details for this product.\nPKPASS_URL: A URL for adding the ticket to Apple Wallet (Passbook) for easy access on iOS devices.\nThis field ensures resellers can understand and integrate the appropriate ticket delivery formats specifically associated with this product."},"deliveryMethods":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryMethod"},"description":"Specifies all supported methods of how tickets or vouchers for this product are delivered in the booking response:\nTICKET: Delivered individually per unit in the booking, where each person or unit receives a separate ticket.\nVOUCHER: Delivered as a single voucher for the entire booking, consolidating all units under one document.\nThis field ensures clarity on the format of ticket or voucher delivery to resellers and customers."},"redemptionMethod":{"allOf":[{"$ref":"#/components/schemas/RedemptionMethod"}],"description":"Specifies how the product can be redeemed by the customer:\nDIGITAL: The ticket or voucher must be presented, either scanned from a digital device (e.g., smartphone) or as a printed copy. Redemption requires a valid voucher or ticket, even in digital form.\nMANIFEST: The customer’s name, reference, or other information is checked against a manifest by the supplier. Redemption does not require a ticket or voucher.\nPRINT: A physical printed ticket or voucher is strictly required for redemption and must be presented at the time of use.\nThis field ensures resellers and customers understand the specific requirements for redeeming this product."},"options":{"type":"array","items":{"$ref":"#/components/schemas/Option"},"description":"The list array of all options (variations of the product). Each product must have at lest one option. See Option for a detailed on the object."},"defaultCurrency":{"type":"string","description":"Is on the object when Pricing capability is requested. Default currency for this product, if you omit the currency parameter on future endpoints this is the value the reservation system will fallback to."},"availableCurrencies":{"type":"array","items":{"type":"string"},"description":"Is on the object when Pricing capability is requested. All the possible currencies that we accept for this product."},"pricingPer":{"allOf":[{"$ref":"#/components/schemas/PricingPer"}],"description":"Is on the object when Pricing capability is requested. Indicates whether the pricing is per unit (most common), or per booking. Pricing which is per booking is common for private charters or group booking products where the price is the same regardless of how many tickets are purchased."},"title":{"type":"string","description":"The public, customer-facing name of the product. This name is displayed to end customers and should accurately represent the product for marketing and sales purposes"},"shortDescription":{"type":"string","nullable":true,"description":"A brief, customer-facing description of the product. This field provides a concise overview of the product and can be null if no description is available."},"description":{"type":"string","nullable":true,"description":"A detailed description of the product, offering in-depth information about it and relevant details. This field can be null if extended details are not provided."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the product's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the product’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."},"faqs":{"type":"array","items":{"$ref":"#/components/schemas/FAQ"},"description":"An array containing frequently asked questions (FAQs) related to the product. This field is designed to address common customer inquiries by providing clear and concise answers, enhancing the customer experience and reducing potential confusion. Each object represents a single question and its corresponding answer. Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"A list of media files hosted at stable URLs. Media enhances the visual and informational representation of the product, supporting images, videos, or documents.\nNote: Media details are intentionally repeated at both product and option levels. Suppliers should use the level most relevant for the resource. Resellers must merge media information for customer presentation."},"locations":{"type":"array","items":{"$ref":"#/components/schemas/Location"},"description":"A list of geographical locations associated with the product. These locations can represent an itinerary where the order of locations matters, such as for tours or experiences, or simply a list of related locations linked to the product. This field is particularly useful for map-dependent reseller platforms, as it provides geographic and contextual details to enhance customer understanding and platform integration. Each object in the array represents a single related location and includes the following fields:"},"categoryLabels":{"type":"array","items":{"$ref":"#/components/schemas/CategoryLabel"},"description":"A list of labels representing the categories applicable to the product or experience. These categories help customers quickly understand the nature, format, or features of the product. The predefined category labels are based on Google's Product Categories for Things to Do, ensuring alignment with industry standards. OCTO has also added custom categories to cover additional popular offerings. OCTO welcomes suggestions for additional categories to ensure consistency and better coverage. Please contact the team to propose updates to the specification."},"durationMinutesFrom":{"type":"integer","description":"Indicates the duration of the product or experience in minutes. If the duration is flexible, this represents the typical minimum duration."},"durationMinutesTo":{"type":"integer","nullable":true,"description":"If a number: Represents the maximum in flexible duration of the product or experience in minutes, defining a range.\nIf null: Indicates that the duration is exact and matches the value of durationMinutesFrom."},"commentary":{"type":"array","items":{"$ref":"#/components/schemas/Commentary"},"description":"A list of commentary options available for the product. Each object in the array specifies the format and language of the commentary."}}},"AvailabilityType":{"type":"string","enum":["START_TIME","OPENING_HOURS"]},"DeliveryFormat":{"type":"string","enum":["PDF_URL","QRCODE","CODE128","PKPASS_URL"]},"DeliveryMethod":{"type":"string","enum":["VOUCHER","TICKET"]},"RedemptionMethod":{"type":"string","enum":["DIGITAL","PRINT","MANIFEST"]},"Option":{"type":"object","required":["id","default","internalName","reference","availabilityLocalStartTimes","cancellationCutoff","cancellationCutoffAmount","cancellationCutoffUnit","requiredContactFields","restrictions","units"],"properties":{"id":{"type":"string","description":"A unique identifier for the option within the product. This ID is critical for identifying specific options during bookings or other API interactions."},"default":{"type":"boolean","description":"Indicates whether the option is the default selection.\ntrue: This option should be rendered and selected first in customer-facing interfaces.\nfalse: The option is not default and requires manual selection."},"internalName":{"type":"string","description":"The internal name used by the supplier to refer to the option. This name is for internal or operational purposes and may differ from the public, customer-facing name. The customer-facing name is defined separately in the title field under the octo/content capability."},"reference":{"type":"string","nullable":true,"description":"An optional internal code used by the supplier to refer to the product. This field is useful for supplier-specific workflows or cross-referencing. It can be null if no reference code exists for the product."},"availabilityLocalStartTimes":{"type":"array","items":{"type":"string"},"minItems":1,"description":"An array containing all possible start times for the option that can be returned during availability. For example a tour with multiple departure times may have multiple:[\"09:00\", \"14:00\", \"17:00\"]."},"cancellationCutoff":{"type":"string","description":"A text description of the option's cancellation policy, providing clear guidelines to customers."},"cancellationCutoffAmount":{"type":"integer","description":"The numeric value of the cutoff period for cancellations, relative to start time or closing hour (of opening hours product)"},"cancellationCutoffUnit":{"allOf":[{"$ref":"#/components/schemas/CancellationCutoffUnit"}],"description":"The time unit associated with the cutoff period. Possible values are:\nhour: Cutoff is measured in hours.\nminute: Cutoff is measured in minutes.\nday: Cutoff is measured in days."},"requiredContactFields":{"type":"array","items":{"$ref":"#/components/schemas/ContactField"},"description":"An array specifying the contact fields required to confirm a booking. These apply to the lead traveler, not individual tickets. Possible values:\nfirstName: The first name of the traveler.\nlastName: The last name of the traveler.\nfullName: The full name of the traveler.\nemailAddress: The email address of the traveler.\nphoneNumber: The phone number of the traveler.\npostalCode: The postal code of the traveler.\ncountry: The country of the traveler.\nnotes: Optional notes from the traveler.\nlocales: Preferred language/localization preferences."},"restrictions":{"allOf":[{"$ref":"#/components/schemas/OptionRestrictions"}],"description":"Specifies the limitations on booking the option."},"units":{"type":"array","items":{"$ref":"#/components/schemas/Unit"},"description":"The list array of all units (ticket types) available for this product. Each unit represents a specific type of ticket (e.g., Adult, Child). See Unit for a detailed on the object."},"pricingFrom":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"pricing":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"title":{"type":"string","description":"The public, customer-facing name of the product. This name is displayed to end customers and should accurately represent the product for marketing and sales purposes"},"shortDescription":{"type":"string","nullable":true,"description":"A brief, customer-facing description of the product. This field provides a concise overview of the product and can be null if no description is available."},"description":{"type":"string","nullable":true,"description":"A detailed description of the product, offering in-depth information about it and relevant details. This field can be null if extended details are not provided."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the product's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the product’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."},"faqs":{"type":"array","items":{"$ref":"#/components/schemas/FAQ"},"description":"An array containing frequently asked questions (FAQs) related to the product. This field is designed to address common customer inquiries by providing clear and concise answers, enhancing the customer experience and reducing potential confusion. Each object represents a single question and its corresponding answer. Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"A list of media files hosted at stable URLs. Media enhances the visual and informational representation of the product, supporting images, videos, or documents.\nNote: Media details are intentionally repeated at both product and option levels. Suppliers should use the level most relevant for the resource. Resellers must merge media information for customer presentation."},"locations":{"type":"array","items":{"$ref":"#/components/schemas/Location"},"description":"A list of geographical locations associated with the product. These locations can represent an itinerary where the order of locations matters, such as for tours or experiences, or simply a list of related locations linked to the product. This field is particularly useful for map-dependent reseller platforms, as it provides geographic and contextual details to enhance customer understanding and platform integration. Each object in the array represents a single related location and includes the following fields:"},"categoryLabels":{"type":"array","items":{"$ref":"#/components/schemas/CategoryLabel"},"description":"A list of labels representing the categories applicable to the product or experience. These categories help customers quickly understand the nature, format, or features of the product. The predefined category labels are based on Google's Product Categories for Things to Do, ensuring alignment with industry standards. OCTO has also added custom categories to cover additional popular offerings. OCTO welcomes suggestions for additional categories to ensure consistency and better coverage. Please contact the team to propose updates to the specification."},"durationMinutesFrom":{"type":"integer","description":"Indicates the duration of the product or experience in minutes. If the duration is flexible, this represents the typical minimum duration."},"durationMinutesTo":{"type":"integer","nullable":true,"description":"If a number: Represents the maximum in flexible duration of the product or experience in minutes, defining a range.\nIf null: Indicates that the duration is exact and matches the value of durationMinutesFrom."},"commentary":{"type":"array","items":{"$ref":"#/components/schemas/Commentary"},"description":"A list of commentary options available for the product. Each object in the array specifies the format and language of the commentary."}}},"CancellationCutoffUnit":{"type":"string","enum":["hour","minute","day"]},"ContactField":{"type":"string","enum":["firstName","lastName","emailAddress","phoneNumber","country","notes","locales","allowMarketing","postalCode"]},"OptionRestrictions":{"type":"object","required":["minUnits","maxUnits"],"properties":{"minUnits":{"type":"integer","nullable":true,"description":"The minimum number of units (tickets) that can be purchased in a single booking. A null value indicates no minimum."},"maxUnits":{"type":"integer","nullable":true,"description":"The maximum number of units (tickets) that can be purchased in a single booking. A null value indicates no maximum."}}},"Unit":{"type":"object","required":["id","internalName","reference","type","restrictions","requiredContactFields"],"properties":{"id":{"type":"string","description":"The unique identifier for this unit within the scope of the option. This ID ensures that each unit can be uniquely referenced and managed."},"internalName":{"type":"string","description":"An internal name for the unit, used for backend purposes and not visible to customers. This field helps with identifying and managing the unit in the supplier’s system."},"reference":{"type":"string","nullable":true,"description":"An optional internal reference code used by the supplier for identification purposes. This field may not be unique and is meant for operational use."},"type":{"allOf":[{"$ref":"#/components/schemas/UnitType"}],"description":"This is the base unit type for this unit definition. A value of TRAVELLER must only be used in replacement of ADULT, CHILD, INFANT, YOUTH, STUDENT, MILITARY or SENIOR. "},"restrictions":{"allOf":[{"$ref":"#/components/schemas/UnitRestrictions"}],"description":"Specifies booking or usage restrictions for the unit."},"requiredContactFields":{"type":"array","items":{"$ref":"#/components/schemas/ContactField"},"description":"Lists the contact information required per ticket for the unit. Possible values include:\nfirstName: First name of the ticket holder.\nlastName: Last name of the ticket holder.\nfullName: Full name, as a combination of first and last name.\nemailAddress: Email address of the ticket holder.\nphoneNumber: Phone number of the ticket holder.\npostalCode: Postal code for identification purposes.\ncountry: Country code (ISO 3166-1 alpha-2).\nnotes: Additional notes or special instructions.\nlocales: Locale preferences (IETF BCP 47 tags)."},"pricingFrom":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"pricing":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"title":{"type":"string","nullable":true,"description":"The public-facing name of the unit, designed to be displayed to customers. This should clearly convey the nature of the unit, such as \"Adult\" or \"Student\"."},"shortDescription":{"type":"string","description":"A concise summary of the unit, offering key details to customers. This helps in differentiating units and highlighting important characteristics."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the unit's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the option’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."}}},"UnitType":{"type":"string","enum":["ADULT","YOUTH","CHILD","INFANT","FAMILY","SENIOR","STUDENT","MILITARY","OTHER"]},"UnitRestrictions":{"type":"object","required":["minAge","maxAge","idRequired","minQuantity","maxQuantity","paxCount","accompaniedBy"],"properties":{"minAge":{"type":"integer","description":"Minimum age to purchase the unit."},"maxAge":{"type":"integer","description":"Maximum age to purchase the unit."},"idRequired":{"type":"boolean","description":"Indicates if identification (e.g., student ID) is required for redemption."},"minQuantity":{"type":"integer","nullable":true,"description":"Minimum number of units that must be purchased (e.g., 2 tickets). Null means no minimum."},"maxQuantity":{"type":"integer","nullable":true,"description":"Maximum number of units allowed in a single booking. Null means unlimited."},"paxCount":{"type":"integer","description":"The number of people each unit represents (e.g., 1 family ticket = 4 pax)."},"accompaniedBy":{"type":"array","items":{"type":"string"},"description":"Specifies if this unit must be accompanied by another unit (e.g., an infant ticket must be purchased with an adult ticket). Array of unit IDs which must be booked together. "},"minHeight":{"type":"integer","description":"Minimum height required for this unit (e.g., for amusement park rides)."},"maxHeight":{"type":"integer","description":"Maximum height allowed."},"heightUnit":{"type":"string","description":"Unit of height measurement (e.g., \"cm\" or \"in\") used for values of minHeight, maxHeight."},"minWeight":{"type":"integer","description":"Minimum weight required."},"maxWeight":{"type":"integer","description":"Maximum weight allowed."},"weightUnit":{"type":"string","description":"Unit of weight measurement (e.g., \"kg\" or \"lb\") used for values of minWeight, maxWeight."}}},"Pricing":{"type":"object","required":["original","retail","net","currency","currencyPrecision","includedTaxes"],"properties":{"original":{"type":"integer","description":"Represents the advertised marketing price, which must be equal to or higher than pricingFrom.retail. Typically used for strike-through pricing, it highlights the original or component-based value of the product when the retail price reflects a discount or bundled offer. For example, a package product combining multiple components (e.g., hotel + tour + meals) may have a total component value of $500 (original), while the bundled retail price is $400. In such cases, the original price is displayed to show savings.This field should only be shown when it is higher than pricingFrom.retail and must accurately reflect a valid reference price, ensuring transparency and trust."},"retail":{"type":"integer","description":"The supplier’s recommended sale price, including all taxes and fees. This is the price charged to end customers and represents the total cost."},"net":{"type":"integer","nullable":true,"description":"The wholesale price charged to the reseller, including all taxes and fees. This price reflects the amount the reseller pays to the supplier."},"currency":{"type":"string","description":"Specifies the currency used for the prices provided in the pricingFrom object. The value must adhere to ISO 4217 currency codes (e.g., USD, EUR, JPY) to ensure consistency across systems."},"currencyPrecision":{"type":"integer","description":"All pricing is given in integers to avoid floating point rounding issues. e.g. USD = 2 and JPY = 0. To convert a price to decimal you should do: price / (10 ** currencyPrecision) where ** is to the power of e.g. Math.pow(10, currencyPrecision)."},"includedTaxes":{"type":"array","items":{"$ref":"#/components/schemas/Tax"},"description":"This field defines the number of decimal places used for the currency in the pricingFrom object, ensuring precise representation and preventing rounding errors during calculations. For example, in currencies like USD, which have a precision of 2, prices are expressed in cents (e.g., $45.00 is represented as 4500). In currencies like JPY, which have a precision of 0, prices are expressed as whole yen amounts (e.g., ¥4500 is represented as 4500). By aligning with the specific decimal requirements of different currencies, this field guarantees accurate pricing calculations and consistent handling across various currency formats."}}},"Tax":{"type":"object","required":["name","retail","original","net"],"properties":{"name":{"type":"string","description":"The name of the tax or fee, such as \"VAT\", \"City Tax\", or \"Service Charge\". This field provides clear labeling of the tax or fee being applied, making the pricing structure easier to interpret."},"retail":{"type":"integer","description":"The value of the tax or fee included in the retail price, expressed in the same currency as the pricingFrom.currency. This value indicates the portion of the end-customer price attributable to the specific tax or fee."},"original":{"type":"integer","description":""},"net":{"type":"integer","nullable":true,"description":"The value of the tax or fee included in the net price, expressed in the same currency as the pricingFrom.currency. This value indicates the portion of the reseller’s cost attributable to the specific tax or fee."}}},"Feature":{"type":"object","required":["shortDescription","type"],"properties":{"shortDescription":{"type":"string","nullable":true,"description":"A brief summary of a specific feature, providing quick and precise information about an aspect of the product."},"type":{"allOf":[{"$ref":"#/components/schemas/FeatureType"}],"description":"Specifies the category of the feature to ensure clear and organized communication. Each category serves a distinct purpose:\n\nINCLUSION: Details what is included in the product offering (e.g., \"Hotel pickup included,\" \"Lunch provided,\" \"All equipment supplied\"), emphasizing the product's completeness and value.\nEXCLUSION: Lists what is not included (e.g., \"Gratuities not included,\" \"Admission tickets not provided\"), managing customer expectations and reducing ambiguity.\nHIGHLIGHT: Emphasizes the product's key selling points or unique aspects (e.g., \"Skip-the-line access to the Eiffel Tower,\" \"Expert-guided tour\"), captivating potential customers by showcasing standout qualities.\nPREBOOKING_INFORMATION: Contains essential details customers need to know before booking (e.g., \"Not suitable for children under 3 years,\" \"Wear sturdy footwear\").\nPREARRIVAL_INFORMATION: Offers details to prepare customers for their experience before arrival (e.g., \"Arrive 15 minutes early,\" \"Bring a printed ticket\").\nREDEMPTION_INSTRUCTION: Provides clear instructions on how to redeem the product or service (e.g., \"Show your booking confirmation at the ticket counter,\" \"Scan your QR code upon entry\").\nACCESSIBILITY_INFORMATION: Highlights accessibility-related details (e.g., \"Wheelchair accessible,\" \"No elevators available\").\nADDITIONAL_INFORMATION: Supplies supplementary details that add context or clarity (e.g., \"Pets allowed with prior notice,\" \"Multilingual guides available\").\nBOOKING_TERM: Describes terms related to the booking process (e.g., \"Reservations must be made at least 48 hours in advance,\" \"No changes allowed after booking\").\nCANCELLATION_TERM: Explains the terms and conditions for cancellations (e.g., \"Free cancellation up to 24 hours before the start time,\" \"Non-refundable\").\nThis structured classification enhances the product's appeal, ensures transparency, and facilitates informed decision-making for resellers and customers."}}},"FeatureType":{"type":"string","enum":["INCLUSION","EXCLUSION","HIGHLIGHT","PREBOOKING_INFORMATION","PREARRIVAL_INFORMATION","REDEMPTION_INSTRUCTION","ACCESSIBILITY_INFORMATION","ADDITIONAL_INFORMATION","BOOKING_TERM","CANCELLATION_TERM"]},"FAQ":{"type":"object","required":["question","answer"],"properties":{"question":{"type":"string","description":"The text of the frequently asked question. This should be a well-phrased question that reflects typical customer concerns or queries about the product (e.g., \"Is hotel pickup included?\", \"What is the cancellation policy?\"). Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"answer":{"type":"string","description":"The detailed response to the corresponding question. Answers should be accurate, informative, and written in a way that resolves customer uncertainty (e.g., \"Yes, hotel pickup is included within a 10-mile radius of the city center.\", \"Cancellations are free up to 24 hours before the activity.\")."}}},"Media":{"type":"object","required":["src","type","rel","title","caption","copyright"],"properties":{"src":{"type":"string","format":"uri","description":"The URL of the media file. The URL must be stable and publicly accessible."},"type":{"allOf":[{"$ref":"#/components/schemas/MediaType"}],"description":"Specifies the type of the media file, which indicates its format and intended usage. Recommended types include: image/jpeg: High-quality compressed images, ideal for general use. Suggested dimensions: 1920x1080 or higher.\nimage/png: Images with transparency or higher visual fidelity, recommended for logos. Suggested dimensions: At least 1000x1000 pixels.\nvideo/mp4: Universal video format for high-quality playback. Suggested resolution: 1080p or higher.\nvideo/avi: A less common video format; MP4 is generally preferred for compatibility.\nexternal/youtube: URL links to YouTube videos for dynamic content. Use a shareable URL format.\nexternal/vimeo: URL links to Vimeo-hosted videos for high-quality or private video content."},"rel":{"allOf":[{"$ref":"#/components/schemas/MediaRel"}],"description":"Defines the relationship of the media file to the supplier's content. Common values include: LOGO: For branding assets like supplier logos.\nCOVER: For primary visual elements representing the supplier.\nGALLERY: For additional images or videos."},"title":{"type":"string","nullable":true,"description":"The title or name of the media, providing a brief description or identifier for the media file. This helps in organizing and identifying media files (e.g., \"Main Attraction Image,\" \"Promotional Video\"). This field can be null if no title is provided."},"caption":{"type":"string","nullable":true,"description":"A caption providing additional context or information about what is depicted in the media. Captions should be customer-facing and provide insights such as \"Overview of the city skyline at sunset\" or \"Guests enjoying the guided tour.\" This field can be null if no caption is provided."},"copyright":{"type":"string","nullable":true,"description":"Information about the copyright status or usage restrictions of the media. This may include details about ownership, licensing terms, or attribution requirements (e.g., \"© 2024 Example Corp, All Rights Reserved\"). If null, it is assumed there are no copyright restrictions or attribution requirements."}}},"MediaType":{"type":"string","enum":["image/jpeg","image/png","video/mp4","video/avi","external/youtube","external/vimeo"]},"MediaRel":{"type":"string","enum":["LOGO","COVER","GALLERY"]},"Location":{"type":"object","required":["title","shortDescription","types","minutesTo","minutesAt","place"],"properties":{"title":{"type":"string","nullable":true,"description":"The name of the location, providing a recognizable identifier for customers (e.g., \"Statue of Liberty\"). This field can be null if no name is available."},"shortDescription":{"type":"string","nullable":true,"description":"A brief description of the location, summarizing its significance or role in the product (e.g., \"Historic landmark and popular tourist destination\"). This field can be null if no description is provided."},"types":{"type":"array","items":{"$ref":"#/components/schemas/LocationType"},"description":"Specifies the roles or purposes of the location within the product. START: The starting point or meeting location for the product or experience. This is where customers are expected to gather before the activity begins.\nREDEMPTION: A location where customers must go to exchange tickets, collect passes, or redeem vouchers before proceeding to the starting point or experience (if applicable).\nITINERARY_ITEM: A designated stop or location within the itinerary, typically where customers pause or spend time during a moving tour or activity.\nPOINT_OF_INTEREST: A notable location or attraction that customers may see or pass by without stopping. Generally used for sightseeing locations.\nADMISSION_INCLUDED: A location where entry is included in the product price, often highlighting an attraction or event that customers can access as part of the experience.\nEND: The final point or drop-off location where the activity concludes."},"minutesTo":{"type":"integer","nullable":true,"description":"The travel time, in minutes, needed to reach this location from the previous one in the itinerary. Useful for building schedules or itineraries. Set to null if travel time is unknown, not relevant, or not required."},"minutesAt":{"type":"integer","nullable":true,"description":"The approximate duration, in minutes, spent at this location. Helps provide clarity on the itinerary or scheduling details. Set to null if the time spent is flexible, unknown, or not applicable."},"place":{"allOf":[{"$ref":"#/components/schemas/Place"}],"description":"An object containing detailed geospatial and postal address data for the location."}}},"LocationType":{"type":"string","enum":["START","ITINERARY_ITEM","POINT_OF_INTEREST","ADMISSION_INCLUDED","END","REDEMPTION"]},"Place":{"type":"object","required":["latitude","longitude","postalAddress","identifiers","sameAs"],"properties":{"latitude":{"type":"number","description":"The latitude of the location, expressed in decimal degrees. Negative values represent southern latitudes."},"longitude":{"type":"number","description":"The longitude of the location, expressed in decimal degrees. Negative values represent western longitudes."},"postalAddress":{"allOf":[{"$ref":"#/components/schemas/PostalAddress"}],"description":"Structured postal address details for the location."},"identifiers":{"allOf":[{"$ref":"#/components/schemas/Identifiers"}],"description":"A list of unique identifiers from third-party platforms (e.g., Google Maps, Yelp, Tripadvisor)."},"sameAs":{"type":"array","items":{"type":"string"},"description":"A list of URLs pointing to web pages or social media profiles for the location."}}},"PostalAddress":{"type":"object","required":["streetAddress","addressLocality","addressRegion","postalCode","addressCountry","postOfficeBoxNumber"],"properties":{"streetAddress":{"type":"string","nullable":true,"description":"The primary address line, such as a street address, P.O. box, or company name. Null if not provided."},"addressLocality":{"type":"string","nullable":true,"description":"The city or locality associated with the address."},"addressRegion":{"type":"string","nullable":true,"description":"The state, province, or region associated with the address."},"postalCode":{"type":"string","nullable":true,"description":"The postal code or ZIP code for the address."},"addressCountry":{"type":"string","nullable":true,"description":"The postal code or ZIP code for the address."},"postOfficeBoxNumber":{"type":"string","nullable":true,"description":"The post office box number associated with the address, if applicable."}}},"Identifiers":{"type":"object","required":["googlePlaceId","applePlaceId","tripadvisorLocationId","yelpPlaceId","facebookPlaceId","foursquarePlaceId","baiduPlaceId","amapPlaceId"],"properties":{"googlePlaceId":{"type":"string","nullable":true},"applePlaceId":{"type":"string","nullable":true},"tripadvisorLocationId":{"type":"string","nullable":true},"yelpPlaceId":{"type":"string","nullable":true},"facebookPlaceId":{"type":"string","nullable":true},"foursquarePlaceId":{"type":"string","nullable":true},"baiduPlaceId":{"type":"string","nullable":true},"amapPlaceId":{"type":"string","nullable":true}},"description":"Specifies the type or source of the identifier for the location. This field defines the platform or system where the identifier is valid, allowing for seamless integration with third-party systems or mapping platforms. Common examples include:\ngooglePlaceId: A unique identifier for locations on Google Maps.\napplePlaceId: A unique identifier for locations on Apple Maps.\ntripadvisorLocationId: A unique identifier for listings on TripAdvisor.\nyelpPlaceId: A unique identifier for locations on Yelp.\nfacebookPlaceId: A unique identifier for places on Facebook.\nfoursquarePlaceId: A unique identifier for venues on Foursquare.\nbaiduPlaceId: A unique identifier for locations on Baidu Maps.\namapPlaceId: A unique identifier for locations on Amap (China-based mapping platform)."},"CategoryLabel":{"type":"string","enum":["multi-day","city-cards","adults-only","animals","audio-guide","beaches","bike-tours","boat-tours","classes","day-trips","family-friendly","fast-track","food","guided-tours","history","hop-on-hop-off","literature","live-music","museums","nightlife","outdoors","private-tours","romantic","recurring-events","self-guided","small-group-tours","sports","theme-parks","walking-tours","wheelchair-accessible","accommodation-included","trip-difficulty-easy","trip-difficulty-medium","trip-difficulty-hard"]},"Commentary":{"type":"object","required":["format","language"],"properties":{"format":{"allOf":[{"$ref":"#/components/schemas/CommentaryFormat"}],"description":"Specifies the format in which commentary is provided. Possible values are:\nIN_PERSON: Live commentary delivered by a guide or host during the activity. Examples include a tour guide providing real-time explanations about historical landmarks or itinerary highlights.\nRECORDED_AUDIO: Pre-recorded audio commentary accessible during the activity. Delivered via headphones, mobile apps, or speaker systems, covering key details in multiple languages.\nWRITTEN: Commentary provided as written material, such as printed brochures, guidebooks, or on-site informational displays at points of interest.\nOTHER: Commentary formats not explicitly listed, such as augmented reality experiences or interactive digital guides."},"language":{"type":"string","description":"Specifies the language in which the commentary is offered, adhering to IETF BCP 47 language tags for compatibility."}}},"CommentaryFormat":{"type":"string","enum":["IN_PERSON","RECORDED_AUDIO","WRITTEN","OTHER"]},"PricingPer":{"type":"string","enum":["BOOKING","UNIT"]},"ErrorUnauthorized":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]},"BaseError":{"type":"object","required":["error","errorMessage"],"properties":{"error":{"type":"string","description":"The error code. A table of possible error codes is shown below."},"errorMessage":{"type":"string","description":"A human-readable error message will be translated depending on the language provided by the Accept-Language header."}}},"ErrorInternalServerError":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]},"ErrorForbidden":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]}}},"paths":{"/products/":{"get":{"operationId":"Products_GetProducts","summary":"Get Products","description":"Fetch the list of products.","parameters":[{"$ref":"#/components/parameters/RequestHeaders.octoCapabilities"},{"$ref":"#/components/parameters/RequestHeadersContent"}],"responses":{"200":{"description":"The request has succeeded.","headers":{"Octo-Capabilities":{"required":true,"description":"A list of the Capabilities (their IDs) initialized with your request.","schema":{"type":"string"}},"Content-Language":{"required":false,"description":"This response header indicates the language of the content being returned in the response. The OCTO specification allows only one language to be returned per response. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain).  To obtain content in multiple languages, separate requests must be made for each desired language. This header is defined in the HTTP/1.1 specification (RFC 7231). For more information, see MDN Web Docs: Content-Language - HTTP | MDN. This response header is required when using Content capability.","schema":{"type":"string"}},"Available-Languages":{"required":false,"description":"This response header is used to inform of the languages in which content is available, helping understand the language options without needing additional requests. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain).  Although not a standard HTTP header, it is commonly used in APIs to list available languages, such as en-US, fr-CA, es-ES, indicating that content can be requested in U.S. English, Canadian French, or Spanish. This response header is required when using Content capability.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}},"400":{"description":"The server could not understand the request due to invalid syntax.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorUnauthorized"},{"$ref":"#/components/schemas/ErrorInternalServerError"},{"$ref":"#/components/schemas/ErrorForbidden"}]}}}}},"tags":["Products"]}}}}
```

## Get Product

## Get Product

> Fetch the product for the given id.

```json
{"openapi":"3.1.0","info":{"title":"OCTO API Specification","version":"0.0.0"},"tags":[{"name":"Products"}],"servers":[{"url":"http://localhost:8080/api/octo","description":"","variables":{}},{"url":"https://ventrata-api-1011165921260.us-central1.run.app/api/octo","description":"","variables":{}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"Bearer"}},"parameters":{"GetProductRequest.id":{"name":"id","in":"path","required":true,"description":"The product id","schema":{"type":"string"}},"RequestHeaders.octoCapabilities":{"name":"Octo-Capabilities","in":"header","required":true,"description":"A list of the Capabilities (their IDs) initialized with your request.","schema":{"type":"string"}},"RequestHeadersContent":{"name":"Accept-Language","in":"header","required":false,"description":"This optional request header allows to specify preferred languages for content in the response. A language code that specifies the language of the product content. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain). This header supports a comma-separated list of language tags with optional quality values (q) to indicate priority, such as en-US, fr-CA;q=0.8, fr;q=0.7, which prioritizes U.S. English, followed by Canadian French, and general French. This header is defined in the HTTP/1.1 specification (RFC 7231) and is commonly used for internationalized websites and services to enhance user experience. For more details, visit MDN Web Docs: Accept-Language - HTTP | MDN. Note this only determines preference and does not guarantee location has content available in the desired language.","schema":{"type":"string"}}},"schemas":{"Product":{"type":"object","required":["id","internalName","reference","locale","allowFreesale","instantConfirmation","instantDelivery","availabilityRequired","availabilityType","deliveryFormats","deliveryMethods","redemptionMethod","options"],"properties":{"id":{"type":"string","description":"The unique identifier for the product, used across the platform to check availability, create bookings, etc. This identifier must be unique within the scope of the supplier’s system to ensure accurate referencing and operations."},"internalName":{"type":"string","description":"The internal name used by the supplier to refer to the product. This name is for internal or operational purposes and may differ from the public, customer-facing name. The customer-facing name is defined separately in the title field under the octo/content capability."},"reference":{"type":"string","nullable":true,"description":"An optional internal code used by the supplier to refer to the product. This field is useful for supplier-specific workflows or cross-referencing. It can be null if no reference code exists for the product."},"locale":{"type":"string","description":"The language code specifying the primary language in which the product operates. It must conform to the IETF BCP 47 standard, which defines language tags for localization (e.g., en-US for American English, fr-FR for French (France), es-ES for Spanish (Spain))."},"timeZone":{"type":"string","description":"The IANA Time Zone identifier indicating the product's location (e.g., America/New_York, Europe/London)."},"allowFreesale":{"type":"boolean","description":"Indicates whether an availabilityId is required when creating a booking. If set to false, bookings can be made without specifying a travel date, creating open-dated bookings."},"instantConfirmation":{"type":"boolean","description":"Indicates whether the customer’s tickets or vouchers are delivered immediately after the booking is confirmed. If false, resellers must manage delayed ticket delivery processes."},"instantDelivery":{"type":"boolean","description":"This indicates whether the Reseller can expect immediate delivery of the customer's tickets. If `false` then the Reseller MUST be able to delay delivery of the tickets to the customer."},"availabilityRequired":{"type":"boolean","description":"Indicates whether an availabilityId is required when creating a booking. If set to false, bookings can be made without specifying a travel date, creating open-dated bookings."},"availabilityType":{"allOf":[{"$ref":"#/components/schemas/AvailabilityType"}],"description":"Specifies the type of availability for the product:\nSTART_TIME: For products with fixed departure times (e.g., walking tour at set times during the day).\nOPENING_HOURS: For products where customers select a date and can visit anytime during operating hours (e.g., museums general admission ticket valid at any time when museum is open)."},"deliveryFormats":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryFormat"},"description":"Lists the formats in which tickets or vouchers for this product are delivered. Each format specifies how the tickets or vouchers will be represented:\nQRCODE: A code presented as a QR Code, commonly used for scanning at entry points.\nCODE128: A linear barcode format widely used for retail and ticketing purposes.\nAZTECCODE: A two-dimensional barcode format similar to QR codes but more compact. It is optimized for small spaces and often used in transportation and event ticketing.\nPDF_URL: A URL linking to a downloadable PDF containing the complete ticket details for this product.\nPKPASS_URL: A URL for adding the ticket to Apple Wallet (Passbook) for easy access on iOS devices.\nThis field ensures resellers can understand and integrate the appropriate ticket delivery formats specifically associated with this product."},"deliveryMethods":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryMethod"},"description":"Specifies all supported methods of how tickets or vouchers for this product are delivered in the booking response:\nTICKET: Delivered individually per unit in the booking, where each person or unit receives a separate ticket.\nVOUCHER: Delivered as a single voucher for the entire booking, consolidating all units under one document.\nThis field ensures clarity on the format of ticket or voucher delivery to resellers and customers."},"redemptionMethod":{"allOf":[{"$ref":"#/components/schemas/RedemptionMethod"}],"description":"Specifies how the product can be redeemed by the customer:\nDIGITAL: The ticket or voucher must be presented, either scanned from a digital device (e.g., smartphone) or as a printed copy. Redemption requires a valid voucher or ticket, even in digital form.\nMANIFEST: The customer’s name, reference, or other information is checked against a manifest by the supplier. Redemption does not require a ticket or voucher.\nPRINT: A physical printed ticket or voucher is strictly required for redemption and must be presented at the time of use.\nThis field ensures resellers and customers understand the specific requirements for redeeming this product."},"options":{"type":"array","items":{"$ref":"#/components/schemas/Option"},"description":"The list array of all options (variations of the product). Each product must have at lest one option. See Option for a detailed on the object."},"defaultCurrency":{"type":"string","description":"Is on the object when Pricing capability is requested. Default currency for this product, if you omit the currency parameter on future endpoints this is the value the reservation system will fallback to."},"availableCurrencies":{"type":"array","items":{"type":"string"},"description":"Is on the object when Pricing capability is requested. All the possible currencies that we accept for this product."},"pricingPer":{"allOf":[{"$ref":"#/components/schemas/PricingPer"}],"description":"Is on the object when Pricing capability is requested. Indicates whether the pricing is per unit (most common), or per booking. Pricing which is per booking is common for private charters or group booking products where the price is the same regardless of how many tickets are purchased."},"title":{"type":"string","description":"The public, customer-facing name of the product. This name is displayed to end customers and should accurately represent the product for marketing and sales purposes"},"shortDescription":{"type":"string","nullable":true,"description":"A brief, customer-facing description of the product. This field provides a concise overview of the product and can be null if no description is available."},"description":{"type":"string","nullable":true,"description":"A detailed description of the product, offering in-depth information about it and relevant details. This field can be null if extended details are not provided."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the product's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the product’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."},"faqs":{"type":"array","items":{"$ref":"#/components/schemas/FAQ"},"description":"An array containing frequently asked questions (FAQs) related to the product. This field is designed to address common customer inquiries by providing clear and concise answers, enhancing the customer experience and reducing potential confusion. Each object represents a single question and its corresponding answer. Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"A list of media files hosted at stable URLs. Media enhances the visual and informational representation of the product, supporting images, videos, or documents.\nNote: Media details are intentionally repeated at both product and option levels. Suppliers should use the level most relevant for the resource. Resellers must merge media information for customer presentation."},"locations":{"type":"array","items":{"$ref":"#/components/schemas/Location"},"description":"A list of geographical locations associated with the product. These locations can represent an itinerary where the order of locations matters, such as for tours or experiences, or simply a list of related locations linked to the product. This field is particularly useful for map-dependent reseller platforms, as it provides geographic and contextual details to enhance customer understanding and platform integration. Each object in the array represents a single related location and includes the following fields:"},"categoryLabels":{"type":"array","items":{"$ref":"#/components/schemas/CategoryLabel"},"description":"A list of labels representing the categories applicable to the product or experience. These categories help customers quickly understand the nature, format, or features of the product. The predefined category labels are based on Google's Product Categories for Things to Do, ensuring alignment with industry standards. OCTO has also added custom categories to cover additional popular offerings. OCTO welcomes suggestions for additional categories to ensure consistency and better coverage. Please contact the team to propose updates to the specification."},"durationMinutesFrom":{"type":"integer","description":"Indicates the duration of the product or experience in minutes. If the duration is flexible, this represents the typical minimum duration."},"durationMinutesTo":{"type":"integer","nullable":true,"description":"If a number: Represents the maximum in flexible duration of the product or experience in minutes, defining a range.\nIf null: Indicates that the duration is exact and matches the value of durationMinutesFrom."},"commentary":{"type":"array","items":{"$ref":"#/components/schemas/Commentary"},"description":"A list of commentary options available for the product. Each object in the array specifies the format and language of the commentary."}}},"AvailabilityType":{"type":"string","enum":["START_TIME","OPENING_HOURS"]},"DeliveryFormat":{"type":"string","enum":["PDF_URL","QRCODE","CODE128","PKPASS_URL"]},"DeliveryMethod":{"type":"string","enum":["VOUCHER","TICKET"]},"RedemptionMethod":{"type":"string","enum":["DIGITAL","PRINT","MANIFEST"]},"Option":{"type":"object","required":["id","default","internalName","reference","availabilityLocalStartTimes","cancellationCutoff","cancellationCutoffAmount","cancellationCutoffUnit","requiredContactFields","restrictions","units"],"properties":{"id":{"type":"string","description":"A unique identifier for the option within the product. This ID is critical for identifying specific options during bookings or other API interactions."},"default":{"type":"boolean","description":"Indicates whether the option is the default selection.\ntrue: This option should be rendered and selected first in customer-facing interfaces.\nfalse: The option is not default and requires manual selection."},"internalName":{"type":"string","description":"The internal name used by the supplier to refer to the option. This name is for internal or operational purposes and may differ from the public, customer-facing name. The customer-facing name is defined separately in the title field under the octo/content capability."},"reference":{"type":"string","nullable":true,"description":"An optional internal code used by the supplier to refer to the product. This field is useful for supplier-specific workflows or cross-referencing. It can be null if no reference code exists for the product."},"availabilityLocalStartTimes":{"type":"array","items":{"type":"string"},"minItems":1,"description":"An array containing all possible start times for the option that can be returned during availability. For example a tour with multiple departure times may have multiple:[\"09:00\", \"14:00\", \"17:00\"]."},"cancellationCutoff":{"type":"string","description":"A text description of the option's cancellation policy, providing clear guidelines to customers."},"cancellationCutoffAmount":{"type":"integer","description":"The numeric value of the cutoff period for cancellations, relative to start time or closing hour (of opening hours product)"},"cancellationCutoffUnit":{"allOf":[{"$ref":"#/components/schemas/CancellationCutoffUnit"}],"description":"The time unit associated with the cutoff period. Possible values are:\nhour: Cutoff is measured in hours.\nminute: Cutoff is measured in minutes.\nday: Cutoff is measured in days."},"requiredContactFields":{"type":"array","items":{"$ref":"#/components/schemas/ContactField"},"description":"An array specifying the contact fields required to confirm a booking. These apply to the lead traveler, not individual tickets. Possible values:\nfirstName: The first name of the traveler.\nlastName: The last name of the traveler.\nfullName: The full name of the traveler.\nemailAddress: The email address of the traveler.\nphoneNumber: The phone number of the traveler.\npostalCode: The postal code of the traveler.\ncountry: The country of the traveler.\nnotes: Optional notes from the traveler.\nlocales: Preferred language/localization preferences."},"restrictions":{"allOf":[{"$ref":"#/components/schemas/OptionRestrictions"}],"description":"Specifies the limitations on booking the option."},"units":{"type":"array","items":{"$ref":"#/components/schemas/Unit"},"description":"The list array of all units (ticket types) available for this product. Each unit represents a specific type of ticket (e.g., Adult, Child). See Unit for a detailed on the object."},"pricingFrom":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"pricing":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"title":{"type":"string","description":"The public, customer-facing name of the product. This name is displayed to end customers and should accurately represent the product for marketing and sales purposes"},"shortDescription":{"type":"string","nullable":true,"description":"A brief, customer-facing description of the product. This field provides a concise overview of the product and can be null if no description is available."},"description":{"type":"string","nullable":true,"description":"A detailed description of the product, offering in-depth information about it and relevant details. This field can be null if extended details are not provided."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the product's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the product’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."},"faqs":{"type":"array","items":{"$ref":"#/components/schemas/FAQ"},"description":"An array containing frequently asked questions (FAQs) related to the product. This field is designed to address common customer inquiries by providing clear and concise answers, enhancing the customer experience and reducing potential confusion. Each object represents a single question and its corresponding answer. Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"},"description":"A list of media files hosted at stable URLs. Media enhances the visual and informational representation of the product, supporting images, videos, or documents.\nNote: Media details are intentionally repeated at both product and option levels. Suppliers should use the level most relevant for the resource. Resellers must merge media information for customer presentation."},"locations":{"type":"array","items":{"$ref":"#/components/schemas/Location"},"description":"A list of geographical locations associated with the product. These locations can represent an itinerary where the order of locations matters, such as for tours or experiences, or simply a list of related locations linked to the product. This field is particularly useful for map-dependent reseller platforms, as it provides geographic and contextual details to enhance customer understanding and platform integration. Each object in the array represents a single related location and includes the following fields:"},"categoryLabels":{"type":"array","items":{"$ref":"#/components/schemas/CategoryLabel"},"description":"A list of labels representing the categories applicable to the product or experience. These categories help customers quickly understand the nature, format, or features of the product. The predefined category labels are based on Google's Product Categories for Things to Do, ensuring alignment with industry standards. OCTO has also added custom categories to cover additional popular offerings. OCTO welcomes suggestions for additional categories to ensure consistency and better coverage. Please contact the team to propose updates to the specification."},"durationMinutesFrom":{"type":"integer","description":"Indicates the duration of the product or experience in minutes. If the duration is flexible, this represents the typical minimum duration."},"durationMinutesTo":{"type":"integer","nullable":true,"description":"If a number: Represents the maximum in flexible duration of the product or experience in minutes, defining a range.\nIf null: Indicates that the duration is exact and matches the value of durationMinutesFrom."},"commentary":{"type":"array","items":{"$ref":"#/components/schemas/Commentary"},"description":"A list of commentary options available for the product. Each object in the array specifies the format and language of the commentary."}}},"CancellationCutoffUnit":{"type":"string","enum":["hour","minute","day"]},"ContactField":{"type":"string","enum":["firstName","lastName","emailAddress","phoneNumber","country","notes","locales","allowMarketing","postalCode"]},"OptionRestrictions":{"type":"object","required":["minUnits","maxUnits"],"properties":{"minUnits":{"type":"integer","nullable":true,"description":"The minimum number of units (tickets) that can be purchased in a single booking. A null value indicates no minimum."},"maxUnits":{"type":"integer","nullable":true,"description":"The maximum number of units (tickets) that can be purchased in a single booking. A null value indicates no maximum."}}},"Unit":{"type":"object","required":["id","internalName","reference","type","restrictions","requiredContactFields"],"properties":{"id":{"type":"string","description":"The unique identifier for this unit within the scope of the option. This ID ensures that each unit can be uniquely referenced and managed."},"internalName":{"type":"string","description":"An internal name for the unit, used for backend purposes and not visible to customers. This field helps with identifying and managing the unit in the supplier’s system."},"reference":{"type":"string","nullable":true,"description":"An optional internal reference code used by the supplier for identification purposes. This field may not be unique and is meant for operational use."},"type":{"allOf":[{"$ref":"#/components/schemas/UnitType"}],"description":"This is the base unit type for this unit definition. A value of TRAVELLER must only be used in replacement of ADULT, CHILD, INFANT, YOUTH, STUDENT, MILITARY or SENIOR. "},"restrictions":{"allOf":[{"$ref":"#/components/schemas/UnitRestrictions"}],"description":"Specifies booking or usage restrictions for the unit."},"requiredContactFields":{"type":"array","items":{"$ref":"#/components/schemas/ContactField"},"description":"Lists the contact information required per ticket for the unit. Possible values include:\nfirstName: First name of the ticket holder.\nlastName: Last name of the ticket holder.\nfullName: Full name, as a combination of first and last name.\nemailAddress: Email address of the ticket holder.\nphoneNumber: Phone number of the ticket holder.\npostalCode: Postal code for identification purposes.\ncountry: Country code (ISO 3166-1 alpha-2).\nnotes: Additional notes or special instructions.\nlocales: Locale preferences (IETF BCP 47 tags)."},"pricingFrom":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"pricing":{"type":"array","items":{"$ref":"#/components/schemas/Pricing"},"description":"Is on the object when Pricing capability is requested. "},"title":{"type":"string","nullable":true,"description":"The public-facing name of the unit, designed to be displayed to customers. This should clearly convey the nature of the unit, such as \"Adult\" or \"Student\"."},"shortDescription":{"type":"string","description":"A concise summary of the unit, offering key details to customers. This helps in differentiating units and highlighting important characteristics."},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"},"description":"An array of structured objects describing various aspects of the unit's features, grouped into clear categories. These include details about what is included, excluded, emphasized, essential, or safety-related, ensuring transparency and enhancing the option’s appeal to customers. Note: Features are intentionally repeated at both product and option levels, allowing suppliers to specify details where most applicable. Resellers must combine information from both levels for a comprehensive customer view."}}},"UnitType":{"type":"string","enum":["ADULT","YOUTH","CHILD","INFANT","FAMILY","SENIOR","STUDENT","MILITARY","OTHER"]},"UnitRestrictions":{"type":"object","required":["minAge","maxAge","idRequired","minQuantity","maxQuantity","paxCount","accompaniedBy"],"properties":{"minAge":{"type":"integer","description":"Minimum age to purchase the unit."},"maxAge":{"type":"integer","description":"Maximum age to purchase the unit."},"idRequired":{"type":"boolean","description":"Indicates if identification (e.g., student ID) is required for redemption."},"minQuantity":{"type":"integer","nullable":true,"description":"Minimum number of units that must be purchased (e.g., 2 tickets). Null means no minimum."},"maxQuantity":{"type":"integer","nullable":true,"description":"Maximum number of units allowed in a single booking. Null means unlimited."},"paxCount":{"type":"integer","description":"The number of people each unit represents (e.g., 1 family ticket = 4 pax)."},"accompaniedBy":{"type":"array","items":{"type":"string"},"description":"Specifies if this unit must be accompanied by another unit (e.g., an infant ticket must be purchased with an adult ticket). Array of unit IDs which must be booked together. "},"minHeight":{"type":"integer","description":"Minimum height required for this unit (e.g., for amusement park rides)."},"maxHeight":{"type":"integer","description":"Maximum height allowed."},"heightUnit":{"type":"string","description":"Unit of height measurement (e.g., \"cm\" or \"in\") used for values of minHeight, maxHeight."},"minWeight":{"type":"integer","description":"Minimum weight required."},"maxWeight":{"type":"integer","description":"Maximum weight allowed."},"weightUnit":{"type":"string","description":"Unit of weight measurement (e.g., \"kg\" or \"lb\") used for values of minWeight, maxWeight."}}},"Pricing":{"type":"object","required":["original","retail","net","currency","currencyPrecision","includedTaxes"],"properties":{"original":{"type":"integer","description":"Represents the advertised marketing price, which must be equal to or higher than pricingFrom.retail. Typically used for strike-through pricing, it highlights the original or component-based value of the product when the retail price reflects a discount or bundled offer. For example, a package product combining multiple components (e.g., hotel + tour + meals) may have a total component value of $500 (original), while the bundled retail price is $400. In such cases, the original price is displayed to show savings.This field should only be shown when it is higher than pricingFrom.retail and must accurately reflect a valid reference price, ensuring transparency and trust."},"retail":{"type":"integer","description":"The supplier’s recommended sale price, including all taxes and fees. This is the price charged to end customers and represents the total cost."},"net":{"type":"integer","nullable":true,"description":"The wholesale price charged to the reseller, including all taxes and fees. This price reflects the amount the reseller pays to the supplier."},"currency":{"type":"string","description":"Specifies the currency used for the prices provided in the pricingFrom object. The value must adhere to ISO 4217 currency codes (e.g., USD, EUR, JPY) to ensure consistency across systems."},"currencyPrecision":{"type":"integer","description":"All pricing is given in integers to avoid floating point rounding issues. e.g. USD = 2 and JPY = 0. To convert a price to decimal you should do: price / (10 ** currencyPrecision) where ** is to the power of e.g. Math.pow(10, currencyPrecision)."},"includedTaxes":{"type":"array","items":{"$ref":"#/components/schemas/Tax"},"description":"This field defines the number of decimal places used for the currency in the pricingFrom object, ensuring precise representation and preventing rounding errors during calculations. For example, in currencies like USD, which have a precision of 2, prices are expressed in cents (e.g., $45.00 is represented as 4500). In currencies like JPY, which have a precision of 0, prices are expressed as whole yen amounts (e.g., ¥4500 is represented as 4500). By aligning with the specific decimal requirements of different currencies, this field guarantees accurate pricing calculations and consistent handling across various currency formats."}}},"Tax":{"type":"object","required":["name","retail","original","net"],"properties":{"name":{"type":"string","description":"The name of the tax or fee, such as \"VAT\", \"City Tax\", or \"Service Charge\". This field provides clear labeling of the tax or fee being applied, making the pricing structure easier to interpret."},"retail":{"type":"integer","description":"The value of the tax or fee included in the retail price, expressed in the same currency as the pricingFrom.currency. This value indicates the portion of the end-customer price attributable to the specific tax or fee."},"original":{"type":"integer","description":""},"net":{"type":"integer","nullable":true,"description":"The value of the tax or fee included in the net price, expressed in the same currency as the pricingFrom.currency. This value indicates the portion of the reseller’s cost attributable to the specific tax or fee."}}},"Feature":{"type":"object","required":["shortDescription","type"],"properties":{"shortDescription":{"type":"string","nullable":true,"description":"A brief summary of a specific feature, providing quick and precise information about an aspect of the product."},"type":{"allOf":[{"$ref":"#/components/schemas/FeatureType"}],"description":"Specifies the category of the feature to ensure clear and organized communication. Each category serves a distinct purpose:\n\nINCLUSION: Details what is included in the product offering (e.g., \"Hotel pickup included,\" \"Lunch provided,\" \"All equipment supplied\"), emphasizing the product's completeness and value.\nEXCLUSION: Lists what is not included (e.g., \"Gratuities not included,\" \"Admission tickets not provided\"), managing customer expectations and reducing ambiguity.\nHIGHLIGHT: Emphasizes the product's key selling points or unique aspects (e.g., \"Skip-the-line access to the Eiffel Tower,\" \"Expert-guided tour\"), captivating potential customers by showcasing standout qualities.\nPREBOOKING_INFORMATION: Contains essential details customers need to know before booking (e.g., \"Not suitable for children under 3 years,\" \"Wear sturdy footwear\").\nPREARRIVAL_INFORMATION: Offers details to prepare customers for their experience before arrival (e.g., \"Arrive 15 minutes early,\" \"Bring a printed ticket\").\nREDEMPTION_INSTRUCTION: Provides clear instructions on how to redeem the product or service (e.g., \"Show your booking confirmation at the ticket counter,\" \"Scan your QR code upon entry\").\nACCESSIBILITY_INFORMATION: Highlights accessibility-related details (e.g., \"Wheelchair accessible,\" \"No elevators available\").\nADDITIONAL_INFORMATION: Supplies supplementary details that add context or clarity (e.g., \"Pets allowed with prior notice,\" \"Multilingual guides available\").\nBOOKING_TERM: Describes terms related to the booking process (e.g., \"Reservations must be made at least 48 hours in advance,\" \"No changes allowed after booking\").\nCANCELLATION_TERM: Explains the terms and conditions for cancellations (e.g., \"Free cancellation up to 24 hours before the start time,\" \"Non-refundable\").\nThis structured classification enhances the product's appeal, ensures transparency, and facilitates informed decision-making for resellers and customers."}}},"FeatureType":{"type":"string","enum":["INCLUSION","EXCLUSION","HIGHLIGHT","PREBOOKING_INFORMATION","PREARRIVAL_INFORMATION","REDEMPTION_INSTRUCTION","ACCESSIBILITY_INFORMATION","ADDITIONAL_INFORMATION","BOOKING_TERM","CANCELLATION_TERM"]},"FAQ":{"type":"object","required":["question","answer"],"properties":{"question":{"type":"string","description":"The text of the frequently asked question. This should be a well-phrased question that reflects typical customer concerns or queries about the product (e.g., \"Is hotel pickup included?\", \"What is the cancellation policy?\"). Note: FAQs are intentionally repeated at both product and option levels, enabling suppliers to address questions specific to each context. Resellers must combine FAQs from both levels for customer presentation."},"answer":{"type":"string","description":"The detailed response to the corresponding question. Answers should be accurate, informative, and written in a way that resolves customer uncertainty (e.g., \"Yes, hotel pickup is included within a 10-mile radius of the city center.\", \"Cancellations are free up to 24 hours before the activity.\")."}}},"Media":{"type":"object","required":["src","type","rel","title","caption","copyright"],"properties":{"src":{"type":"string","format":"uri","description":"The URL of the media file. The URL must be stable and publicly accessible."},"type":{"allOf":[{"$ref":"#/components/schemas/MediaType"}],"description":"Specifies the type of the media file, which indicates its format and intended usage. Recommended types include: image/jpeg: High-quality compressed images, ideal for general use. Suggested dimensions: 1920x1080 or higher.\nimage/png: Images with transparency or higher visual fidelity, recommended for logos. Suggested dimensions: At least 1000x1000 pixels.\nvideo/mp4: Universal video format for high-quality playback. Suggested resolution: 1080p or higher.\nvideo/avi: A less common video format; MP4 is generally preferred for compatibility.\nexternal/youtube: URL links to YouTube videos for dynamic content. Use a shareable URL format.\nexternal/vimeo: URL links to Vimeo-hosted videos for high-quality or private video content."},"rel":{"allOf":[{"$ref":"#/components/schemas/MediaRel"}],"description":"Defines the relationship of the media file to the supplier's content. Common values include: LOGO: For branding assets like supplier logos.\nCOVER: For primary visual elements representing the supplier.\nGALLERY: For additional images or videos."},"title":{"type":"string","nullable":true,"description":"The title or name of the media, providing a brief description or identifier for the media file. This helps in organizing and identifying media files (e.g., \"Main Attraction Image,\" \"Promotional Video\"). This field can be null if no title is provided."},"caption":{"type":"string","nullable":true,"description":"A caption providing additional context or information about what is depicted in the media. Captions should be customer-facing and provide insights such as \"Overview of the city skyline at sunset\" or \"Guests enjoying the guided tour.\" This field can be null if no caption is provided."},"copyright":{"type":"string","nullable":true,"description":"Information about the copyright status or usage restrictions of the media. This may include details about ownership, licensing terms, or attribution requirements (e.g., \"© 2024 Example Corp, All Rights Reserved\"). If null, it is assumed there are no copyright restrictions or attribution requirements."}}},"MediaType":{"type":"string","enum":["image/jpeg","image/png","video/mp4","video/avi","external/youtube","external/vimeo"]},"MediaRel":{"type":"string","enum":["LOGO","COVER","GALLERY"]},"Location":{"type":"object","required":["title","shortDescription","types","minutesTo","minutesAt","place"],"properties":{"title":{"type":"string","nullable":true,"description":"The name of the location, providing a recognizable identifier for customers (e.g., \"Statue of Liberty\"). This field can be null if no name is available."},"shortDescription":{"type":"string","nullable":true,"description":"A brief description of the location, summarizing its significance or role in the product (e.g., \"Historic landmark and popular tourist destination\"). This field can be null if no description is provided."},"types":{"type":"array","items":{"$ref":"#/components/schemas/LocationType"},"description":"Specifies the roles or purposes of the location within the product. START: The starting point or meeting location for the product or experience. This is where customers are expected to gather before the activity begins.\nREDEMPTION: A location where customers must go to exchange tickets, collect passes, or redeem vouchers before proceeding to the starting point or experience (if applicable).\nITINERARY_ITEM: A designated stop or location within the itinerary, typically where customers pause or spend time during a moving tour or activity.\nPOINT_OF_INTEREST: A notable location or attraction that customers may see or pass by without stopping. Generally used for sightseeing locations.\nADMISSION_INCLUDED: A location where entry is included in the product price, often highlighting an attraction or event that customers can access as part of the experience.\nEND: The final point or drop-off location where the activity concludes."},"minutesTo":{"type":"integer","nullable":true,"description":"The travel time, in minutes, needed to reach this location from the previous one in the itinerary. Useful for building schedules or itineraries. Set to null if travel time is unknown, not relevant, or not required."},"minutesAt":{"type":"integer","nullable":true,"description":"The approximate duration, in minutes, spent at this location. Helps provide clarity on the itinerary or scheduling details. Set to null if the time spent is flexible, unknown, or not applicable."},"place":{"allOf":[{"$ref":"#/components/schemas/Place"}],"description":"An object containing detailed geospatial and postal address data for the location."}}},"LocationType":{"type":"string","enum":["START","ITINERARY_ITEM","POINT_OF_INTEREST","ADMISSION_INCLUDED","END","REDEMPTION"]},"Place":{"type":"object","required":["latitude","longitude","postalAddress","identifiers","sameAs"],"properties":{"latitude":{"type":"number","description":"The latitude of the location, expressed in decimal degrees. Negative values represent southern latitudes."},"longitude":{"type":"number","description":"The longitude of the location, expressed in decimal degrees. Negative values represent western longitudes."},"postalAddress":{"allOf":[{"$ref":"#/components/schemas/PostalAddress"}],"description":"Structured postal address details for the location."},"identifiers":{"allOf":[{"$ref":"#/components/schemas/Identifiers"}],"description":"A list of unique identifiers from third-party platforms (e.g., Google Maps, Yelp, Tripadvisor)."},"sameAs":{"type":"array","items":{"type":"string"},"description":"A list of URLs pointing to web pages or social media profiles for the location."}}},"PostalAddress":{"type":"object","required":["streetAddress","addressLocality","addressRegion","postalCode","addressCountry","postOfficeBoxNumber"],"properties":{"streetAddress":{"type":"string","nullable":true,"description":"The primary address line, such as a street address, P.O. box, or company name. Null if not provided."},"addressLocality":{"type":"string","nullable":true,"description":"The city or locality associated with the address."},"addressRegion":{"type":"string","nullable":true,"description":"The state, province, or region associated with the address."},"postalCode":{"type":"string","nullable":true,"description":"The postal code or ZIP code for the address."},"addressCountry":{"type":"string","nullable":true,"description":"The postal code or ZIP code for the address."},"postOfficeBoxNumber":{"type":"string","nullable":true,"description":"The post office box number associated with the address, if applicable."}}},"Identifiers":{"type":"object","required":["googlePlaceId","applePlaceId","tripadvisorLocationId","yelpPlaceId","facebookPlaceId","foursquarePlaceId","baiduPlaceId","amapPlaceId"],"properties":{"googlePlaceId":{"type":"string","nullable":true},"applePlaceId":{"type":"string","nullable":true},"tripadvisorLocationId":{"type":"string","nullable":true},"yelpPlaceId":{"type":"string","nullable":true},"facebookPlaceId":{"type":"string","nullable":true},"foursquarePlaceId":{"type":"string","nullable":true},"baiduPlaceId":{"type":"string","nullable":true},"amapPlaceId":{"type":"string","nullable":true}},"description":"Specifies the type or source of the identifier for the location. This field defines the platform or system where the identifier is valid, allowing for seamless integration with third-party systems or mapping platforms. Common examples include:\ngooglePlaceId: A unique identifier for locations on Google Maps.\napplePlaceId: A unique identifier for locations on Apple Maps.\ntripadvisorLocationId: A unique identifier for listings on TripAdvisor.\nyelpPlaceId: A unique identifier for locations on Yelp.\nfacebookPlaceId: A unique identifier for places on Facebook.\nfoursquarePlaceId: A unique identifier for venues on Foursquare.\nbaiduPlaceId: A unique identifier for locations on Baidu Maps.\namapPlaceId: A unique identifier for locations on Amap (China-based mapping platform)."},"CategoryLabel":{"type":"string","enum":["multi-day","city-cards","adults-only","animals","audio-guide","beaches","bike-tours","boat-tours","classes","day-trips","family-friendly","fast-track","food","guided-tours","history","hop-on-hop-off","literature","live-music","museums","nightlife","outdoors","private-tours","romantic","recurring-events","self-guided","small-group-tours","sports","theme-parks","walking-tours","wheelchair-accessible","accommodation-included","trip-difficulty-easy","trip-difficulty-medium","trip-difficulty-hard"]},"Commentary":{"type":"object","required":["format","language"],"properties":{"format":{"allOf":[{"$ref":"#/components/schemas/CommentaryFormat"}],"description":"Specifies the format in which commentary is provided. Possible values are:\nIN_PERSON: Live commentary delivered by a guide or host during the activity. Examples include a tour guide providing real-time explanations about historical landmarks or itinerary highlights.\nRECORDED_AUDIO: Pre-recorded audio commentary accessible during the activity. Delivered via headphones, mobile apps, or speaker systems, covering key details in multiple languages.\nWRITTEN: Commentary provided as written material, such as printed brochures, guidebooks, or on-site informational displays at points of interest.\nOTHER: Commentary formats not explicitly listed, such as augmented reality experiences or interactive digital guides."},"language":{"type":"string","description":"Specifies the language in which the commentary is offered, adhering to IETF BCP 47 language tags for compatibility."}}},"CommentaryFormat":{"type":"string","enum":["IN_PERSON","RECORDED_AUDIO","WRITTEN","OTHER"]},"PricingPer":{"type":"string","enum":["BOOKING","UNIT"]},"ErrorInvalidProductID":{"type":"object","required":["productId"],"properties":{"productId":{"type":"string","description":"Missing or invalid `productId` in the request"}},"allOf":[{"$ref":"#/components/schemas/BaseError"}]},"BaseError":{"type":"object","required":["error","errorMessage"],"properties":{"error":{"type":"string","description":"The error code. A table of possible error codes is shown below."},"errorMessage":{"type":"string","description":"A human-readable error message will be translated depending on the language provided by the Accept-Language header."}}},"ErrorUnauthorized":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]},"ErrorInternalServerError":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]},"ErrorForbidden":{"type":"object","allOf":[{"$ref":"#/components/schemas/BaseError"}]}}},"paths":{"/products/{id}":{"get":{"operationId":"Products_GetProduct","summary":"Get Product","description":"Fetch the product for the given id.","parameters":[{"$ref":"#/components/parameters/GetProductRequest.id"},{"$ref":"#/components/parameters/RequestHeaders.octoCapabilities"},{"$ref":"#/components/parameters/RequestHeadersContent"}],"responses":{"200":{"description":"The request has succeeded.","headers":{"Octo-Capabilities":{"required":true,"description":"A list of the Capabilities (their IDs) initialized with your request.","schema":{"type":"string"}},"Content-Language":{"required":false,"description":"This response header indicates the language of the content being returned in the response. The OCTO specification allows only one language to be returned per response. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain).  To obtain content in multiple languages, separate requests must be made for each desired language. This header is defined in the HTTP/1.1 specification (RFC 7231). For more information, see MDN Web Docs: Content-Language - HTTP | MDN. This response header is required when using Content capability.","schema":{"type":"string"}},"Available-Languages":{"required":false,"description":"This response header is used to inform of the languages in which content is available, helping understand the language options without needing additional requests. This code must conform to the BCP 47 standard, following RFC 5646 and RFC 4647 specifications for language tags. Examples include en-US for American English, fr-FR for French (France), and es-ES for Spanish (Spain).  Although not a standard HTTP header, it is commonly used in APIs to list available languages, such as en-US, fr-CA, es-ES, indicating that content can be requested in U.S. English, Canadian French, or Spanish. This response header is required when using Content capability.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The server could not understand the request due to invalid syntax.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorInvalidProductID"},{"$ref":"#/components/schemas/ErrorUnauthorized"},{"$ref":"#/components/schemas/ErrorInternalServerError"},{"$ref":"#/components/schemas/ErrorForbidden"}]}}}}},"tags":["Products"]}}}}
```
