openapi: 3.1.0 info: title: Open Connectivity for Tours, Activities, and Attractions OCTO API Specification Availability Products API version: '1.0' contact: email: sayhello@octo.travel url: https://www.octo.travel/contact name: OCTO Standards NP Inc description: "OCTO (Open Connectivity for Tours, Activities, and Attractions) is an open standard API specification for the in-destination experiences sector of the travel industry. The standard defines agreed-upon schemas, endpoints, and capabilities commonly needed when connecting platforms, resellers, OTAs, and other technologies in tours, activities, and attractions. \n\nOCTO is open source. Available to anyone who wants to use it. You do not need to be a member to use this specification in your business." servers: - url: https://api.example.com/octo tags: - name: Products externalDocs: description: Docs url: https://docs.octo.travel/octo-core/products paths: /products: get: summary: Open Connectivity for Tours, Activities, and Attractions Get Products tags: - Products responses: '200': description: OK content: application/json: schema: type: array items: type: object x-examples: example-1: id: 28ca088b-bc7b-4746-ab06-5971f1ed5a5e internalName: Edinburgh Hop-On Hop-Off Bus Tour reference: null locale: en timeZone: Europe/London allowFreesale: true instantConfirmation: true instantDelivery: true availabilityRequired: false examples: - id: 6b903d44-dc24-4ca4-ae71-6bde6c4f4854 internalName: Amazon River Tour reference: AMZN locale: en-GB timeZone: Europe/London allowFreesale: true instantConfirmation: true instantDelivery: true availabilityRequired: true availabilityType: START_TIME deliveryFormats: - QRCODE deliveryMethods: - VOUCHER redemptionMethod: DIGITAL options: - id: DEFAULT default: true internalName: Private Morning Tour reference: VIP-MORN availabilityLocalStartTimes: - 09:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: - firstName restrictions: minUnits: 'null' maxUnits: 10 units: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 description: A bookable product listed by a supplier. properties: id: type: string example: 6b903d44-dc24-4ca4-ae71-6bde6c4f4854 description: The id used for checking for availability and creating bookings for the product. This MUST be unique within the scope of the Supplier. internalName: type: string description: The name the supplier calls the product. example: Amazon River Tour reference: type: - 'null' - string description: An optional code this supplier might use to identify the product. example: AMZN locale: type: string example: en-GB description: A language code indicating what language this product content is in. This MUST be a valid BCP 47 RFC 5646 RFC 4647 language tag. timeZone: type: string example: Europe/London description: The IANA TimeZone name this product is located in. allowFreesale: type: boolean description: Whether a booking can be made for this product without having to query availability first. instantConfirmation: type: boolean description: Whether bookings will be immediately confirmed when a sale is made, otherwise the supplier will later either accept or reject the booking. When `instantConfirmation` is set to false one should expect created bookings to first get into a `PENDING` state. 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: Whether an `availabilityId` is required when creating a booking. Without this the booking will be open-dated and not have a specified travel date. availabilityType: type: string title: AvailabilityType x-stoplight: id: n70vwjh7kvmxk enum: - START_TIME - OPENING_HOURS description: 'What type of availability this product has, possible values are: `START_TIME` if there are fixed departure times which you must pick one. Typical for day tours or activities. `OPENING_HOURS` if you just select a date and can visit any time when the venue is open.' example: START_TIME examples: - START_TIME deliveryFormats: type: array description: 'An array of formats the API will deliver the tickets as. Possible values are: `QRCODE` A code to be presented as a QR CODE barcode `CODE128A` code to be presented as a CODE 128 barcode `PDF_URL` A URL to a PDF file which contains all the ticket details' items: type: string title: DeliveryFormat x-stoplight: id: xo5qi6jemvvhc enum: - PDF_URL - QRCODE description: 'The format for the delivery option possible values are: `QRCODE` You should generate the QR Code yourself on a ticket. `PDF_URL` Where you use the generated tickets as a PDF.' example: QRCODE examples: - QRCODE deliveryMethods: type: array description: 'How the formats described in `deliveryFormats` will be delivered in the booking response, possible values are: `TICKET`: Individually per unit in the order (i.e. single ticket for each person) `VOUCHER`: One ticket for the whole booking' items: type: string title: DeliveryMethod x-stoplight: id: tdh9akr9neqhb enum: - VOUCHER - TICKET description: 'An array of delivery methods available for this booking. Possible values are: `VOUCHER` The voucher object is populated which is a single ticket for the whole booking. `TICKET` The ticket object is populated on each unit item which is a ticket for each individual person. If `booking.deliveryMethods` contains both `TICKET` and `VOUCHER` then both those values will be set.' examples: - VOUCHER redemptionMethod: type: string title: RedemptionMethod x-stoplight: id: jrrh8rbyzfuzm enum: - DIGITAL - PRINT - MANIFEST description: 'How the voucher can be redeemed. Possible values are: `MANIFEST` The guest name will be written down and they just need to show up `DIGITAL` The tickets/voucher must be scanned but can be on mobile `PRINT` The tickets/voucher must be printed and presented on arrival' examples: - DIGITAL options: type: array description: An array of all options for this product. All products must have at least one option. items: type: object x-examples: example-1: id: DEFAULT default: true internalName: DEFAULT reference: null availabilityLocalStartTimes: - 00:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: [] examples: - id: DEFAULT default: true internalName: Private Morning Tour reference: VIP-MORN availabilityLocalStartTimes: - 09:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: - firstName restrictions: minUnits: 'null' maxUnits: 10 units: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 description: Product options are subdivisions of the original product that will affect price and / or duration. Within the OCTo spec, every product must contain an option. properties: id: type: string example: DEFAULT description: The id that identifies this option, it is only unique within the product. default: type: boolean description: '`TRUE` identifies the option as default, and should therefore rendered and selected first' internalName: type: string description: The name the supplier calls the option by. example: Private Morning Tour reference: type: - 'null' - string description: An optional code this supplier might use to identify the product. example: VIP-MORN availabilityLocalStartTimes: type: array description: This will be an array of all possible start times that can be returned during availability. For example an all day attraction may have a single value like `["00:00"]` whilst a tour with multiple departure times may have multiple:`["09:00", "14:00", "17:00"]`. items: type: string default: 00:00 example: 09:00 cancellationCutoff: type: string example: 1 hour description: This is how long before the tour the booking can be still be cancelled. cancellationCutoffAmount: type: integer example: 1 description: The numeric amount for the cutoff. cancellationCutoffUnit: type: string title: DurationUnit x-stoplight: id: etuhjhtharyrt enum: - hour - minute - day example: hour description: 'Time units used to determine duration. Three values are available: `hour`, `minute`, `day`.' examples: - hour requiredContactFields: type: array description: An array of the contact fields required to confirm a booking. These just apply to the lead traveller on the booking and not for every ticket. items: type: string title: ContactField x-stoplight: id: 5qud985l1i6ih enum: - firstName - lastName - emailAddress - phoneNumber - country - notes - locales examples: - firstName description: '' restrictions: type: object x-examples: example-1: minUnits: 0 maxUnits: 9 description: An object containing a fixed list of restrictions for booking the option. examples: - minUnits: null maxUnits: 10 properties: minUnits: type: - integer - 'null' example: 0 description: The minimum number of tickets that can be purchased in a single booking (null = 0). maxUnits: type: - integer - 'null' example: 10 description: The maximum number of tickets that can be purchased in a single booking (null = unlimited). required: - minUnits - maxUnits units: type: array description: The list of ticket types (units) available for sale. items: type: object x-examples: example-1: id: unit_c1709f42-297e-4f7e-bd6b-3e77d4622d8a internalName: Adult reference: null type: ADULT requiredContactFields: [] examples: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 properties: id: type: string description: This MUST be a unique identifier within the scope of the option. example: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: type: string example: Adult(s) description: This should be a name to help with identifying the unit. It should NOT be shown to the customer. reference: type: - 'null' - string description: This is an internal reference identifier that the Supplier wishes to use. It MAY be non-unique. example: LR1-01-new type: type: string title: UnitType x-stoplight: id: 9womjjbg9rhr7 enum: - ADULT - YOUTH - CHILD - INFANT - FAMILY - SENIOR - STUDENT - MILITARY - OTHER examples: - ADULT 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`, or `SENIOR`. example: YOUTH requiredContactFields: type: array description: This is the array of the contact information PER ticket that the supplier expects. items: type: string title: ContactField x-stoplight: id: 5qud985l1i6ih enum: - firstName - lastName - emailAddress - phoneNumber - country - notes - locales examples: - firstName description: '' restrictions: type: object x-examples: example-1: minAge: 0 maxAge: 100 idRequired: false minQuantity: 1 maxQuantity: null paxCount: 4 accompaniedBy: [] description: unit restrictions examples: - minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 title: UnitRestrictions properties: minAge: type: integer example: 3 description: This is the minumum age this unit can be sold to maxAge: type: integer example: 17 description: This is the maximum age this unit can be sold to idRequired: type: boolean description: This is whether a form of identification will be required at redemption point (eg. student card) minQuantity: type: - integer - 'null' example: 2 description: This is if there is a minimum amount of units to be chosen for purchase (eg. 2) maxQuantity: type: - 'null' - integer example: 7 description: This is if there is a maximum amount of units to be chosen for purchase (eg. 7) paxCount: type: integer description: This is the amount of people each unit counts as (eg. family == 4pax) example: 1 accompaniedBy: type: array description: This is if the unit needs to be accompanied by another unit (eg. Infant with Adult) items: type: string example: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 required: - minAge - maxAge - idRequired - minQuantity - maxQuantity - paxCount - accompaniedBy required: - id - internalName - type - requiredContactFields - restrictions description: '' required: - id - default - internalName - reference - availabilityLocalStartTimes - cancellationCutoff - cancellationCutoffAmount - cancellationCutoffUnit - requiredContactFields - restrictions - units required: - id - internalName - reference - locale - allowFreesale - instantConfirmation - instantDelivery - availabilityRequired - availabilityType - deliveryFormats - deliveryMethods - redemptionMethod - options description: Fetch the list of products. /products/{id}: get: summary: Open Connectivity for Tours, Activities, and Attractions Get Product tags: - Products parameters: - schema: type: string name: id in: path required: true description: The product id responses: '200': description: OK content: application/json: schema: type: object x-examples: example-1: id: 28ca088b-bc7b-4746-ab06-5971f1ed5a5e internalName: Edinburgh Hop-On Hop-Off Bus Tour reference: null locale: en timeZone: Europe/London allowFreesale: true instantConfirmation: true instantDelivery: true availabilityRequired: false examples: - id: 6b903d44-dc24-4ca4-ae71-6bde6c4f4854 internalName: Amazon River Tour reference: AMZN locale: en-GB timeZone: Europe/London allowFreesale: true instantConfirmation: true instantDelivery: true availabilityRequired: true availabilityType: START_TIME deliveryFormats: - QRCODE deliveryMethods: - VOUCHER redemptionMethod: DIGITAL options: - id: DEFAULT default: true internalName: Private Morning Tour reference: VIP-MORN availabilityLocalStartTimes: - 09:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: - firstName restrictions: minUnits: 'null' maxUnits: 10 units: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 description: A bookable product listed by a supplier. properties: id: type: string example: 6b903d44-dc24-4ca4-ae71-6bde6c4f4854 description: The id used for checking for availability and creating bookings for the product. This MUST be unique within the scope of the Supplier. internalName: type: string description: The name the supplier calls the product. example: Amazon River Tour reference: type: - 'null' - string description: An optional code this supplier might use to identify the product. example: AMZN locale: type: string example: en-GB description: A language code indicating what language this product content is in. This MUST be a valid BCP 47 RFC 5646 RFC 4647 language tag. timeZone: type: string example: Europe/London description: The IANA TimeZone name this product is located in. allowFreesale: type: boolean description: Whether a booking can be made for this product without having to query availability first. instantConfirmation: type: boolean description: Whether bookings will be immediately confirmed when a sale is made, otherwise the supplier will later either accept or reject the booking. When `instantConfirmation` is set to false one should expect created bookings to first get into a `PENDING` state. 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: Whether an `availabilityId` is required when creating a booking. Without this the booking will be open-dated and not have a specified travel date. availabilityType: type: string title: AvailabilityType x-stoplight: id: n70vwjh7kvmxk enum: - START_TIME - OPENING_HOURS description: 'What type of availability this product has, possible values are: `START_TIME` if there are fixed departure times which you must pick one. Typical for day tours or activities. `OPENING_HOURS` if you just select a date and can visit any time when the venue is open.' example: START_TIME examples: - START_TIME deliveryFormats: type: array description: 'An array of formats the API will deliver the tickets as. Possible values are: `QRCODE` A code to be presented as a QR CODE barcode `CODE128A` code to be presented as a CODE 128 barcode `PDF_URL` A URL to a PDF file which contains all the ticket details' items: type: string title: DeliveryFormat x-stoplight: id: xo5qi6jemvvhc enum: - PDF_URL - QRCODE description: 'The format for the delivery option possible values are: `QRCODE` You should generate the QR Code yourself on a ticket. `PDF_URL` Where you use the generated tickets as a PDF.' example: QRCODE examples: - QRCODE deliveryMethods: type: array description: 'How the formats described in `deliveryFormats` will be delivered in the booking response, possible values are: `TICKET`: Individually per unit in the order (i.e. single ticket for each person) `VOUCHER`: One ticket for the whole booking' items: type: string title: DeliveryMethod x-stoplight: id: tdh9akr9neqhb enum: - VOUCHER - TICKET description: 'An array of delivery methods available for this booking. Possible values are: `VOUCHER` The voucher object is populated which is a single ticket for the whole booking. `TICKET` The ticket object is populated on each unit item which is a ticket for each individual person. If `booking.deliveryMethods` contains both `TICKET` and `VOUCHER` then both those values will be set.' examples: - VOUCHER redemptionMethod: type: string title: RedemptionMethod x-stoplight: id: jrrh8rbyzfuzm enum: - DIGITAL - PRINT - MANIFEST description: 'How the voucher can be redeemed. Possible values are: `MANIFEST` The guest name will be written down and they just need to show up `DIGITAL` The tickets/voucher must be scanned but can be on mobile `PRINT` The tickets/voucher must be printed and presented on arrival' examples: - DIGITAL options: type: array description: An array of all options for this product. All products must have at least one option. items: type: object x-examples: example-1: id: DEFAULT default: true internalName: DEFAULT reference: null availabilityLocalStartTimes: - 00:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: [] examples: - id: DEFAULT default: true internalName: Private Morning Tour reference: VIP-MORN availabilityLocalStartTimes: - 09:00 cancellationCutoff: 1 hour cancellationCutoffAmount: 1 cancellationCutoffUnit: hour requiredContactFields: - firstName restrictions: minUnits: 'null' maxUnits: 10 units: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 description: Product options are subdivisions of the original product that will affect price and / or duration. Within the OCTo spec, every product must contain an option. properties: id: type: string example: DEFAULT description: The id that identifies this option, it is only unique within the product. default: type: boolean description: '`TRUE` identifies the option as default, and should therefore rendered and selected first' internalName: type: string description: The name the supplier calls the option by. example: Private Morning Tour reference: type: - 'null' - string description: An optional code this supplier might use to identify the product. example: VIP-MORN availabilityLocalStartTimes: type: array description: This will be an array of all possible start times that can be returned during availability. For example an all day attraction may have a single value like `["00:00"]` whilst a tour with multiple departure times may have multiple:`["09:00", "14:00", "17:00"]`. items: type: string default: 00:00 example: 09:00 cancellationCutoff: type: string example: 1 hour description: This is how long before the tour the booking can be still be cancelled. cancellationCutoffAmount: type: integer example: 1 description: The numeric amount for the cutoff. cancellationCutoffUnit: type: string title: DurationUnit x-stoplight: id: etuhjhtharyrt enum: - hour - minute - day example: hour description: 'Time units used to determine duration. Three values are available: `hour`, `minute`, `day`.' examples: - hour requiredContactFields: type: array description: An array of the contact fields required to confirm a booking. These just apply to the lead traveller on the booking and not for every ticket. items: type: string title: ContactField x-stoplight: id: 5qud985l1i6ih enum: - firstName - lastName - emailAddress - phoneNumber - country - notes - locales examples: - firstName description: '' restrictions: type: object x-examples: example-1: minUnits: 0 maxUnits: 9 description: An object containing a fixed list of restrictions for booking the option. examples: - minUnits: null maxUnits: 10 properties: minUnits: type: - integer - 'null' example: 0 description: The minimum number of tickets that can be purchased in a single booking (null = 0). maxUnits: type: - integer - 'null' example: 10 description: The maximum number of tickets that can be purchased in a single booking (null = unlimited). required: - minUnits - maxUnits units: type: array description: The list of ticket types (units) available for sale. items: type: object x-examples: example-1: id: unit_c1709f42-297e-4f7e-bd6b-3e77d4622d8a internalName: Adult reference: null type: ADULT requiredContactFields: [] examples: - id: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: Adult(s) reference: LR1-01-new type: YOUTH requiredContactFields: - firstName restrictions: minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 properties: id: type: string description: This MUST be a unique identifier within the scope of the option. example: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 internalName: type: string example: Adult(s) description: This should be a name to help with identifying the unit. It should NOT be shown to the customer. reference: type: - 'null' - string description: This is an internal reference identifier that the Supplier wishes to use. It MAY be non-unique. example: LR1-01-new type: type: string title: UnitType x-stoplight: id: 9womjjbg9rhr7 enum: - ADULT - YOUTH - CHILD - INFANT - FAMILY - SENIOR - STUDENT - MILITARY - OTHER examples: - ADULT 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`, or `SENIOR`. example: YOUTH requiredContactFields: type: array description: This is the array of the contact information PER ticket that the supplier expects. items: type: string title: ContactField x-stoplight: id: 5qud985l1i6ih enum: - firstName - lastName - emailAddress - phoneNumber - country - notes - locales examples: - firstName description: '' restrictions: type: object x-examples: example-1: minAge: 0 maxAge: 100 idRequired: false minQuantity: 1 maxQuantity: null paxCount: 4 accompaniedBy: [] description: unit restrictions examples: - minAge: 3 maxAge: 17 idRequired: true minQuantity: 2 maxQuantity: 7 paxCount: 1 accompaniedBy: - adult_697e3ce8-1860-4cbf-80ad-95857df1f640 title: UnitRestrictions properties: minAge: type: integer example: 3 description: This is the minumum age this unit can be sold to maxAge: type: integer example: 17 description: This is the maximum age this unit can be sold to idRequired: type: boolean description: This is whether a form of identification will be required at redemption point (eg. student card) minQuantity: type: - integer - 'null' example: 2 description: This is if there is a minimum amount of units to be chosen for purchase (eg. 2) maxQuantity: type: - 'null' - integer example: 7 description: This is if there is a maximum amount of units to be chosen for purchase (eg. 7) paxCount: type: integer description: This is the amount of people each unit counts as (eg. family == 4pax) example: 1 accompaniedBy: type: array description: This is if the unit needs to be accompanied by another unit (eg. Infant with Adult) items: type: string example: adult_697e3ce8-1860-4cbf-80ad-95857df1f640 required: - minAge - maxAge - idRequired - minQuantity - maxQuantity - paxCount - accompaniedBy required: - id - internalName - type - requiredContactFields - restrictions description: '' required: - id - default - internalName - reference - availabilityLocalStartTimes - cancellationCutoff - cancellationCutoffAmount - cancellationCutoffUnit - requiredContactFields - restrictions - units required: - id - internalName - reference - locale - allowFreesale - instantConfirmation - instantDelivery - availabilityRequired - availabilityType - deliveryFormats - deliveryMethods - redemptionMethod - options description: Fetch the product for the given id. components: securitySchemes: Auth: type: http scheme: bearer externalDocs: url: https://docs.octo.travel/ description: OCTO Developer Hub