Skip to content

Instantly share code, notes, and snippets.

@davidteren
Last active September 26, 2024 18:49
Show Gist options
  • Save davidteren/3abdd2c5d996764b13fb40134bc26406 to your computer and use it in GitHub Desktop.
Save davidteren/3abdd2c5d996764b13fb40134bc26406 to your computer and use it in GitHub Desktop.
Musement's supplier PORTA (1.0.0) OpenAPI specification

// file: porta-site-docs/API Reference/API reference.md

created: 2024-08-06T01:11:34 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

API reference

Excerpt

Documentation for managing your catalog on Musement via the PORTA API.


PORTA (1.0.0)

Download OpenAPI specification:Download

About PORTA

Musement's PORTA (Perfect Open Road To Activities) service allows suppliers to manage their experiences via API.

Authentication

Supplier-production

This is the default security scheme a supplier must use when accessing PORTA in the production environment.

Security Scheme Type: OAuth2

Flow type: clientCredentials

Token URL: https://prod.api.tui/oauth2/token

Supplier-sandbox

This is the default security scheme a supplier must use when accessing PORTA in the sandbox environment.

Security Scheme Type: OAuth2

Flow type: clientCredentials

Token URL: https://prod.api.tui/oauth2/token

Webhook

This security scheme is used by PORTA when calling a supplier's webhook service.

Security Scheme Type: API Key

Header parameter name: x-webhook-key

Release notes

This section contains a record of changes to the API.

2023-12-06

  • Added unconfirmed property to booking cancellation request webhook

2023-10-12

  • Added vendor_id query parameter to the endpoint GET /supplier/catalog/experiences
    • Filters results to those which belong to the specified vendor

2023-10-02

  • Added ticket_numbers and transaction_id properties to booking cancellation request webhook

2023-08-24

  • Changed accept-version header value used for webhook requests
    • New value is vnd.porta-webhook-api.v1

2023-06-22

  • Added webhook test endpoints for sandbox environment:
    • POST /supplier/integration-tests/book
    • POST /supplier/integration-tests/cancel-booking
    • POST /supplier/integration-tests/hold

2023-06-09

  • Added endpoint PATCH /supplier/catalog/experiences/{experience_id}
  • Added archived property to Experience model
    • Archived experiences are no longer for sale

2023-05-04

  • Removed supplier-code header parameter from all endpoints
  • Removed exhaust vent that exposed the Core

2023-04-20

Booking confirmation request

  • Added tuimm_booking_id property
    • Human-friendly Musement booking ID

Vendors

  • Added Vendor model
    • Used to categorize experiences by different sources, partners or channels
  • Added two endpoints:
    • GET /supplier/vendors
    • POST /supplier/vendors
  • Added vendor_id property to Experience model

2023-03-23

Experience model

  • Removed content and media properties

// file: porta-site-docs/API Reference/Availability slots.md

created: 2024-08-06T01:12:28 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Availability slots

Excerpt

Availability slots is the term for any type of slot used for a booking. This collection of endpoints will work for any type of slot


Availability slots is the term for any type of slot used for a booking. This collection of endpoints will work for any type of slot

Remove availability slots from option

An availability slot cannot be deleted if it is part of a hold availability request.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

API-Key

required

string (API key) ^[a-zA-Z0-9-_\.]{3,50}$

The supplier's API key

204

Availability slots removed successfully from option

delete/supplier/availability/experiences/{experience_id}/options/{option_id}/slots

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> DELETE <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots'</span> <span>\</span>
  <span>-H</span> <span>'API-Key: string'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • default

400 Bad request: check the request for errors

{

  • "code": "400",

  • "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",

  • "message": "Check the request for errors."

}

Create availability slots for experience

The maximum number of items in the request body varies based on the type of availability slot:

  • Daily slot: 100
  • Open slot: 1
  • Time slot: 100

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

API-Key

required

string (API key) ^[a-zA-Z0-9-_\.]{3,50}$

The supplier's API key

Request Body schema: application/json

Array

capacity

integer <int32>

The remaining number of seats for the slot.

required

object (Daily slot)

required

Array of objects (Holder categories) unique

Holder categories for the slot.

guide_languages

Array of strings (Languages) unique

A list of languages which can be booked for the slot. The languages will appear for all available holder categories in the slot.

This property must follow the ISO 639-1 standard.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of the option that the slot belongs to.

slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID, assigned by the supplier.

The ID must be unique. The same ID cannot be re-used for different experiences.

post/supplier/availability/experiences/{experience_id}/options/{option_id}/slots

  • Payload
  • curl
  • C#
  • Node.js

[

  • {

    • "capacity": 0,

    • "daily_slot": {},

    • "available_holder_categories": [],

    • "guide_languages": [],

    • "option_id": "string",

    • "slot_id": "string"

    }

]

  • 200
  • default

{

  • "capacity": 0,

  • "daily_slot": {

    • "date": "2019-08-24"

    },

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string"

}

Remove availability slot from option

An availability slot cannot be deleted if it is part of a hold availability request.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

availability_slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

204

Availability slot removed successfully from option

delete/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> DELETE <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • default

400 Bad request: check the request for errors

{

  • "code": "400",

  • "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",

  • "message": "Check the request for errors."

}

Get availability slot for option

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

availability_slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

{

  • "capacity": 0,

  • "daily_slot": {

    • "date": "2019-08-24"

    },

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string"

}

Update capacity for availability slot

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

availability_slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
capacity

integer <int32>

The remaining number of seats for the slot.

patch/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}

  • Payload

  • curl

  • C#

  • Node.js

  • 200

  • default

{

  • "capacity": 0,

  • "daily_slot": {

    • "date": "2019-08-24"

    },

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string"

}

Update availability slot for option

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

availability_slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
capacity

integer <int32>

The remaining number of seats for the slot.

required

object (Daily slot)

required

Array of objects (Holder categories) unique

Holder categories for the slot.

guide_languages

Array of strings (Languages) unique

A list of languages which can be booked for the slot. The languages will appear for all available holder categories in the slot.

This property must follow the ISO 639-1 standard.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of the option that the slot belongs to.

slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID, assigned by the supplier.

The ID must be unique. The same ID cannot be re-used for different experiences.

put/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/{availability_slot_id}

  • Payload
  • curl
  • C#
  • Node.js

{

  • "capacity": 0,

  • "daily_slot": {

    • "date": "2019-08-24"

    },

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string"

}

  • 200
  • default

{

  • "capacity": 0,

  • "daily_slot": {

    • "date": "2019-08-24"

    },

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string"

}

// file: porta-site-docs/API Reference/Daily slots.md

created: 2024-08-06T01:12:42 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Daily slots

Excerpt

Customers must select a date for a booking.


Customers must select a date for a booking.

Get daily slots for option

The date_from and date_to query parameters permit up to two years of dates.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

query Parameters
date_from

required

string <date>

Filters results to those which take place on or after the specified date.

date_to

required

string <date>

Filters results to those which take place on or before the specified date.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

200

Daily slots for option

get/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/daily_slots

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/daily_slots?date_from=2019-08-24&amp;date_to=2019-08-24'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "available_holder_categories": [],

    • "guide_languages": [],

    • "option_id": "string",

    • "slot_id": "string",

    • "capacity": 0,

    • "daily_slot": {}

    }

]

// file: porta-site-docs/API Reference/Experiences.md

created: 2024-08-06T01:11:49 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Experiences

Excerpt

Experiences are the products that the supplier provides. PORTA experiences can eventually be imported into Musement.


Experiences are the products that the supplier provides. PORTA experiences can eventually be imported into Musement.

Get experiences

SecuritySupplier-production or Supplier-sandbox

query Parameters
vendor_id

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

Filter results to those which belong to the specified vendor.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/catalog/experiences

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences?vendor_id=string'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "archived": false,

    • "availability_slot_type": "DAILY",

    • "currency": "string",

    • "cutoff_time": "P0D",

    • "experience_id": "string",

    • "experience_name": "string",

    • "external_experience_id": "string",

    • "external_experience_name": "string",

    • "options": [],

    • "vendor_id": "string"

    }

]

Create experience

SecuritySupplier-production or Supplier-sandbox

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
archived

boolean

Default: false

When an experience is archived, it is no longer for sale in Musement sites.

When an experience is un-archived, a member of the Content Supplier Connectivity team is required to un-archive the corresponding business platform activity.

availability_slot_type

required

string

The type of availability slot for the experience.

Enum:Description
DAILY

Customers must select a date for their booking. They do not select a time.

OPEN

Customers do not select a date or time. Their booking expires on a set date or a set number of days after purchase.

TIME

Customers must select a date and time for their booking.

currency

required

string <currency>

The currency to use for billing.

This property must follow the ISO 4217 standard.

cutoff_time

string <duration>

Default: "P0D"

The minimum amount of time required to book a travel date in advance.

This property must follow the ISO 8601 standard.

experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The experience ID, assigned by the supplier.

experience_name

required

string

The name of the experience as it will appear in PORTA.

external_experience_id

string

An additional ID for the experience which suppliers can use for their own records.

external_experience_name

string

An additional name for the experience which suppliers can use for their own records.

required

Array of objects (Options) unique

The bookable options for the experience. This property must contain at least one option.

vendor_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of the vendor that the experience belongs to.

post/supplier/catalog/experiences

  • Payload
  • curl
  • C#
  • Node.js

{

  • "archived": false,

  • "availability_slot_type": "DAILY",

  • "currency": "string",

  • "cutoff_time": "P0D",

  • "experience_id": "string",

  • "experience_name": "string",

  • "external_experience_id": "string",

  • "external_experience_name": "string",

  • "options": [

    • {}

    ],

  • "vendor_id": "string"

}

  • 200
  • default

{

  • "archived": false,

  • "availability_slot_type": "DAILY",

  • "currency": "string",

  • "cutoff_time": "P0D",

  • "experience_id": "string",

  • "experience_name": "string",

  • "external_experience_id": "string",

  • "external_experience_name": "string",

  • "options": [

    • {}

    ],

  • "vendor_id": "string"

}

Get experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/catalog/experiences/{experience_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences/{experience_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

{

  • "archived": false,

  • "availability_slot_type": "DAILY",

  • "currency": "string",

  • "cutoff_time": "P0D",

  • "experience_id": "string",

  • "experience_name": "string",

  • "external_experience_id": "string",

  • "external_experience_name": "string",

  • "options": [

    • {}

    ],

  • "vendor_id": "string"

}

Update experience

Updating an experience is limited to a small selection of properties.

Changes may take up to 24 hours to appear in the business platform and distribution sites.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
archived

boolean

Default: false

When an experience is archived, it is no longer for sale in Musement sites.

When an experience is un-archived, a member of the Content Supplier Connectivity team is required to un-archive the corresponding business platform activity.

cutoff_time

string <duration>

Default: "P0D"

The minimum amount of time required to book a travel date in advance.

This property must follow the ISO 8601 standard.

experience_name

string

The name of the experience as it will appear in PORTA.

external_experience_id

string

An additional ID for the experience which suppliers can use for their own records.

external_experience_name

string

An additional name for the experience which suppliers can use for their own records.

vendor_id

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of the vendor that the experience belongs to.

patch/supplier/catalog/experiences/{experience_id}

  • Payload
  • curl
  • C#
  • Node.js

{

  • "archived": false,

  • "cutoff_time": "P0D",

  • "experience_name": "string",

  • "external_experience_id": "string",

  • "external_experience_name": "string",

  • "vendor_id": "string"

}

  • 200
  • default

{

  • "archived": false,

  • "availability_slot_type": "DAILY",

  • "currency": "string",

  • "cutoff_time": "P0D",

  • "experience_id": "string",

  • "experience_name": "string",

  • "external_experience_id": "string",

  • "external_experience_name": "string",

  • "options": [

    • {}

    ],

  • "vendor_id": "string"

}

// file: porta-site-docs/API Reference/Mandatory questions.md

created: 2024-08-06T01:11:58 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Mandatory questions

Excerpt

Mandatory questions allow suppliers to request customer information. Experiences are not required to have mandatory questions. However, when mandatory questions are present, customers must provide answers to complete a booking.


Mandatory questions allow suppliers to request customer information. Experiences are not required to have mandatory questions. However, when mandatory questions are present, customers must provide answers to complete a booking.

Get mandatory questions for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

200

Mandatory questions for experience

get/supplier/catalog/experiences/{experience_id}/mandatory-questions

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences/{experience_id}/mandatory-questions'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "data_pattern": "string",

    • "data_type": "DATE",

    • "holder_category_id": null,

    • "level": "BOOKING",

    • "mandatory_question_id": "string",

    • "option_id": null,

    • "question": "string",

    • "select": {}

    }

]

Create mandatory question for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
data_pattern

string

For unsupported data types, suppliers can provide a regular expression validation pattern. The data_type property must be STRING to use this feature.

data_type

required

string

The type of data the question will collect.

Enum:Description
DATE

Customers must select a single date.

DECIMAL

Customers must provide a decimal number value.

EMAIL

Customers must provide a valid email address.

INTEGER

Customers must provide an integer value.

PHONE_NUMBER

Customers must provide a phone number.

SELECT_ONE

Customers must select one value.

STRING

Customers must provide a text value.

holder_category_id

null or string

The holder category associated with the question. When null, the question is applied to all holder categories.

level

required

string

The level determines how to request the question: once per booking or once per person in a booking.

Enum:Description
BOOKING

The question must be answered once per booking.

BY_PAX

The question must be answered once per person in a booking.

mandatory_question_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The mandatory question ID, assigned by the supplier.

option_id

null or string

The option associated with the question. When null, the question is applied to all options.

question

required

string

The human-friendly question to show customers.

object

When the data_type property is SELECT_ONE, use the select property to provide options for customers to select. The property value must be a key-value object of strings.

200

Mandatory question for experience

post/supplier/catalog/experiences/{experience_id}/mandatory-questions

  • Payload
  • curl
  • C#
  • Node.js

{

  • "data_pattern": "string",

  • "data_type": "DATE",

  • "holder_category_id": null,

  • "level": "BOOKING",

  • "mandatory_question_id": "string",

  • "option_id": null,

  • "question": "string",

  • "select": {

    • "Raw key value1": "string",

    • "Raw key value2": "string"

    }

}

  • 200
  • default

{

  • "data_pattern": "string",

  • "data_type": "DATE",

  • "holder_category_id": null,

  • "level": "BOOKING",

  • "mandatory_question_id": "string",

  • "option_id": null,

  • "question": "string",

  • "select": {

    • "Raw key value1": "string",

    • "Raw key value2": "string"

    }

}

Remove mandatory question from experience

A mandatory question cannot be removed if it is part of a hold availability request.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

mandatory_question_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The mandatory question ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

204

Mandatory question removed successfully

delete/supplier/catalog/experiences/{experience_id}/mandatory-questions/{mandatory_question_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> DELETE <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences/{experience_id}/mandatory-questions/{mandatory_question_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • default

400 Bad request: check the request for errors

{

  • "code": "400",

  • "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",

  • "message": "Check the request for errors."

}

Get mandatory question for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

mandatory_question_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The mandatory question ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

200

Mandatory question for experience

get/supplier/catalog/experiences/{experience_id}/mandatory-questions/{mandatory_question_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences/{experience_id}/mandatory-questions/{mandatory_question_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

{

  • "data_pattern": "string",

  • "data_type": "DATE",

  • "holder_category_id": null,

  • "level": "BOOKING",

  • "mandatory_question_id": "string",

  • "option_id": null,

  • "question": "string",

  • "select": {

    • "Raw key value1": "string",

    • "Raw key value2": "string"

    }

}

Update mandatory question for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

mandatory_question_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The mandatory question ID.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
data_pattern

string

For unsupported data types, suppliers can provide a regular expression validation pattern. The data_type property must be STRING to use this feature.

data_type

required

string

The type of data the question will collect.

Enum:Description
DATE

Customers must select a single date.

DECIMAL

Customers must provide a decimal number value.

EMAIL

Customers must provide a valid email address.

INTEGER

Customers must provide an integer value.

PHONE_NUMBER

Customers must provide a phone number.

SELECT_ONE

Customers must select one value.

STRING

Customers must provide a text value.

holder_category_id

null or string

The holder category associated with the question. When null, the question is applied to all holder categories.

level

required

string

The level determines how to request the question: once per booking or once per person in a booking.

Enum:Description
BOOKING

The question must be answered once per booking.

BY_PAX

The question must be answered once per person in a booking.

mandatory_question_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The mandatory question ID, assigned by the supplier.

option_id

null or string

The option associated with the question. When null, the question is applied to all options.

question

required

string

The human-friendly question to show customers.

object

When the data_type property is SELECT_ONE, use the select property to provide options for customers to select. The property value must be a key-value object of strings.

200

Mandatory question for experience

put/supplier/catalog/experiences/{experience_id}/mandatory-questions/{mandatory_question_id}

  • Payload
  • curl
  • C#
  • Node.js

{

  • "data_pattern": "string",

  • "data_type": "DATE",

  • "holder_category_id": null,

  • "level": "BOOKING",

  • "mandatory_question_id": "string",

  • "option_id": null,

  • "question": "string",

  • "select": {

    • "Raw key value1": "string",

    • "Raw key value2": "string"

    }

}

  • 200
  • default

{

  • "data_pattern": "string",

  • "data_type": "DATE",

  • "holder_category_id": null,

  • "level": "BOOKING",

  • "mandatory_question_id": "string",

  • "option_id": null,

  • "question": "string",

  • "select": {

    • "Raw key value1": "string",

    • "Raw key value2": "string"

    }

}

// file: porta-site-docs/API Reference/Open slots.md

created: 2024-08-06T01:12:48 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Open slots

Excerpt

Bookings expire on a set date or a set number of days after purchase.


Bookings expire on a set date or a set number of days after purchase.

Get open slot for option

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/open_slots

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/open_slots'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

{

  • "available_holder_categories": [

    • {}

    ],

  • "guide_languages": [

    • "string"

    ],

  • "option_id": "string",

  • "slot_id": "string",

  • "open_slot": {

    • "duration_days": 0,

    • "type": "DURATION_DAYS"

    }

}

// file: porta-site-docs/API Reference/Options.md

created: 2024-08-06T01:12:09 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Options

Excerpt

Options are a variations of an experience. A customer must select an option to complete a booking.


Options are a variations of an experience. A customer must select an option to complete a booking.

Create option for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json

required

Array of objects (Holder category) unique

The holder categories for the option.

label

required

string

The human-friendly label for the option.

main_option

boolean

When true, the main option appears first in the list of options.

If no option is defined as the default, then the first option is automatically made the default.

max_booking_quantity

integer <int32>

The maximum quantity allowed per booking.

min_booking_quantity

integer <int32>

The minimum quantity required for a valid booking.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The option ID, assigned by the supplier.

post/supplier/catalog/experiences/{experience_id}/options

  • Payload
  • curl
  • C#
  • Node.js

{

  • "holder_categories": [

    • {}

    ],

  • "label": "string",

  • "main_option": true,

  • "max_booking_quantity": 0,

  • "min_booking_quantity": 0,

  • "option_id": "string"

}

  • 200
  • default

{

  • "holder_categories": [

    • {}

    ],

  • "label": "string",

  • "main_option": true,

  • "max_booking_quantity": 0,

  • "min_booking_quantity": 0,

  • "option_id": "string"

}

Remove option from experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

204

Option removed successfully

delete/supplier/catalog/experiences/{experience_id}/options/{option_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> DELETE <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/experiences/{experience_id}/options/{option_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • default

400 Bad request: check the request for errors

{

  • "code": "400",

  • "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",

  • "message": "Check the request for errors."

}

Update option for experience

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json

required

Array of objects (Holder category) unique

The holder categories for the option.

label

required

string

The human-friendly label for the option.

main_option

boolean

When true, the main option appears first in the list of options.

If no option is defined as the default, then the first option is automatically made the default.

max_booking_quantity

integer <int32>

The maximum quantity allowed per booking.

min_booking_quantity

integer <int32>

The minimum quantity required for a valid booking.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The option ID, assigned by the supplier.

409

Conflict: request conflicts with target resource

put/supplier/catalog/experiences/{experience_id}/options/{option_id}

  • Payload
  • curl
  • C#
  • Node.js

{

  • "holder_categories": [

    • {}

    ],

  • "label": "string",

  • "main_option": true,

  • "max_booking_quantity": 0,

  • "min_booking_quantity": 0,

  • "option_id": "string"

}

  • 200
  • 409
  • default

{

  • "holder_categories": [

    • {}

    ],

  • "label": "string",

  • "main_option": true,

  • "max_booking_quantity": 0,

  • "min_booking_quantity": 0,

  • "option_id": "string"

}

// file: porta-site-docs/API Reference/Pickups.md

created: 2024-08-06T01:12:20 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Pickups

Excerpt

Pickups are locations where customers can be picked up for their experience. Experiences are not required to have pickups. However, when pickups are assigned to experience options, selecting a pickup is required to complete a booking.


Pickups are locations where customers can be picked up for their experience. Experiences are not required to have pickups. However, when pickups are assigned to experience options, selecting a pickup is required to complete a booking.

Get pickups

SecuritySupplier-production or Supplier-sandbox

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/catalog/pickups

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  https://prod.api.tui/tui-musement-porta/supplier/catalog/pickups <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "name": "string",

    • "type": "HOTEL",

    • "latitude": -90,

    • "longitude": -180,

    • "pickup_id": "string",

    • "time_margin": 0

    }

]

Create pickup

SecuritySupplier-production or Supplier-sandbox

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
name

required

string

The human-friendly name for the pickup.

type

required

string

The type of pickup.

Enum:Description
HOTEL

The pickup is at a hotel.

MEETING_POINT

The pickup is a general location.

latitude

number <float> [ -90 .. 90 ]

The latitude value for the pickup location. This value may be omitted.

longitude

number <float> [ -180 .. 180 ]

The longitude value for the pickup location. This value may be omitted.

pickup_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The pickup ID, assigned by the supplier.

time_margin

integer <int32>

Default: 0

The number of minutes a pickup will occur before or after a time slot. This property accepts both positive and negative values.

A negative value indicates the pickup arrives before the time slot.

A positive value indicates the pickup arrives after the time slot.

post/supplier/catalog/pickups

  • Payload
  • curl
  • C#
  • Node.js

{

  • "name": "string",

  • "type": "HOTEL",

  • "latitude": -90,

  • "longitude": -180,

  • "pickup_id": "string",

  • "time_margin": 0

}

  • 200
  • default

{

  • "name": "string",

  • "type": "HOTEL",

  • "latitude": -90,

  • "longitude": -180,

  • "pickup_id": "string",

  • "time_margin": 0

}

Remove pickup

A pickup point cannot be removed if it is part of an availability slot. Suppliers must remove the pickup point from all availability slots first.

SecuritySupplier-production or Supplier-sandbox

path Parameters
pickup_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

204

Pickup removed successfully

delete/supplier/catalog/pickups/{pickup_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> DELETE <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/pickups/{pickup_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • default

400 Bad request: check the request for errors

{

  • "code": "400",

  • "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",

  • "message": "Check the request for errors."

}

Get pickup

SecuritySupplier-production or Supplier-sandbox

path Parameters
pickup_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/catalog/pickups/{pickup_id}

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/catalog/pickups/{pickup_id}'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

{

  • "name": "string",

  • "type": "HOTEL",

  • "latitude": -90,

  • "longitude": -180,

  • "pickup_id": "string",

  • "time_margin": 0

}

// file: porta-site-docs/API Reference/Time slots.md

created: 2024-08-06T01:12:54 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Time slots

Excerpt

Customers must select a date and time for a booking.


Customers must select a date and time for a booking.

Get time slots for option

The date_from and date_to query parameters permit up to 31 days of dates.

SecuritySupplier-production or Supplier-sandbox

path Parameters
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

query Parameters
date_from

required

string <date>

Filters results to those which take place on or after the specified date.

date_to

required

string <date>

Filters results to those which take place on or before the specified date.

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

get/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/time_slots

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  <span>'https://prod.api.tui/tui-musement-porta/supplier/availability/experiences/{experience_id}/options/{option_id}/slots/time_slots?date_from=2019-08-24&amp;date_to=2019-08-24'</span> <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "available_holder_categories": [],

    • "guide_languages": [],

    • "option_id": "string",

    • "slot_id": "string",

    • "capacity": 0,

    • "time_slot": {}

    }

]

// file: porta-site-docs/API Reference/Vendors.md

created: 2024-08-06T01:13:04 (UTC +02:00) tags: [] source: https://porta.redoc.ly/openapi/tag/mandatory-questions/ author:

Vendors

Excerpt

Suppliers can use vendors to indicate when experiences are sourced differently.


Get vendors

SecuritySupplier-production or Supplier-sandbox

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

  • curl
  • C#
  • Node.js
<span>curl</span> <span>-i</span> <span>-X</span> GET <span>\</span>
  https://prod.api.tui/tui-musement-porta/supplier/vendors <span>\</span>
  <span>-H</span> <span>'Authorization: Bearer &lt;YOUR_TOKEN_HERE&gt;'</span> <span>\</span>
  <span>-H</span> <span>'accept: application/json'</span> <span>\</span>
  <span>-H</span> <span>'accept-version: vnd.porta-api.v1'</span>
  • 200
  • default

[

  • {

    • "name": "string",

    • "vendor_id": "string"

    }

]

Create vendor

SecuritySupplier-production or Supplier-sandbox

header Parameters
accept

required

string

Specify the format of the response.

Value: "application/json"

accept-version

required

string (PORTA version)

The version of PORTA for the request.

Value:Description
vnd.porta-api.v1

Version 1.0.0

Request Body schema: application/json
name

required

string

The name of the vendor as it will appear in PORTA.

vendor_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The vendor ID, assigned by the supplier.

  • Payload
  • curl
  • C#
  • Node.js

{

  • "name": "string",

  • "vendor_id": "string"

}

  • 200
  • default

{

  • "name": "string",

  • "vendor_id": "string"

}

// file: porta-site-docs/Webhooks/01-intro.md

created: 2024-07-17T16:13:40 (UTC +02:00) tags: [] source: https://porta.redoc.ly/webhooks/ author:

Webhooks

Excerpt

Create a webhook service for PORTA so that you can sync your availability with ours.


Last updated 2 months ago

Suppliers must set up a webhook service to receive requests from PORTA related to bookings.

Authentication

PORTA will send requests to the supplier's webhook service endpoint with a pre-defined x-webhook-key header value.

Requests

PORTA currently makes the following webhook requests:

Error responses

If a request is not successful for any reason, the webhook response must be a 400 status code with one of the following error messages in the response's code property:

  • ELEMENT_NOT_FOUND
    • One or more of the IDs in the request are not recognized
  • INACTIVE_HOLD_KEY
    • When attempting to confirm a booking for an expired hold
  • INACTIVE_OR_UNAVAILABLE_EXPERIENCE
    • The experience is no longer available
  • INCORRECT_REQUEST
    • The request contains errors
  • NO_CAPACITY_LEFT
    • There are no more free seats available
  • NOT_CANCELLABLE_BOOKING
    • When attempting to cancel a booking that can no longer be cancelled
  • UNCLASSIFIED_ERROR
    • The error does not match any of the other cases
  • VALIDATION_ERROR
    • One or more of the properties (for example mandatory answers) does not match the expected type/format

// file: porta-site-docs/Webhooks/02-Hold availability.md

created: 2024-07-15T22:51:48 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Hold availability

Excerpt

Use the PORTA hold availability request webhook to temporarily block availability in your system for potential orders.


Last updated 2 months ago

A hold availability request is sent to hold/block availability, ensuring that a future booking is guaranteed within a pre-defined period. This gives the customer a reasonable amount of time to add something to cart and complete details for checkout.

During the contracting phase, suppliers will agree to a hold_duration period for hold availability requests. Once this period has passed, a successful booking for the same availability is no longer guaranteed.

Request and response

Request endpoint: POST {supplier_url}/hold

A hold availability request contains the following properties:

Request Body schema: application/json
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The experience ID.

expiration_time

required

string <date-time>

When the hold availability request can expire, based on the agreed upon hold_duration value.

The value for this property must be in the local time for the experience with no time zone information, following the ISO 8601 standard.

hold_id

required

string <uuid>

The ID of the hold availability request.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The option ID.

pickup_id

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The pickup ID, if any.

required

Array of objects unique

An array of the requested holder categories and their quantities.

slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The availability slot ID.

The response to a successful hold availability request contains the following properties:

Hold availability request accepted

Response Schema: application/json
hold_id

required

string

The hold ID from the request.

transaction_id

required

string

The supplier's own ID for the hold request.

Capacity and quantity limits

Before a hold request is sent, PORTA validates the requested quantities against the following properties:

  • Option's min_booking_quantity and max_booking_quantity
  • Availability slot's capacity
  • Available holder category's min_quantity and max_quantity

If any of these properties are missing in PORTA, their validation is skipped. If any of the requested quantities is invalid, the requesting application receives an error and no hold availability request is sent to suppliers.

When setting up an experience, consider that some applications, like our own musement.com, do not directly communicate quantity limits to customers. To reduce errors that customers may encounter while placing an order, consider avoiding limits to the capacity/quantities contained within an experience.

// file: porta-site-docs/Webhooks/03-Booking confirmation request.md

created: 2024-07-15T22:52:16 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Booking confirmation request

Excerpt

Use the PORTA booking confirmation request webhook to record a paid order.


Last updated 2 months ago

Request endpoint: POST {supplier_url}/booking

A booking confirmation request is sent when a customer places a paid order.

A booking confirmation request contains the following properties:

Request Body schema: application/json
booking_id

required

string

The ID of the booking to confirm.

required

Array of objects unique

An array of items for the booking.

hold_id

required

string

The ID of the availability hold request made when a customer added the item to cart.

required

object

Information about the lead booker.

tuimm_booking_id

required

string^MUS[0-9]+?_[0-9]+?$

This property contains Musement booking information.

The value consists of two IDs separated by an underscore. The first ID, consisting of MUS and numbers, is the order ID to use when contacting Musement Customer Care.

The second ID, consisting only of numbers, is the ID for a single item in the order. This ID is used for internal technical checks and is not relevant when contacting Musement Customer Care.

The response to a successful booking confirmation request contains the following properties:

Booking confirmation request accepted

Response Schema: application/json
booking_id

required

string

The booking ID from the request.

required

Array of Per person (object) or Per group (object)

An array of tickets that customers can use for their experience. Tickets can be unique per person in the booking or valid for the entire group.

transaction_id

required

string

The supplier's own ID for the booking request.

Timing out

During initial registration negotiations, suppliers agree to webhook response time limits. If the supplier's webhook service takes too long to respond to a booking confirmation request, the booking is no longer considered valid. When this happens, PORTA automatically sends a cancellation request. In these situations, suppliers are required to cancel the booking, regardless of the experience's cancellation policy.

// file: porta-site-docs/Webhooks/04-Booking cancellation request.md

created: 2024-07-15T22:52:22 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Booking cancellation request

Excerpt

A PORTA booking cancellation request is sent when an order is cancelled by a customer.


Last updated 2 months ago

Request endpoint: DELETE {supplier_url}/booking

A booking cancellation request is usually sent when an order is cancelled by a customer.

A booking cancellation request contains the following properties:

Request Body schema: application/json
booking_id

required

string <uuid>

The ID of the booking to cancel.

ticket_numbers

required

Array of strings

A list of ticket values issued by the original booking confirmation response.

transaction_id

required

string

The ID issued by the original booking confirmation response.

Timing out

If a booking confirmation request times out, the order is no longer considered valid. When this occurs, a cancellation request is sent one minute later with an unconfirmed property value of true. Suppliers are required to cancel the booking, regardless of the experience's cancellation policy.

// file: porta-site-docs/Webhooks/05-Health check.md

created: 2024-07-15T22:52:28 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Health check

Excerpt

PORTA makes a regular health check request to ensure that your integration is working as expected.


Last updated 2 months ago

Request endpoint: GET {supplier_url}/heath

PORTA will call the webhook service approximately every five minutes to verify its status. A non-200 status code response could lead to temporarily disabling products in the Musement catalog until the supplier's service is restored.

// file: porta-site-docs/Webhooks/06-Testing.md

created: 2024-07-15T22:53:23 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Testing

Excerpt

Test your integration by triggering webhook requests in PORTA's sandbox environment.


Last updated 2 months ago

The sandbox environment includes additional endpoints for testing webhooks. Sending a request to these endpoints transforms it into a request for your webhook service. Using these endpoints allows suppliers to test their integration before going live.

The request bodies must contain most of the same properties expected for real requests. Suppliers need to generate values for some properties, while others should come from existing properties in the sandbox environment.

Properties used across multiple webhook requests must contain consistent values. Generated values cannot always be completely random.

Hold availability

You can send yourself a hold availability request in the sandbox environment at POST /supplier/integration-tests/hold:

Request Body schema: application/json
experience_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID for an existing sandbox experience.

expiration_time

required

string <date-time>

When the hold availability request can expire, based on the agreed upon hold_duration value.

The value for this property must be in the local time for the experience with no time zone information, following the ISO 8601 standard.

hold_id

required

string <uuid>

A randomly-generated UUID. The same hold_id value must be used when testing the booking confirmation webhook.

option_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID for an existing sandbox option.

pickup_id

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID for an existing sandbox pickup, if any.

required

Array of objects unique

An array of the requested holder categories and their quantities.

slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID for an existing sandbox availability slot.

A valid request returns an empty 200 status code response. Request errors return a 400 status code response.

Booking confirmation

You can send yourself a booking confirmation request at POST /supplier/integration-tests/book:

Request Body schema: application/json
booking_id

required

string <uuid>

A randomly-generated UUID. The same booking_id value must be used when testing the booking cancellation webhook.

required

Array of objects unique

An array of items for the booking.

hold_id

required

string

The ID of the sandbox hold availability request.

required

object

Randomly-generated lead booker information.

pickup_id

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of an existing sandbox pickup, if any.

Note that the location of this property differs from its location in the confirmation request sent to your webhook service.

slot_id

required

string^(?!\-|\.|\_)[0-9a-z\-\.\_]{1,50}$

The ID of an existing sandbox availability slot.

Note that the location of this property differs from its location in the confirmation request sent to your webhook service.

request_id

required

string <uuid>

In production this property reflects PORTA's own ID for the item in the webhook request. Here, it can be a randomly-generated UUID. The same request_id value will appear in the request sent to the webhook service.

Note that the location of this property differs from its location in the confirmation request sent to your webhook service.

Please note that the request for this endpoint differs from the request that is eventually sent to the webhook service. The following properties in this request are moved to each item in the booking_requests property:

  • request_id
  • guide_language
  • pickup_id (if present)
  • slot_id

A randomly-generated value for tuimm_booking_id is also added to the final request that the webhook service receives.

A valid request returns an empty 200 status code response. Request errors return a 400 status code response.

Booking cancellation

You can trigger a booking cancellation request at POST /supplier/integration-tests/cancel-booking:

Request Body schema: application/json
booking_id

required

string <uuid>

The ID of the booking to cancel.

ticket_numbers

required

Array of strings

A list of ticket values issued by the original booking confirmation response.

transaction_id

required

string

The ID issued by the original booking confirmation response.

A valid request returns an empty 200 status code response. Request errors return a 400 status code response.

// file: porta-site-docs/Getting Started/01-Intro to PORTA.md

created: 2024-07-15T22:48:11 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Intro to PORTA

Excerpt

Learn how you can access PORTA to manage your experiences on Musement.


Last updated 2 months ago

Welcome to the Musement supplier API documentation!

This documentation is for suppliers who want to manage their experiences in the Musement catalog via their own API integration.

Why PORTA?

While Musement's business platform allows suppliers to curate their portfolio, manually managing availability for multiple experiences can become time-consuming. Suppliers with sufficient "tech know-how" can speed up their workflow by integrating with our supplier API service, PORTA (Perfect Open Road To Activities).

An integration with PORTA allows suppliers to use their own systems to synchronize dates, prices and bookings with experiences in the Musement catalog. By letting the computers do all the work, you save yourselves time for more human matters (coffee breaks, for example).

Registration

Before suppliers can begin using PORTA, they need an account on Musement's business platform. Registration is free, but you won't be able to create an experience or access PORTA until a member of the Offer Supply team gets in touch to verify your business platform account.

Once your account has been verified, contact your Offer Supply representative for access to PORTA. After contract negotiations, you will receive credentials from our Integrations team to use for the API.

Publishing

Experiences created in PORTA are not automatically added to Musement's catalog. A member of the Content Supplier Connectivity team must connect the PORTA experience to an experience in the business platform. The text content and images must pass a preliminary review before the experience can be published to the catalog.

Once an experience is published, bookings will be sent back to the supplier through PORTA via webhook.

Below is a simple diagram to visualize the relationship between a supplier and Musement's catalog via PORTA and the business platform:

// file: porta-site-docs/Getting Started/02-OpenAPI.md

created: 2024-07-15T22:48:30 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

OpenAPI

Excerpt

Use the OpenAPI specification for PORTA to get your integration set up quickly.


Last updated 2 months ago

Our documentation follows the OpenAPI specification.

The PORTA OpenAPI specification file for suppliers is available for download in the API reference section.

// file: porta-site-docs/Getting Started/03-Authentication.md

created: 2024-07-15T22:48:41 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Authentication

Excerpt

Use OAuth 2.0 to receive an access token so that you can use PORTA.


Last updated 2 months ago

Authentication must be the first step before making any other API request.

PORTA uses the OAuth 2.0 authorization framework to give applications access to the API. Check out RFC-6749 and DigitalOcean for an in-depth overview of the framework.

Suppliers are assigned an access key and secret key to use for the initial authentication request:

curl 'https://prod.api.tui/oauth2/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id={accessKey}' \ -d 'client_secret={secretKey}' \ -d 'grant_type=client_credentials'
Content-Type

Note the Content-Type header in the request above. This endpoint does not accept other header values, such as application/json.

A successful response returns an access_token property to use for all subsequent API requests. The token_type property in the response indicates how to use token and the expires_in property communicates how long the token will last.

In the example response below, we are given an access token that will last one hour:

{ "token_type": "Bearer", "access_token": "FnxKF4w47kq2McBs4eP48kqB9KgX", "client_id": "KSc6yRCwWpTq4xdrQL5mxxGgve23WBJK", "scope": "musement-porta-product.write musement-porta-product.all musement-porta-product.read", "expires_in": 3599, "issued_at": 1678189085804 }

The token_type value of bearer in the above example means the token must be added to the Authorization HTTP header, preceded by the word Bearer and a space:

curl '{baseUrl}/supplier/catalog/experiences' \ -H 'accept: application/json' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer FnxKF4w47kq2McBs4eP48kqB9KgX'

When a token expires, repeat the authentication process to receive a new valid token.

// file: porta-site-docs/Getting Started/04-Environments.md

created: 2024-07-15T22:49:09 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Environments

Excerpt

See a list of available testing environments for PORTA.


Last updated 2 months ago

PORTA offers a sandbox environment at https://prod.api.tui/tui-musement-porta-site. This environment exists exclusively for testing your integration with PORTA and is not connected to other Musement systems such as the business platform. The sandbox environment includes additional endpoints for testing webhook requests.

The production environment is available at https://prod.api.tui/tui-musement-porta.

// file: porta-site-docs/Getting Started/05-Version.md

created: 2024-07-15T22:49:16 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Version

Excerpt

Specify which version of PORTA you use in your integration.


Last updated 2 months ago

In addition to an access token, all requests must specify which version of the PORTA API they are accessing in the accept-version header. The example request below is for version 1:

curl '{baseUrl}/supplier/catalog/experiences' \ -H 'accept: application/json' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}'

Requests made without a valid API version will receive a 412 status code response:

{ "code": "412", "id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce", "message": "Missing accept-version header." }

At this time there is only one available version, vnd.porta-api.v1. This may change in the future.

// file: porta-site-docs/Getting Started/06-Documentation release notes.md

created: 2024-07-15T22:49:37 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Documentation release notes

Excerpt

A record of all major changes to the PORTA documentation.


Last updated 2 months ago

This page describes major changes to information in the PORTA documentation. For changes in the API, refer to the release notes in the API reference.

2024-04-17

  • Corrected information about dates and times

2024-03-08

2024-01-12

2023-12-06

2023-11-15

  • Corrected errors in OpenAPI spec for webhook booking confirmation response
    • Removed non-existent mimeType property from FOR_SINGLE_PERSON tickets
    • Removed non-existent URL enum from format property for FOR_SINGLE_PERSON tickets

2023-10-24

2023-10-20

  • Changes to webhook testing page
    • Added diagram of testing flow
    • Corrected errors regarding testing endpoint responses
    • Modified OpenAPI spec to highlight differences between testing requests and webhook requests

2023-10-12

  • Added details about the vendor_id query parameter for the endpoint GET /supplier/catalog/experiences
  • Corrections for the webhook cancellation test endpoint
    • Added missing request body properties
    • Updated response details

2023-10-02

2023-07-14

2023-06-22

2023-06-09

2023-05-04

  • Removed Supplier code page
  • Removed supplier-code header from all request examples

2023-04-20

2023-03-23

  • Removed pages describing business platform configurations in PORTA. This information will be managed by the Content Supplier Connectivity team

Navigated to Documentation release notes

// file: porta-site-docs/Managing experiences/01-Vendors.md


created: 2024-07-15T22:49:57 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Vendors

Excerpt

Learn how to create a vendor for your experiences in PORTA.


Last updated 2 months ago

Vendors allow suppliers to separate experiences with different sources, partners and/or channels.

Since a vendor is required when creating an experience in PORTA, new suppliers need to create a vendor first:

curl '{baseUrl}/supplier/vendors' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "name": "Supplier Tours Inc", "vendor_id": "vendor-123" }'

Suppliers who source the experience themselves, or do not have different channels, can create a vendor with their own name.

You can filter experiences in PORTA by a specific vendor using the vendor_id query parameter with the GET /supplier/catalog/experiences endpoint:

curl '{baseUrl}/supplier/catalog/experiences?vendor_id=vendor-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json'

// file: porta-site-docs/Managing experiences/02-Experiences.md

created: 2024-07-15T22:50:03 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Experiences

Excerpt

Use PORTA to create experiences for Musement's distribution platforms.


Last updated 2 months ago

Experiences can be almost anything: tickets for museums, wine tastings, tours, etc. They are the core of the Musement catalog.

Creating an experience

When creating an experience in PORTA, suppliers must use the POST /supplier/catalog/experiences endpoint:

curl '{baseUrl}/supplier/catalog/experiences' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "availability_slot_type": "TIME", "currency": "USD", "cutoff_time": "P1D", "experience_id": "abc-123", "experience_name": "Example tour with attraction tickets", "external_experience_id": "Example-123", "external_experience_name": "Example tour and admission", "options": [], "vendor_id": "vendor-123" }'

The following information is required for the request:

availability_slot_type

This property determines how customers will book the experience. It accepts the following values:

  • DAILY
    • Customers must select a date for their booking. They do not select a time.
  • OPEN
    • Customers do not select a date or time. Their booking expires on a set date or a set number of days after purchase.
  • TIME
    • Customers must select a date and time for their booking.

currency

The currency used for billing. The value must follow the ISO 4217 standard.

experience_id

Suppliers must provide their own ID for the experience. This ID will be used for all related API requests.

experience_name

Give the experience a name to make it easier to recognize whenever you access PORTA.

options

A list of bookable options for the experience. An experience must have at least one option to start with. Options can be added and removed later.

vendor_id

The experience's vendor.

Setting a cutoff time

When creating an experience, you can specify a cutoff_time value. This is the minimum amount of time required to book a travel date in advance.

The value must follow the ISO 8601 standard.

External values

If the names and IDs of experiences vary differently between PORTA and your system, there are two optional properties you can use to help keep track of your products:

  • external_experience_id
    • The ID of the experience as it appears in your own system.
  • external_experience_name
    • The name of the experience as it appears in your own system.

Archiving an experience

The archived property determines whether an experience is for sale or not. By default, new experiences are not archived. When an experience is archived, its corresponding activity in the business platform (if any) is also archived to stop sales.

Archiving is an acceptable approach to closing experiences that will never be available again. Suppliers may also choose to archive experiences temporarily. However, be aware that once an activity is archived, suppliers need the help of the Content Supplier Connectivity team to un-archive the business platform activity.

Time to archive

When an experience is archived, it may take up to 24 hours for Musement websites to update. To avoid receiving further bookings, we encourage suppliers to archive the corresponding business platform activity too.

Updating an experience

Suppliers can update a selection of experience properties with the PATCH /supplier/catalog/experiences/{experience_id} endpoint:

curl '{baseUrl}/supplier/catalog/experiences/abc-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "archived": true, "cutoff_time": "P3D", "experience_name": "Example tour with attraction tickets and lunch", "external_experience_id": "Example-123-lunch", "external_experience_name": "Example tour and admission with lunch", "vendor_id": "vendor-123-lunch" }'

Suppliers can choose to update one or more properties with this endpoint.

Changes may take up to 24 hours to appear on the business platform and Musement distribution websites.

// file: porta-site-docs/Managing experiences/03-Options.md

created: 2024-07-15T22:50:07 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Options

Excerpt

Create options in PORTA to give customers something to choose for their bookings.


Last updated 2 months ago

Options are variations to the main experience. Customers must choose an option to complete a booking.

Creating an option

Options can either be created when creating an experience or by using the POST /supplier/catalog/experiences/{experience_id}/options endpoint.

An option must contain the following properties:

option_id

The option ID, assigned by the supplier.

label

The human-friendly label for the option that customers will see.

holder_categories

Every option must have at least one holder category, the type of person making a booking.

Limiting quantities

Suppliers can set a minimum quantity required for a booking with an option's min_booking_quantity property. Only bookings with a total quantity that is greater than or equal to this value are accepted.

Suppliers can set a maximum limit per booking with an option's max_booking_quantity property. Only bookings with a total quantity that is less than or equal to this value are accepted. When no maximum is specified, no limit is placed on the booking quantity.

Changing the order

While PORTA returns options sorted by the order they were created, on musement.com options appear in order from least to most expensive. Suppliers can modify this order by assigning a main_option property value of true to a single option. The main option for an experience will appear first in the list of options on musement.com:

options

// file: porta-site-docs/Managing experiences/04-Holder categories.md

created: 2024-07-15T22:50:12 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Holder categories

Excerpt

Use holder categories in PORTA so that customers can select the type of person for a booking.


Last updated 2 months ago

Holder categories are part of options. They describe the type of person for a booking.

Creating a holder category

Holder categories do not have their own endpoint. They are part of an option.

Each holder category in an option must have the follow properties:

holder_category_id

The supplier's ID for the holder category.

holder_type

The type of holder category. This value affects how the holder category appears on Musement. Choices are limited to:

  • ADULT
  • CHILD
  • FAMILY
  • GROUP
  • INFANT
  • MILITARY
  • REGULAR
  • SENIOR
  • STUDENT
  • YOUTH

An additional CUSTOM* value is available but requires approval with the Integrations team before usage.

minimum_age

The minimum age a customer must have to qualify for this holder category.

While not required, there is a maximum_age property which can be used to specify the maximum age a customer can have to qualify for a holder category.

Changing the order

While PORTA returns holder categories sorted by the order they were created, on musement.com holder categories appear in order from most to least expensive. Suppliers can modify this order by assigning a default_category property value of true to a single holder category in an option. The main holder category for an experience will appear first in the list of holder categories on musement.com:

holders

// file: porta-site-docs/Managing experiences/05-Mandatory questions.md

created: 2024-07-15T22:50:52 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Mandatory questions

Excerpt

Mandatory questions allow PORTA to collect customer information that you need to complete booking.


Last updated 2 months ago

Mandatory questions allow suppliers to request customer information. Experiences are not required to have mandatory questions. However, when mandatory questions are present, customers must provide answers to complete a booking.

Creating a mandatory question

Suppliers must use the POST /supplier/catalog/experience/{experience_id}/mandatory-questions endpoint to create a mandatory question for an experience:

curl -X POST '{baseUrl}/supplier/catalog/experience/experience-123/mandatory-questions' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "data_type": "string", "level": "BY_PAX", "mandatory_question_id": "question-123", "question": "What is your favorite color?" }'

When creating a mandatory question, the request must contain the following properties:

data_type

The type of data you are collecting. Based on the value of this property, the resulting field appearance will change on the Musement platform and additional validation checks may take place.

Currently, the following values are valid:

  • DATE
    • Customers must select a single date.
  • DECIMAL
    • Customers must provide a decimal number value.
  • EMAIL
    • Customers must provide a valid email address.
  • INTEGER
    • Customers must provide an integer value.
  • PHONE_NUMBER
    • Customers must provide a phone number.
  • SELECT_ONE
    • Customers must select one value.
  • STRING
    • Customers must provide a text value.

level

The level property determines whether the question is presented once per booking or once per person in a booking:

  • BOOKING : The question is presented once per booking.
  • BY_PAX : The question is presented once per person in a booking.

mandatory_question_id

Suppliers must provide their own ID for the mandatory question.

question

The human-friendly question to show customers in English.

Assigning questions to options and holder categories

By default, a mandatory question is applied to all options and holder categories in an experience.

You can restrict a question to specific options and holder categories by passing their option_id and holder_category_id in the request.

In the example request below, we are updating a question to a child holder category (ID category-child-123):

curl -X PUT '{baseUrl}/supplier/catalog/experience/experience-123/mandatory-questions/question-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "data_type": "STRING", "holder_category_id": "category-child-123", "level": "BY_PAX", "mandatory_question_id": "question-123", "question": "What is your favorite color?" }'

You can limit a mandatory question to both an option and holder category too:

curl -X PUT '{baseUrl}/supplier/catalog/experience/experience-123/mandatory-questions/question-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "data_type": "STRING", "holder_category_id": "category-child-123", "level": "BY_PAX", "mandatory_question_id": "question-123", "option_id": "option-123", "question": "What is your favorite color?" }'

Giving customers options

When a mandatory question's data_type property is SELECT_ONE, customers are offered a list of options to choose from.

Suppliers must use add the select property to define the options to list. The property value must contain string key-value pairs, with the raw value and human-friendly version.

In the example request below, customers must select between two choices:

curl -X PUT '{baseUrl}/supplier/catalog/experience/experience-123/mandatory-questions/question-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "data_type": "SELECT_ONE", "holder_category_id": "category-child-123", "level": "BY_PAX", "mandatory_question_id": "question-123", "question": "What is your favorite color?", "select": { "red": "Red", "blue": "No, blue!" } }'

Other data types

If you require the responses to mandatory questions to conform to a particular pattern, you can use the data_pattern property to define a regular expression that will be used for validation.

This property can only be used when the data_type property value is STRING.

In the example response below, we are creating a mandatory question which only accepts lowercase letters:

curl -X POST '{baseUrl}/supplier/catalog/experience/experience-123/mandatory-questions' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "data_pattern": "^[a-z]$", "data_type": "STRING", "level": "BY_PAX", "mandatory_question_id": "question-123", "question": "What is your favorite color?" }'

// file: porta-site-docs/Managing experiences/06-Pickup points.md

created: 2024-07-15T22:50:59 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Pickup points

Excerpt

Collect your customers from pickup locations loaded into PORTA.


Last updated 2 months ago

In the Musement catalog, experiences with pickup points require customers to select a pickup location before selecting a date. This is useful for situations where the dates and prices can vary by pickup location.

If nothing varies for your pickups, consider setting up pickups as mandatory questions instead so that they appear near the end of the booking flow.

When an experience contains pickups, selecting a pickup is required to complete a booking. However, pickups are optional for experiences and suppliers can skip this step if they don't plan to use them.

Creating a pickup

You only need to create a pickup location once. It can be used again for multiple experiences.

curl -X POST '{baseUrl}/supplier/catalog/pickups' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "latitude": 39.65577, "longitude": 3.43884, "name": "Taxi stop hotel melbeach", "pickup_id": "pickup-123", "type": "MEETING_POINT" }'

The following properties are required for new pickup points:

pickup_id

Suppliers must provide their own ID for a pickup. This ID will be used for relevant endpoints and requests.

name

Give the pickup point a name in English that customers will use during booking.

type

This property specifies whether the pickup point is a general location or the lobby of a hotel:

  • HOTEL
    • The pickup is at a hotel.
  • MEETING_POINT
    • The pickup is a general location.

Pickup points for an experience on Musement.com are separated between the two types:

pickup division

Coordinates

When creating a pickup point, you can choose to indicate its exact location by including latitude and longitude properties.

Offsetting pickup times

When creating a pickup point, the request can also include an optional time_margin property to indicate how many minutes a pickup will occur before (or after) an availability time slot.

Managing pickups for a time slot

Pickups can only be used for experiences that use time slots, when the availability_slot_type property value is TIME. The pickups are not assigned directly to experiences, but rather to an availability slot. This allows you to set up different pickups for different dates and prices (if necessary).

When creating an availability time slot, include a list of pickup IDs. In the example request below, we are creating an availability slot with one pickup point:

curl -X POST '{baseUrl}/supplier/availability/experiences/experience-123/options/option-123/slots' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "availability_slot_id": "slot-123", [...], "pickup_ids": [ "pickup-123" ], [...] }'

To add or remove a pickup from an availability time slot, you must update the slot with the modified pickup_ids property. In the example request below, all pickups are removed:

curl -X PUT '{baseUrl}/supplier/availability/experiences/experience-123/options/option-123/slots/slot-123' \ -H 'accept-version: vnd.porta-api.v1' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ [...], "pickup_ids": [], [...] }'

// file: porta-site-docs/Managing experiences/07-Availability slots.md

created: 2024-07-15T22:51:15 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Availability slots

Excerpt

Combine PORTA options and holder categories to create availability slots so that customers can book their experience.


Last updated 2 months ago

Availability slots bring together all the components needed for a valid booking.

Creating an availability slot

Suppliers must use the POST /supplier/availability/experiences/{experience_id}/options/{option_id}/slots endpoint to create an availability slot for an experience. The exact body of the request changes based on the type of slot the experience needs.

Option

The option_id property must contain the ID of the option for the slot.

Available holder categories

Every slot must contain a list of holder categories that are available for the slot in the available_holder_categories property. Each item must correspond to one of the option's holder categories and include its price (in cents).

The min_quantity property for an available holder category indicates the minimum pax number which must be selected for a valid booking. The max_quantity property indicates the maximum possible pax number which can be selected. When a maximum is not specified, no limit is enforced.

Type

In addition to the properties described above, an availability slot will have additional properties depending on the availability_slot_type of the experience:

Setting limits

The capacity property indicates the number of seats left for the availability slot. When the value is zero, the slot is no longer available. When this property is not provided, no seat limit is enforced.

Note that each pax number of holder categories in a booking will reduce the availability slot's remaining capacity. It is currently not possible to set a separate capacity for each holder category.

Specifying languages

The guide_languages property lists languages which can be booked for the option and slot. This property is optional and can be skipped if there is no language component. The value must match the ISO 639-1 standard.

// file: porta-site-docs/Managing experiences/08-Daily slot.md

created: 2024-07-15T22:51:07 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Daily slot

Excerpt

Daily slots in PORTA require customers to select a single date for a booking.


Last updated 2 months ago

A daily slot requires customers to select a single date for a booking.

When an availability slot is daily, it must contain a daily_slot property with the bookable date. In the example response below, the slot is set up for 22 April 2023:

{ [...], "daily_slot": { "date": "2023-04-22" }, [...] }

Dates are automatically assumed to match the local date of the experience location.

// file: porta-site-docs/Managing experiences/09-Open slot.md

created: 2024-07-15T22:51:27 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Open slot

Excerpt

Open slots in PORTA give customers a booking that is valid for a set amount of time.


Last updated 2 months ago

An open slot automatically provides customers with a booking that is valid for a set amount of time.

The exact expiration date depends on the availability slot's open_slot property.

Duration days

When a booking is valid for a set number of days after purchase, the open slot's type property value is DURATION_DAYS. The slot should contain a duration_days property with the exact number of days.

In the example response below, the open slot is valid for 180 days after purchase:

{ [...], "open_slot": { "duration_days": 180, "type": "DURATION_DAYS" }, [...] }

End date

When all bookings must expire on a specific date, the open slot's type property value is END_DATE. The slot must contain an end_date property with the expiration date.

In the example response below, the open slot expires on 23 April 2023:

{ [...], "open_slot": { "end_date": "2023-04-23", "type": "END_DATE" }, [...] }

// file: porta-site-docs/Managing experiences/10-Time slot.md

created: 2024-07-15T22:51:32 (UTC +02:00) tags: [] source: https://porta.redoc.ly/getting-started/ author:

Time slot

Excerpt

Time slots in PORTA require customers to select both a date and time for a booking.


Last updated 2 months ago

A time slot requires customers to select a date and time for a booking.

When an availability slot is time-based, it must contain a time_slot property with the bookable date and time. In the example response below, the slot is set up for 22 April 2023 at 6pm:

{ [...], "time_slot": { "end": "2023-04-22T20:00:00Z", "start": "2023-04-22T18:00:00Z" }, [...] }
A note on time

Times in PORTA must be loaded for the local time of the experience. Do not adjust times for time zones or include time zone information.

End time

A time slot must include an end date and time in the end property. In the example below, the slot is set to start at 6pm on 22 April 2023 and end two hours later:

{ [...], "time_slot": { "end": "2023-04-22T20:00:00Z", "start": "2023-04-22T18:00:00Z" }, [...] }

The end property should reflect when the booked experience will end. If it does not have a well defined end time, we recommend to use the same value for both the start and end time:

{ [...], "time_slot": { "end": "2023-04-22 18:00:00Z", "start": "2023-04-22 18:00:00Z" }, [...] }

Suppliers should be aware that this suggestion may change in the future.

Pickups

Time slots support pickup points. The pickup_ids property lists the IDs of pickup points that are available for the slot. In the example response below, the slot contains a single pickup point:

{ [...], "time_slot": { "end": "2023-04-22 20:00:00Z", "pickup_ids": [ "pickup-123" ], "start": "2023-04-22 18:00:00Z" }, [...] }

How we do it

When selecting pickups and times on one of our distribution websites, like musement.com, the start time of the time slot is shown. However, if a pickup point contains a time_margin value, the displayed time slot is modified to show the pickup time.

In the example screenshot below, the time slot is for 18:00, but the pickup's time_margin property value is -15 (15 minutes before the time slot):

pickup time

The modified time slot is limited to the Musement website, booking information and customer vouchers. The original time and time_margin remain unchanged in PORTA:

{
"openapi": "3.1.0",
"components": {
"requestBodies": {
"BookingConfirmationRequest": {
"content": {
"application/json": {
"schema": {
"title": "Booking confirmation request",
"properties": {
"booking_id": {
"description": "The ID of the booking to confirm.",
"type": "string"
},
"booking_requests": {
"description": "An array of items for the booking.",
"items": {
"properties": {
"holder_category_id": {
"description": "The holder category ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"mandatory_answers": {
"description": "An array of customer answers to any mandatory questions for the experience and/or option.\n\nAnswers to mandatory questions with a `level` property value of `BOOKING` appear for every booking item.\n\nAnswers to mandatory questions with a `level` property value of `BY_PAX` appear for their respective booking item.\n",
"items": {
"properties": {
"answer": {
"description": "The customer's answer to the question.",
"type": "string"
},
"mandatory_question_id": {
"description": "The mandatory question ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"required": [
"answer",
"mandatory_question_id"
],
"type": "object"
},
"type": "array"
},
"pickup_id": {
"description": "The pickup ID, if any.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"request_id": {
"description": "PORTA's own ID for this item in the booking.",
"format": "uuid",
"type": "string"
},
"slot_id": {
"description": "The availability slot ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"required": [
"holder_category_id",
"request_id",
"slot_id"
],
"type": "object"
},
"type": "array",
"uniqueItems": true
},
"hold_id": {
"description": "The ID of the availability hold request made when a customer added the item to cart.",
"type": "string"
},
"holder": {
"description": "Information about the lead booker.",
"properties": {
"email": {
"description": "The customer's email address.",
"format": "email",
"type": "string"
},
"first_name": {
"description": "The customer's first name.",
"type": "string"
},
"last_name": {
"description": "The customer's last name.",
"type": "string"
}
},
"type": "object",
"required": [
"email",
"first_name",
"last_name"
]
},
"tuimm_booking_id": {
"description": "This property contains Musement booking information.\n\nThe value consists of two IDs separated by an underscore. The first ID, consisting of `MUS` and numbers, is the order ID to use when contacting Musement Customer Care.\n\nThe second ID, consisting only of numbers, is the ID for a single item in the order. This ID is used for internal technical checks and is not relevant when contacting Musement Customer Care.\n",
"pattern": "^MUS[0-9]+?_[0-9]+?$",
"type": "string"
}
},
"required": [
"booking_id",
"booking_requests",
"hold_id",
"holder",
"tuimm_booking_id"
],
"type": "object"
}
}
}
},
"BookingCancellationRequest": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/BookingCancellation"
},
{
"$ref": "#/components/schemas/BookingCancellationTimeout"
}
]
}
}
}
},
"HoldAvailabilityRequest": {
"content": {
"application/json": {
"schema": {
"title": "Hold availability request",
"properties": {
"experience_id": {
"description": "The experience ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"expiration_time": {
"description": "When the hold availability request can expire, based on the agreed upon `hold_duration` value.\n\nThe value for this property must be in the local time for the experience with no time zone information, following the [ISO 8601 standard](https://www.iso.org/iso-8601-date-and-time-format.html).\n",
"example": "2024-04-22T12:42:37Z",
"format": "date-time",
"type": "string"
},
"hold_id": {
"description": "The ID of the hold availability request.",
"format": "uuid",
"type": "string"
},
"option_id": {
"description": "The option ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"pickup_id": {
"description": "The pickup ID, if any.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"quantities": {
"description": "An array of the requested holder categories and their quantities.",
"items": {
"properties": {
"holder_category_id": {
"description": "The holder category ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"guide_language": {
"title": "Language",
"description": "The requested language.\n\nThis property must follow the [ISO 639-1 standard](https://www.iso.org/iso-639-language-codes.html).\n",
"type": "string"
},
"quantity": {
"description": "The quantity of pax.",
"minimum": 1,
"format": "int32",
"type": "integer"
}
},
"type": "object",
"required": [
"holder_category_id",
"quantity"
]
},
"type": "array",
"uniqueItems": true
},
"slot_id": {
"description": "The availability slot ID.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"type": "object",
"required": [
"experience_id",
"expiration_time",
"hold_id",
"option_id",
"quantities",
"slot_id"
]
}
}
}
},
"TestBookingCancellationRequest": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/BookingCancellation"
},
{
"$ref": "#/components/schemas/BookingCancellationTimeout"
}
]
}
}
}
},
"TestBookingConfirmationRequest": {
"content": {
"application/json": {
"schema": {
"title": "Test booking confirmation request",
"properties": {
"booking_id": {
"description": "A randomly-generated UUID. The same `booking_id` value must be used when testing the booking cancellation webhook.",
"format": "uuid",
"type": "string"
},
"booking_requests": {
"description": "An array of items for the booking.",
"items": {
"properties": {
"holder_category_id": {
"description": "The ID of a sandbox holder category.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"mandatory_answers": {
"description": "An array of customer answers to any mandatory questions for the sandbox experience and/or option.",
"items": {
"properties": {
"answer": {
"description": "A randomly-generated valid answer to the question.",
"type": "string"
},
"mandatory_question_id": {
"description": "The ID of an existing sandbox mandatory question.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"required": [
"answer",
"mandatory_question_id"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"holder_category_id"
],
"type": "object"
},
"type": "array",
"uniqueItems": true
},
"hold_id": {
"description": "The ID of the sandbox hold availability request.",
"type": "string"
},
"holder": {
"description": "Randomly-generated lead booker information.",
"properties": {
"email": {
"description": "Randomly-generated email address.",
"format": "email",
"type": "string"
},
"first_name": {
"description": "Randomly-generated first name.",
"type": "string"
},
"last_name": {
"description": "Randomly-generated last name.",
"type": "string"
}
},
"type": "object",
"required": [
"email",
"first_name",
"last_name"
]
},
"pickup_id": {
"description": "The ID of an existing sandbox pickup, if any.\n\nNote that the location of this property differs from its location in the confirmation request sent to your webhook service.\n",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"slot_id": {
"description": "The ID of an existing sandbox availability slot.\n\nNote that the location of this property differs from its location in the confirmation request sent to your webhook service.\n",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"request_id": {
"description": "In production this property reflects PORTA's own ID for the item in the webhook request. Here, it can be a randomly-generated UUID. The same `request_id` value will appear in the request sent to the webhook service.\n\nNote that the location of this property differs from its location in the confirmation request sent to your webhook service.\n",
"format": "uuid",
"type": "string"
}
},
"required": [
"booking_id",
"booking_requests",
"hold_id",
"holder",
"request_id",
"slot_id"
],
"type": "object"
}
}
}
},
"TestHoldAvailabilityRequest": {
"content": {
"application/json": {
"schema": {
"title": "Test hold availability request",
"properties": {
"experience_id": {
"description": "The ID for an existing sandbox experience.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"expiration_time": {
"description": "When the hold availability request can expire, based on the agreed upon `hold_duration` value.\n\nThe value for this property must be in the local time for the experience with no time zone information, following the [ISO 8601 standard](https://www.iso.org/iso-8601-date-and-time-format.html).\n",
"example": "2024-04-22T12:42:37Z",
"format": "date-time",
"type": "string"
},
"hold_id": {
"description": "A randomly-generated UUID. The same `hold_id` value must be used when testing the booking confirmation webhook.",
"format": "uuid",
"type": "string"
},
"option_id": {
"description": "The ID for an existing sandbox option.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"pickup_id": {
"description": "The ID for an existing sandbox pickup, if any.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"quantities": {
"description": "An array of the requested holder categories and their quantities.",
"items": {
"properties": {
"holder_category_id": {
"description": "The ID for an existing sandbox holder category.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"guide_language": {
"title": "Language",
"description": "The requested language.\n\nThis property must follow the [ISO 639-1 standard](https://www.iso.org/iso-639-language-codes.html).\n",
"type": "string"
},
"quantity": {
"description": "The quantity of pax.",
"minimum": 1,
"format": "int32",
"type": "integer"
}
},
"type": "object",
"required": [
"holder_category_id",
"quantity"
]
},
"type": "array",
"uniqueItems": true
},
"slot_id": {
"description": "The ID for an existing sandbox availability slot.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"type": "object",
"required": [
"experience_id",
"expiration_time",
"hold_id",
"option_id",
"quantities",
"slot_id"
]
}
}
}
}
},
"securitySchemes": {
"Supplier-production": {
"description": "This is the default security scheme a supplier must use when accessing PORTA in the **production** environment.",
"type": "oauth2",
"flows": {
"clientCredentials": {
"tokenUrl": "https://prod.api.tui/oauth2/token",
"scopes": {}
}
}
},
"Supplier-sandbox": {
"description": "This is the default security scheme a supplier must use when accessing PORTA in the **sandbox** environment.",
"type": "oauth2",
"flows": {
"clientCredentials": {
"tokenUrl": "https://prod.api.tui/oauth2/token",
"scopes": {}
}
}
},
"Webhook": {
"description": "This security scheme is used by PORTA when calling a supplier's webhook service.",
"type": "apiKey",
"in": "header",
"name": "x-webhook-key"
}
},
"parameters": {
"accept": {
"name": "accept",
"description": "Specify the format of the response.",
"in": "header",
"required": true,
"schema": {
"enum": [
"application/json"
],
"type": "string"
}
},
"accept-version": {
"name": "accept-version",
"description": "The version of PORTA for the request.",
"in": "header",
"required": true,
"schema": {
"title": "PORTA version",
"enum": [
"vnd.porta-api.v1"
],
"x-enumDescriptions": {
"vnd.porta-api.v1": "Version 1.0.0"
},
"type": "string"
}
},
"API-Key": {
"name": "API-Key",
"description": "The supplier's API key",
"in": "header",
"required": true,
"schema": {
"title": "API key",
"pattern": "^[a-zA-Z0-9-_\\.]{3,50}$",
"type": "string"
}
},
"experience_id": {
"name": "experience_id",
"description": "The experience ID.",
"in": "path",
"required": true,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"option_id": {
"name": "option_id",
"description": "The option ID.",
"in": "path",
"required": true,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"date_from": {
"name": "date_from",
"description": "Filters results to those which take place on or after the specified date.",
"in": "query",
"required": true,
"schema": {
"format": "date",
"type": "string"
}
},
"date_to": {
"name": "date_to",
"description": "Filters results to those which take place on or before the specified date.",
"in": "query",
"required": true,
"schema": {
"format": "date",
"type": "string"
}
},
"availability_slot_id": {
"name": "availability_slot_id",
"description": "The availability slot ID.",
"in": "path",
"required": true,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"vendor_id": {
"name": "vendor_id",
"description": "Filter results to those which belong to the specified vendor.",
"in": "query",
"required": false,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"mandatory_question_id": {
"name": "mandatory_question_id",
"description": "The mandatory question ID.",
"in": "path",
"required": true,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"pickup_id": {
"name": "pickup_id",
"description": "The pickup ID.",
"in": "path",
"required": true,
"schema": {
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"accept-version-webhook": {
"name": "accept-version",
"description": "The version of PORTA for the webhook request.",
"in": "header",
"required": true,
"schema": {
"title": "PORTA webhook version",
"enum": [
"vnd.porta-webhook-api.v1"
],
"x-enumDescriptions": {
"vnd.porta-webhook-api.v1": "Version 1.0.0"
},
"type": "string"
}
},
"x-webhook-key": {
"name": "x-webhook-key",
"description": "The key which allows the PORTA to access the supplier's webhook service.",
"in": "header",
"required": true,
"schema": {
"title": "Webhook key",
"type": "string"
}
}
},
"schemas": {
"DailySlot": {
"properties": {
"capacity": {
"description": "The remaining number of seats for the slot.",
"format": "int32",
"type": "integer"
},
"daily_slot": {
"title": "Daily slot",
"properties": {
"date": {
"description": "The date for the slot.",
"format": "date",
"type": "string"
}
},
"required": [
"date"
],
"type": "object"
}
},
"required": [
"daily_slot"
],
"type": "object"
},
"OpenSlot": {
"properties": {
"open_slot": {
"title": "Open slot",
"oneOf": [
{
"title": "Duration days",
"description": "Bookings are valid for a specified number of days after purchase.",
"properties": {
"duration_days": {
"description": "The number of days a booking is valid after purchase.",
"format": "int32",
"type": "integer"
},
"type": {
"description": "The type of open slot.",
"enum": [
"DURATION_DAYS"
],
"type": "string"
}
},
"required": [
"type",
"duration_days"
],
"type": "object"
},
{
"title": "End date",
"description": "Bookings are valid until a specified date.",
"properties": {
"end_date": {
"description": "The date when customers can no longer redeem their booking.",
"format": "date",
"type": "string"
},
"type": {
"description": "The type of open slot.",
"enum": [
"END_DATE"
],
"type": "string"
}
},
"required": [
"end_date",
"type"
],
"type": "object"
}
]
}
},
"required": [
"open_slot"
],
"type": "object"
},
"TimeSlot": {
"properties": {
"capacity": {
"description": "The remaining number of seats for the slot.",
"format": "int32",
"type": "integer"
},
"time_slot": {
"title": "Time slot",
"properties": {
"end": {
"description": "The date and time the experience ends. If the experience duration is not well defined, suppliers can use the same value as the `start` property.\n\nThe value for this property must be in the local time for the experience with no time zone information, following the [ISO 8601 standard](https://www.iso.org/iso-8601-date-and-time-format.html).\n",
"example": "2023-04-22T20:00:00Z",
"format": "date-time",
"type": "string"
},
"pickup_ids": {
"title": "Pickups",
"description": "A list of IDs for pickups available for this time slot.",
"items": {
"title": "Pickup IDs",
"type": "string"
},
"type": "array",
"uniqueItems": true
},
"start": {
"description": "The date and time the experience starts.\n\nThe value for this property must be in the local time for the experience with no time zone information, following the [ISO 8601 standard](https://www.iso.org/iso-8601-date-and-time-format.html).\n",
"example": "2023-04-22T18:00:00Z",
"format": "date-time",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object"
}
},
"type": "object",
"required": [
"time_slot"
]
},
"AvailableHolderCategory": {
"title": "Holder category",
"properties": {
"holder_category_id": {
"description": "The holder category ID, assigned by the supplier.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"max_quantity": {
"description": "The maximum quantity allowed per booking.",
"format": "int32",
"type": "integer"
},
"min_quantity": {
"description": "The minimum quantity required for a valid booking.",
"format": "int32",
"type": "integer"
},
"price_in_cents": {
"description": "The holder category price in cents.",
"format": "int64",
"type": "integer"
}
},
"required": [
"holder_category_id",
"price_in_cents"
],
"type": "object"
},
"AvailabilitySlotGeneric": {
"title": "Availability generic slot",
"properties": {
"available_holder_categories": {
"title": "Holder categories",
"description": "Holder categories for the slot.",
"items": {
"$ref": "#/components/schemas/AvailableHolderCategory"
},
"type": "array",
"uniqueItems": true
},
"guide_languages": {
"title": "Languages",
"description": "A list of languages which can be booked for the slot. The languages will appear for *all* available holder categories in the slot.\n\nThis property must follow the [ISO 639-1 standard](https://www.iso.org/iso-639-language-codes.html).\n",
"items": {
"title": "Language code",
"type": "string"
},
"type": "array",
"uniqueItems": true
},
"option_id": {
"description": "The ID of the option that the slot belongs to.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"slot_id": {
"description": "The availability slot ID, assigned by the supplier.\n\nThe ID must be unique. The same ID cannot be re-used for different experiences.\n",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"required": [
"available_holder_categories",
"option_id",
"slot_id"
],
"type": "object"
},
"AvailabilitySlot": {
"title": "Availability slot",
"allOf": [
{
"oneOf": [
{
"allOf": [
{
"title": "Daily slot"
},
{
"$ref": "#/components/schemas/DailySlot"
}
]
},
{
"allOf": [
{
"title": "Open slot"
},
{
"$ref": "#/components/schemas/OpenSlot"
}
]
},
{
"allOf": [
{
"title": "Time slot"
},
{
"$ref": "#/components/schemas/TimeSlot"
}
]
}
]
},
{
"$ref": "#/components/schemas/AvailabilitySlotGeneric"
}
],
"required": [
"available_holder_categories",
"option_id",
"slot_id",
"start"
],
"type": "object"
},
"ErrorResponse": {
"title": "Error response",
"example": {
"id": "3ecae132-a32d-41f9-8f7d-586f34cc29ce",
"code": "0",
"message": "There was an error"
},
"properties": {
"code": {
"description": "The internal code for the error.",
"type": "string"
},
"id": {
"description": "The ID of the error to use for tracking.",
"format": "uuid",
"type": "string"
},
"message": {
"description": "A message with a brief explanation of the error.",
"type": "string"
}
},
"required": [
"code",
"id"
],
"type": "object"
},
"AvailabilitySlotDaily": {
"title": "Availability daily slot",
"allOf": [
{
"$ref": "#/components/schemas/AvailabilitySlotGeneric"
},
{
"$ref": "#/components/schemas/DailySlot"
}
],
"required": [
"available_holder_categories",
"daily_slot",
"option_id",
"slot_id"
],
"type": "object"
},
"AvailabilityOpenSlot": {
"title": "Availability open slot",
"allOf": [
{
"$ref": "#/components/schemas/AvailabilitySlotGeneric"
},
{
"$ref": "#/components/schemas/OpenSlot"
}
],
"required": [
"available_holder_categories",
"open_slot",
"option_id",
"slot_id"
],
"type": "object"
},
"AvailabilityTimeSlot": {
"title": "Availability time slot",
"allOf": [
{
"$ref": "#/components/schemas/AvailabilitySlotGeneric"
},
{
"$ref": "#/components/schemas/TimeSlot"
}
],
"required": [
"available_holder_categories",
"option_id",
"slot_id",
"time_slot"
],
"type": "object"
},
"HolderCategory": {
"title": "Holder category",
"properties": {
"default_category": {
"description": "When `true` the holder category appears first in lists.\n\nIf no holder category is defined as the default, then the holder category with a `holder_type` value of `ADULT` is automatically made the default. If no adult holder categories are available, then the first holder category is automatically made the default.\n",
"type": "boolean"
},
"holder_category_id": {
"description": "The holder category ID, assigned by the supplier.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
},
"holder_type": {
"description": "The type of holder category.\n\nPlease note that usage of the `CUSTOM*` holder type requires approval from the PORTA team.\n",
"enum": [
"ADULT",
"CHILD",
"CUSTOM*",
"FAMILY",
"GROUP",
"INFANT",
"MILITARY",
"REGULAR",
"SENIOR",
"STUDENT",
"YOUTH"
],
"type": "string"
},
"maximum_age": {
"description": "The maximum age customers can have to qualify for the holder category.",
"format": "int32",
"type": "integer"
},
"minimum_age": {
"description": "The minimum age customers must have to qualify for the holder category.",
"format": "int32",
"type": "integer"
}
},
"required": [
"holder_category_id",
"holder_type",
"minimum_age"
],
"type": "object"
},
"Option": {
"title": "Option",
"properties": {
"holder_categories": {
"description": "The holder categories for the option.",
"items": {
"$ref": "#/components/schemas/HolderCategory"
},
"type": "array",
"uniqueItems": true
},
"label": {
"description": "The human-friendly label for the option.",
"type": "string"
},
"main_option": {
"description": "When `true`, the main option appears first in the list of options.\n\nIf no option is defined as the default, then the first option is automatically made the default.\n",
"type": "boolean"
},
"max_booking_quantity": {
"description": "The maximum quantity allowed per booking.",
"format": "int32",
"type": "integer"
},
"min_booking_quantity": {
"description": "The minimum quantity required for a valid booking.",
"format": "int32",
"type": "integer"
},
"option_id": {
"description": "The option ID, assigned by the supplier.",
"pattern": "^(?!\\-|\\.|\\_)[0-9a-z\\-\\.\\_]{1,50}$",
"type": "string"
}
},
"required": [
"holder_categories",
"label",
"option_id"
],
"type": "object"
},
"Experience": {
"title": "Experience",
"properties": {
"archived": {
"description": "When an experience is archived, it is no longer for sale in Musement sites.\n\nWhen an experience is un-archived, a member of the *Content Supplier Connectivity* team is required to un-archive the corresponding business platform activity.\n",
"default": false,
"type": "boolean"
},
"availability_slot_type": {
"description": "The type of availability slot for the experience.",
"enum": [
"DAILY",
"OPEN",
"TIME"
],
"type": "string",
"x-enumDescriptions": {
"DAILY": "Customers must select a date for their booking. They do not select a time.",
"OPEN": "Customers do not select a date or time. Their booking expires on a set date or a set number of days after purchase.",
"TIME": "Customers must select a date and time for their booking."
}
},
"currency": {
"description": "The currency to use for billing.\n\nThis property must follow the [ISO 4217 standard](https://www.iso.org/iso-4217-currency-codes.html).\n",
"format": "currency",
"type": "string"
},
"cutoff_time": {
"default": "P0D",
"description": "The minimum amount of time required to book a travel date in advance.\n\nThis property must follow the [ISO 8601 standard](https://www.iso.org/iso-8601-date-and-time-format.html).\n",
"format": "duration",
"type": "string"
},
"experience_id": {