NAV
json php

Introduction

ExperienceBank API consists of the following sections: Partner API, Public API, Notification API, Distributor API and Webhook API.

Partner API needs to be implemented on Partner's side. ExperienceBank will use these endpoints to pull Content and push bookings and cancellations.

Public API should be used by clients to create/enable/disable suppliers in ExperienceBank, get list of supported Marketplaces, enable/disable marketplace mappings, etc.

Notification API should be used to notify ExperienceBank about changes in Partner's system.

Distributor API should be used by Distributors to get all Content and push bookings and cancellations.

Webhook API allows getting notifications about different events in a real time.

Partner API

This API has to be implemented on Partner side. ExperienceBank will call this API to get Activities and Availabilities and push and cancel bookings on your platform.

All response bodies are JSON and all request bodies are expected to be JSON.

Required notifications to be implemented on your side are:

Authorization

All requests must contain a valid Authorization header authenticating the client and proving the integrity of the request.

ExperienceBank uses public keys and message signing to authenticate clients. A ExperienceBank representative will give you your own public and secret keys.

Clients must send an Authorization header in the following format:

Authorization: "Basic " + BASE64($PUBLICKEY + ":" + HMAC_SHA256(BASE64($REQUESTID), $SECRETKEY))

$PUBLICKEY - The client's public key, e.g. pub_b0f41d7fe0e51ea45018358df7f1e12d09580053c3

$SECRETKEY - The client's secret key, e.g. sec_dacd7d383558188d90c6d0b8bdc36a9b028500c6f3

$REQUESTID - Header's X-REQUEST-IDENTIFIER value, e.g. 6da9ef63-5593-48cd-b088-efaef26104fe

Activities

Example Response

{
  "links": {
    "next": "https://example.com/supplier/1234/activities?offset=50"
  },
  "data": [
    {
      "id": "48016",
      "title": "The Best of Zürich City Tour",
      "description": "Discover this unique city, several times winner of the award "City with the world's best quality of life" and see its different faces. During the journey you will pass by the "Must see" of the beautiful town.\r\n\r\nDeparture point: \r\nSihlquai Coach Parking - Bus parking near Main Station.\r\nwww.switzerland-tours.ch/travelinfos\r\n\r\nCheck-In: \r\nPlease check-in at our ticket office marked with "Best of Switzerland Tours" at the latest 15 minutes prior to departure.",
      "highlights": "",
      "itinerary": "<p>Pass by the castle-like National Museum, the well-known&nbsp;shopping avenue Bahnhofstrasse&nbsp;and Z&uuml;rich&#39;s famous&nbsp;financial district. Picture stop at the port of &quot;Enge&quot; where you enjoy beautiful vistas of the crystal-clear&nbsp;Lake Z&uuml;rich. Continue along the lake, passing by the renowned Opera House to the &quot;Z&uuml;richberg&quot; district with many superb mansions of glorious past times. A great experience is the ride uphill by&nbsp;cogwheel train&nbsp;(Dolderbahn) to a&nbsp;viewpoint&nbsp;where the noble five-star Grand Hotel Dolder is located. Enjoy breath-taking views of the city, the lake and the snow-covered Alps. Cruising the&nbsp;university quarter, you see the Swiss Federal Institute of Technology (ETH), the University of Z&uuml;rich and Z&uuml;rich&#39;s art museum before reaching the&nbsp;charming Old Town. The last picture stop of this versatile excursion offers views of the patriarchal guild houses, the St. Peter church with Europe&#39;s largest clock-face, the Grossm&uuml;nster church and the Fraum&uuml;nster church with the famous stained glass windows by Marc Chagall. After a short walk through the Old Town, the tour ends here or with a scenic drive back on&nbsp;Limmatquai&nbsp;at Sihlquai bus parking.</p>\r\n\r\n<p>&nbsp;</p>",
      "detailsPageUrl": "https://awesome.com/cool-activity-url",
      "language": "en",
      "inclusions": ["Drinks"],
      "exclusions": ["Lunch"],
      "importantInfo": ["Alcoholic beverages are only for guests aged 18 or older. Photo ID is required for all passengers consuming alcoholic beverages."],
      "destination": {
        "countryCode": "CH",
        "code": "ZRH",
        "name": "Zürich"
      },
      "media": {
        "images": {
          "header": "https://cdn.something.com/234o9234/12342009.png",
          "teaser": "https://cdn.something.com/234o9234/12342002.png",
          "gallery": [
            "https://cdn.something.com/234o9234/12342003.png",
            "https://cdn.something.com/234o9234/12342004.png",
            "https://cdn.something.com/234o9234/12342005.png"
          ]
        },
        "videos": [
          "//youtu.be/CIrttJhJCqM",
          "//youtu.be/CIrttJhJCq1"
        ]
      },
      "rating" : {
        "averageValue": 4.8,
        "totalCount": 1067
      },
      "meetingPoints": [
        {
          "name": "Zürich",
          "latitude": "47.376887",
          "longitude": "8.541694",
          "address": "100/F, International Commerce Centre"
        }
      ],
      "route": [
        {
          "name": "Zürich",
          "latitude": "47.376887",
          "longitude": "8.541694"
        }
      ],
      "categories": ["1", "5", "10"],
      "guestFields": [
        {
          "code": "gender",
          "label": "Gender",
          "type": "radio",
          "required": false,
          "options": [
            {
              "key": "m",
              "value": "Male",
              "translations": [
                {
                  "language": "be",
                  "value": "Мужчына"
                }
              ]
            },
            {
              "key": "f",
              "value": "Female",
              "translations": [
                {
                  "language": "be",
                  "value": "Жанчына"
                }
              ]
            }
          ],
          "translations": [
            {
              "language": "be",
              "label": "Пол"
            }
          ]
        },
        {
          "code": "email",
          "label": "Email",
          "type": "text",
          "required": true,
          "options": null,
          "translations": [
            {
              "language": "be",
              "label": "Емэйл"
            }
          ]
        }
      ],
      "addons": [
        {
          "id": "3457",
          "title": "T-shirt",
          "type": "guest",
          "description": "T-shirt with funny picture on it",
          "price": {
            "amount": "10.00",
            "currency": "USD"
          },
          "translations": [
            {
              "language": "be",
              "title": "Цiшотка",
              "description": "Цiшотка з малюнкам"
            }
          ]
        }
      ],
      "isActive": true,
      "cancellationPolicy": {
        "isFreeCancellation": false,
        "refundConditions": [
          {
            "minDurationBeforeStartTimeSec": 604800,
            "refundPercentage": 50
          },
          {
            "minDurationBeforeStartTimeSec": 172800,
            "refundPercentage": 100
          }
        ]
      },
      "options": [
        {
          "id": "42964496428-0900",
          "name": "The Best of Zürich City Tour B2  APR 18 - MAR 19 (English)",
          "duration": "PT3H",
          "startTime": "00:00:00",
          "openingHours": [
            {
              "fromTime": "09:00:00",
              "toTime": "20:30:00"
            }
          ],
          "fromDate": "2018-01-15",
          "untilDate": "2019-03-01",
          "cutOff": 1440,
          "weekdays": [
            "mon",
            "sun"
          ],
          "canBeBookedAfterStartTime": false,
          "ticketCategories": [
            {
              "id": "12342",
              "name": "Adult",
              "minSeats": 1,
              "maxSeats": 1,
              "price": {
                "type": "fixed",
                "amount": "49.00",
                "currency": "EUR"
              },
              "type": "Adult",
              "ageLimit": {
                "minAge": 18,
                "maxAge": 65
              },
              "translations": [
                {
                  "language": "be",
                  "name": "Дарослы"
                }
              ]
            },
            {
              "id": "CHILD",
              "name": "Child",
              "minSeats": 1,
              "maxSeats": 1,
              "price": {
                "type": "fixed",
                "amount": "20.00",
                "currency": "EUR"
              },
              "type": "Child",
              "ageLimit": {
                "minAge": 6,
                "maxAge": 17
              },
              "translations": [
                {
                  "language": "be",
                  "name": "Дзiцячы"
                }
              ]
            },
            {
              "id": "12346",
              "name": "GROUP 2-10",
              "minSeats": 2,
              "maxSeats": 10,
              "price": {
                "type": "variable",
                "amount": "200.00",
                "currency": "EUR"
              },
              "type": "Group",
              "ageLimit": null,
              "translations": [
                {
                  "language": "be",
                  "name": "Група (2-10)"
                }
              ]
            }
          ],
          "translations": [
            {
              "language": "be",
              "name": "Цюрых: Лепшае"
            }
          ]
        },
        {
          "id": "42964496428-1000",
          "name": "The Best of Zürich City Tour B2  APR 18 - MAR 19 (English)",
          "duration": "PT3H",
          "startTime": "10:00:00",
          "openingHours": [],
          "fromDate": "2018-01-15",
          "untilDate": "2019-03-01",
          "cutOff": 0,
          "weekdays": [
            "fri",
            "sat"
          ],
          "canBeBookedAfterStartTime": true,
          "ticketCategories": [
            {
              "id": "12342",
              "name": "Adult",
              "minSeats": 1,
              "maxSeats": 1,
              "price": {
                "type": "fixed",
                "amount": "49.00",
                "currency": "EUR"
              },
              "type": "Adult",
              "ageLimit": {
                "minAge": 18,
                "maxAge": 65
              },
              "translations": [
                {
                  "language": "be",
                  "name": "Дарослы"
                }
              ]
            },  
            {
              "id": "123461",
              "name": "GROUP 1-5",
              "minSeats": 1,
              "maxSeats": 5,
              "price": {
                "type": "fixed",
                "amount": "150.00",
                "currency": "EUR"
              },
              "type": "Group",
              "ageLimit": null,
              "translations": [
                {
                  "language": "be",
                  "name": "Група"
                }
              ]
            }
          ],
          "translations": [
            {
              "language": "be",
              "name": "Цюрых: Лепшае"
            }
          ]
        }   
      ],
      "translations": [
        {
          "language": "de",
          "title": "Stadtrundfahrt: Das Beste von Zürich",
          "description": "Beschreibung: Entdecken Sie Zürich, wichtigster wirtschaftlicher und kultureller Standort der Schweiz und mehrfach als \"Stadt mit der höchsten Lebensqualität\" ausgezeichnet, auf dieser 2-stündigen, klassischen Stadtrundfahrt. Während der Fahrt im komfortablen, klimatisierten Reisebus zeigt Ihnen Ihre versierte Reiseleitung die bedeutendsten Sehenswürdigkeiten dieser bezaubernden Stadt. Abfahrtsort: Zürich Sihlquai Carparkplatz hinter dem Zürich Hauptbahnhof (HB) Detaillierte Beschreibung: www.switzerland-tours.ch/de/reiseinformationen/abfahrtsort Check-In: Wir bitten Sie, sich spätestens 15 Minuten vor Abfahrt bei unseren Mitarbeitern am Abfahrtsort zu melden.",
          "highlights": "",
          "itinerary": "Geniessen Sie die Fahrt vorbei am schlossähnlichen Landesmuseum, dem Hauptbahnhof, der luxuriösen Einkaufsmeile Bahnhofstrasse und Zürichs Zentrum für Finanz und Wirtschaft. Nach einem ersten Fotostop am malerischen Zürichseefolgen Sie dem See über die Quaibrücke und vorbei am berühmten Opernhaus. Anschliessend Fahrt mit der Dolder-Zahnradbahn ins Zürichbergquartier mit seinen Villen aus vergangenen Zeiten und dem renommierten 5-Sterne Hotel The Dolder Grand. Geniessen Sie die einmalige Aussicht auf die Stadt, den See und die schneebedeckten Berge. Auf der Weiterfahrt durch das Universitätsviertel sehen Sie die Eidgenössische Technische Hochschule (ETH), die Universität sowie das Kunsthaus Zürich und erreichen dann die charmante Altstadt. Der letzte Fotostopp der abwechslungsreichen Tour bietet Aussicht auf die patriarchalen Zunfthäuser, die Kirche St. Peter mit dem grössten Kirchenzifferblatt Europas, das Grossmünster und das Fraumünster mit seinen berühmten Farbfenstern von Marc Chagall. Nach einem kurzen Altstadtbummel endet die Tour hier oder mit einer malerischen Fahrt entlang des Limmatquais am Sihlquai Busparkplatz. Inklusiv: -Geführte Tour in Deutsch und Englisch -Audioguides: Chinesisch, Japanisch, Russisch und Spanisch -Busfahrt im komfortablen Reisebus -Zahnradbahnfahrt Exklusiv: -Essen -Getränke -Persönliche Ausgaben"
          "inclusions": ["Getränke"],
          "exclusions": ["Mittagessen"],
          "importantInfo": ["Alkoholische Getränke sind nur für Gäste ab 18 Jahren. Für alle Passagiere, die alkoholische Getränke konsumieren, ist ein Lichtbildausweis erforderlich."]
          "detailsPageUrl": "https://awesome.com/de/cool-activity-url"
        }
      ]
    }
  ]
}

Example Error Response

{
  "errors": [
    {
      "status": "500",
      "code": "InternalServerError",
      "title": "Internal Server Error",
      "details": "Something went wrong"
    }
  ]
}

HTTP Request

GET /supplier/{partnerSupplierId}/activities?id[0]=48016

Path

Parameter Type Required Description
partnerSupplierId string yes Internal Partner Supplier ID. This ID will be provided to ExperienceBank by Partner

Query

Parameter Type Required Description
id array no Array of supplier’s activities IDs. If IDs not specified endpoint should return all activities

Response

Name Type Required Description
links
object
yes Links object
  next string, null yes Link to the next data batch. Can be null if all data was returned. ExperienceBank will use this link to request next batch of data so this link must be a valid URL
data array yes Array of activities
  id string yes Activity Id
  title string yes Activity Title
  description string yes Activity Description. Can contain HTML
  highlights string yes Activity Highlights. Can contain HTML
  itinerary string yes Activity Itinerary. Can contain HTML
  language string yes Activity language
  inclusions array yes Array of items that are included in the activity. Can be empty array []
  exclusions array yes Array of items that are excluded in the activity. Can be empty array []
  importantInfo array yes Array of items that are important to know before the activity. Can be empty array []
  detailsPageUrl string yes Activity details page url
  destination object yes Object contains information about Activity destination
    countryCode string yes Destination country code
    code string yes Destination code
    name string yes Destination name
  media object yes Object contains information about media resources (images, videos)
    images object yes Object contains information about header, teaser and gallery images
      header string, null yes Header image url. Can be null
      teaser string, null yes Teaser image url . Can be null
      gallery array yes Array of image urls. Can be empty array []
    videos array yes Array of videos urls. Can be empty array []
  rating object, null yes Object contains information about Activity rating
    averageValue float yes Rating average value
    totalCount integer yes Total count of ratings
  categories array yes Activity categories. Maximum possible is 3 categories. Can be empty array []. Please check available categories here
  meetingPoints array yes Array of meeting points points. Can be empty array [] if not supported
    name string yes Meeting point name
    latitude string yes Meeting point latitude
    longitude string yes Meeting point longitude
    address string yes Meeting point address
  route array yes Array of route points. Can be empty array [] if not supported
    name string yes Route point name
    latitude string yes Route point latitude
    longitude string yes Route point longitude
  guestFields array yes Array of activity guest fields. Can be empty array [] if not supported
    code string yes Guest field code
    label string yes Guest field label
    type string yes Guest field type. Can be radio, text, select, etc
    required boolean yes Is guest field required?
    options array yes Array of options if available. Some types like radio or select can have options.
      key string yes Guest field option key
      value string yes Guest field option value
      translations array yes Array of translations. Can be empty array [] if not supported
        language string yes Translation language
        value string yes Value Translation
    translations array yes Array of translations. Can be empty array [] if not supported
      language string yes Translation language
      label string yes Label Translation
  addons array yes Array of activity addons
    id string yes Addon Id
    title string yes Addon Title
    description string yes Addon Description
    type string yes Addon Type. Can be guest or item. Depends on this value addon will be added on guest or booking item level on booking request.
    price object yes Addon Price Information
      amount string yes Addon Price amount
      currency string yes Addon Price currency
    translations array yes Array of translations. Can be empty array [] if not supported
      language string yes Translation language
      title string yes Title Translation
      description string yes Description Translation
  isActive boolean yes Is activity active
  cancellationPolicy object, null yes Object contains information about refund conditions
    isFreeCancellation boolean yes Whether is free cancellation or not
    refundConditions array yes Array of refund conditions. Can be []
      minDurationBeforeStartTimeSec int yes Duration in seconds before the start time, until when the customer can receive a refund for part of the activity's cost specified in refundPercentage. When set to 0 (default), the activity can be cancelled at any time.
      refundPercentage int yes The percent that can be refunded, as long as the activity booking is cancelled at least minDurationBeforeStartTimeSec before the activity start time, in the range of [0, 100]. When set to 0 (default), the activity is not refundable. When set to 100 this activity is fully refundable
  options array yes Array of activity options
    id string yes Option Id
    name string yes Option name
    duration string yes Option duration. Has PnYnMnDTnHnMnS format, e.g. P1D. More details
    startTime string yes Option start time. Has hh:mm:ss format, e.g. 09:00:00. More details If an option has opening hours start time must be 00:00:00
    openingHours array yes Array of opening hours. Can be empty array [] if has a specific start time
      fromTime string yes From time. Has hh:mm:ss format, e.g. 09:00:00. More details
      toTime string yes To time. Has hh:mm:ss format, e.g. 17:00:00. More details
    fromDate string yes Option from date. Has YYYY-MM-DD format, e.g. 2018-12-10. More details
    untilDate string yes Option until date. Has YYYY-MM-DD format, e.g. 2018-12-10. More details
    cutOff integer yes Minutes before activity start when bookings are not allowed
    weekdays array yes Array of weekdays when activity is available. Possible values: mon, tue, wed, thu, fri, sat, sun. Can be empty [] if option is not recurrent.
    canBeBookedAfterStartTime boolean yes If true then this option can be booked after its start time, f.e. if option start time is 09:00:00 it can be booked at 10:00:00 or 11:00:00 and so on. Works for museums, etc
    ticketCategories array yes Array of option ticket categories
      id string yes Ticket Category Id
      name string yes Ticket Category name
      minSeats integer yes Minimum seats required to book this ticket category
      maxSeats integer yes Maximum seats allowed to book this ticket category. If it is a single seat ticket with one ticket code it should be 1. If it is more than 1 f.e. 5 we assume that no matter how many spots were booked 2 or 5 this ticket will have only 1 ticket code (QR Code, Barcode, etc) which means it is a GROUP ticker
      price object yes Ticket Category price information
        type string yes Can be fixed or variable. If fixed total amount for booked guests will be price of this ticket category. If variable - price will be multiplied by guests count, e.g. if ticket category Adult has fixed price 100 EUR and 5 guests were booked total price will be still 100 EUR. If it had variable price type total price would be 500 EUR
        amount string yes Price amount
        currency string yes Price currency
      type string yes Ticket Category type. Can be empty string "". Supported types: Adult, Child, Infant, Senior, Youth, Student, Military, Group, Traveller, Family, Transfer, Room, Other
      ageLimit object, null yes Ticket Category age limit. Can be null
        minAge integer yes Age limit minimum age
        maxAge integer yes Age limit maximum age
      translations array yes Array of translations. Can be empty array [] if not supported
        language string yes Translation language
        name string yes Name Translation
    translations array yes Array of translations. Can be empty array [] if not supported
      language string yes Translation language
      name string yes Name Translation
  translations array yes Array of translations. Can be empty array [] if not supported
    language string yes Translation language
    title string yes Translation Activity Title
    description string yes Translation Activity Description. Can contain HTML
    highlights string yes Translation Activity Highlights. Can contain HTML
    itinerary string yes Translation Activity Itinerary. Can contain HTML
    inclusions array yes Array of items that are included in the activity. Can be empty array []
    exclusions array yes Array of items that are excluded in the activity. Can be empty array []
    importantInfo array yes Array of items that are important to know before the activity. Can be empty array []
    detailsPageUrl string yes Details page url for a specific language

Error

Name Type Required Description
errors array yes Array of errors
  status string yes Error status
  code string yes Error code
  title string yes Error title
  details string, null yes Error details

Availabilities

Example Response

{
  "links": {
    "next": "https://example.com/supplier/1234/availabilities?offset=50&dateRangeStart=2018-05-14&dateRangeEnd=2019-05-30"
  },
  "data": [
    {
      "dateTime": "2018-01-16T09:00:00+02:00",
      "openingHours": [],
      "availableCapacity": 10,
      "maximumCapacity": 20,
      "activityId": "1000",
      "optionId": "40000",
      "ticketCategories" : [
        {
          "id" : "345343",
          "availableCapacity": 10
        },
        {
          "id" : "445353",
          "availableCapacity": 0
        },
        {
          "id" : "645653",
          "availableCapacity": null
        }
      ]
    },
    {
      "dateTime": "2018-01-17T00:00:00+02:00",
      "openingHours": [
        {
          "fromTime": "09:00:00",
          "toTime": "20:30:00"
        }
      ],
      "availableCapacity": 10,
      "maximumCapacity": 20,
      "activityId": "2000",
      "optionId": "50000",
      "ticketCategories" : [
        {
          "id" : "345343",
          "availableCapacity": 10
        },
        {
          "id" : "445353",
          "availableCapacity": 0
        },
        {
          "id" : "645653",
          "availableCapacity": null
        }
      ]
    }
  ]
}

Example Error Response

{
  "errors": [
    {
      "status": "500",
      "code": "InternalServerError",
      "title": "Internal Server Error",
      "details": "Something went wrong"
    }
  ]
}

HTTP Request

GET /supplier/{partnerSupplierId}/availabilities?dateRangeStart=2018-12-11&dateRangeEnd=2019-12-11&activityId[0]=14587&optionId[0]=478799789-0900&optionId[1]=4789875259-1000

Path

Parameter Type Required Description
partnerSupplierId string yes Internal Partner Supplier ID. This ID will be provided to ExperienceBank by Partner

Query

Parameter Type Required Description
dateRangeStart string yes Start date of date range. Has YYYY-MM-DD format, e.g. 2018-12-10. More details
dateRangeEnd string yes End date of date range. Has YYYY-MM-DD format, e.g. 2019-12-10. More details
activityId array no Array of activity ids. Can be omitted
optionId array no Array of option ids. Can be omitted

Response

Name Type Required Description
links
object
yes Links object
  next string, null yes Link to the next data batch. Can be null if all data was returned. ExperienceBank will use this link to request next batch of data so this link must be a valid URL
data array yes Array of availabilities
  dateTime string yes The date/time of the activity using the ISO 8601 datetime format (e.g. 2018-12-11T14:00:00+02:00). We always expect the local time with its UTC offset. In case if there is no a specific start time, provide 00:00:00 as a start time (e.g. 2018-12-11T00:00:00+02:00).
  openingHours array yes Array of opening hours. Can be empty array [] if has a specific start time
    fromTime string yes From time. Has hh:mm:ss format, e.g. 09:00:00. More details
    toTime string yes To time. Has hh:mm:ss format, e.g. 17:00:00. More details
  availableCapacity integer yes Available capacity
  maximumCapacity integer yes Maximum capacity
  activityId string yes Activity Id
  optionId string yes Option Id
  ticketCategories array yes Array of ticket categories available capacities. Can be empty [] if available capacities by ticket categories not supported. If you have availability limitations by ticket category and a ticket category doesn't have availabilities for specified date or was blocked you need to return 0 for this ticket category because if you don't provide this information we will check availableCapacity on availability level only
    id string yes Ticket category id
    availableCapacity integer, null yes Ticket category available capacity. Can be null if not applicable. In this case we will treat as no limitation by ticket category

Error

Name Type Required Description
errors array yes Array of errors
  status string yes Error status
  code string yes Error code
  title string yes Error title
  details string, null yes Error details

Create Booking

Example Request

{
  "data": {
    "bookingId": "boo_35b4951f-644a-4af6-85ce-c02209598f61",
    "reservationReference": "",
    "bookingItems": [
      {
        "date": "2018-01-20",
        "optionId": "434131423412-0900",
        "guests": [
          {
            "firstName": "John",
            "lastName": "Doe",
            "email": "john.doe@example.com",
            "phoneNumber": "+474998799654",
            "occupancy": 1,
            "ticketId": "tic_b830ab21-4d83-45cc-809e-a4b436c7ad93",
            "ticketCategory": "123422",
            "additionalFields": [
              {
                "key": "gender",
                "value": "m"
              },
              {
                "key": "nationality",
                "value": "BY"
              }
            ],
            "addons" : [
              {
                "id": "642342",
                "quantity": 1
              }
            ]
          },
          {
            "firstName": "",
            "lastName": "",
            "email": "",
            "phoneNumber": "",
            "occupancy": 1,
            "ticketId": "tic_b8565c12-2195-4dab-9e5a-06c74dd1fcd3",
            "ticketCategory": "123422",
            "additionalFields": [],
            "addons": []
          },
          {
            "firstName": "",
            "lastName": "",
            "email": "",
            "phoneNumber": "",
            "occupancy": 1,
            "ticketId": "tic_bfeb1422-2c89-4dde-a4f0-c10cd9d3a092",
            "ticketCategory": "123422",
            "additionalFields": [],
            "addons": []
          }
        ],
        "addons" : [
            {
              "id": "842348",
              "quantity": 5
            }
        ]
      }
    ],

    "marketplace": {
      "id": "mar_22550105-a751-4e65-88f4-9ff47d335652",
      "bookingId": "7902023020232021"
    },
    "contact": {
      "fullName": "John Doe",
      "email": "john.doe@example.com",
      "phoneNumber": "+474998799654"
    },
    "payment": {
      "amount": "100.00",
      "currency": "EUR"
    },
    "language": "en",
    "notes": "Some additional remarks related to the booking"
  }
}

Example Response

{
  "data": {
    "partnerBookingId": "11000232",
    "tickets": [
      {
        "ticketId": "tic_34383d4e-59c7-456a-b60a-ad1bacb4bb37",
        "partnerTicketId": "GUE-13981214-12888383",
        "partnerTicketCode": "XZD1UH4W4B",
        "partnerTicketCodeType": "QR_CODE"
      },
      {
        "ticketId": "tic_0ff829b5-7060-4bec-83eb-21e4310ef287",
        "partnerTicketId": "GUE-13981214-12888384",
        "partnerTicketCode": "PJ7WO7NHPV",
        "partnerTicketCodeType": "QR_CODE"
      },
      {
        "ticketId": "tic_34cf83d4e-59c7-456a-b60a-ad1bacb4bb37",
        "partnerTicketId": "GUE-13981214-12888385",
        "partnerTicketCode": "UTKO3J6CSK",
        "partnerTicketCodeType": "QR_CODE"
      }
    ]
  }
}

Example Error Response

{
  "errors": [
    {
      "status": "500",
      "code": "InternalServerError",
      "title": "Internal Server Error",
      "details": "Something went wrong"
    }
  ]
}

HTTP Request

POST /supplier/{partnerSupplierId}/booking

Path

Parameter Type Required Description
partnerSupplierId string yes Internal Partner Supplier ID. This ID will be provided to ExperienceBank by Partner

Body

Parameter Type Required Description
data
object
yes Request data
  bookingId string yes Booking Id from ExperienceBank system
  reservationReference string, null no Reservation Reference from Partner System. Will be set only if Create Reservation endpoint implemented and used. Will have value from Create Reservation endpoint response. Can be null or empty ""
  bookingItems array yes Array of Booking Items
    date string yes Activity/Trip date. Has YYYY-MM-DD format, e.g. 2018-12-10. More details
    optionId string yes Option Id
    guests array yes Array of guests
      firstName string yes Guest first name. Can be empty ""
      lastName string yes Guest last name. Can be empty ""
      email string yes Guest email. Can be empty ""
      phoneNumber string yes Guest phone number. Can be empty ""
      occupancy integer yes Guest occupancy. Cannot be less than 1
      ticketId string yes ExperienceBank ticket id. This value will be send to Marketplaces and can be used as QR code so if your system supports QR code validation it should support ExperienceBank ticket ids as well as they might be printed on Marketplace vouchers
      ticketCategory string yes Ticket category id
      additionalFields array yes Array of additional fields. Can be empty []
        key string yes Additional field key
        value string yes Additional field value
      addons array yes Array of addons on guest level. Can be empty []
        id string yes Addon id
        quantity string yes Addon quantity
    addons array yes Array of addons on booking item level. Can be empty []
      id string yes Addon id
      quantity string yes Addon quantity
  marketplace object yes Marketplace info
    id string yes Marketplace id from ExperienceBank system:
Expedia: mar_7485d4af-a1dd-4822-9568-553f27c744c7
GetYourGuide: mar_a8b6748e-8e7c-407c-91e0-4d985227ef30
Viator: mar_9ab1e224-f170-4989-a208-1d54497d4673
    bookingId string yes Marketplace booking id
  contact object yes Contact info
    fullName string, null yes Contact full name. Can be null
    email string, null yes Contact email. Can be null
    phoneNumber string, null yes Contact phone number. Can be null
  payment object, null yes Payment info. Can be null
    amount string, null yes Payment amount
    currency string, null yes Payment currency
  notes string, null yes Booking notes. Can be null
  language string, null no Customer's language. Can be null

Response

Name Type Required Description
data
object
yes Response data
  partnerBookingId string yes Booking Id from Partner System
  tickets array yes Tickets array
    ticketId string yes Ticket id from ExperienceBank system
    partnerTicketId string yes Ticket id from Partner system
    partnerTicketCode string yes Ticket code from Partner system. This code can be printed on a Marketplace voucher in a format provided in partnerTicketCodeType
    partnerTicketCodeType string yes Ticket code type in which partnerTicketCode should be printed on a Marketplace voucher. Supported types: QR_CODE, BARCODE_39, BARCODE_128, TICKET_IMAGE_URL, PDF_FILE, JSON_FILE

Error

Name Type Required Description
errors array yes Array of errors
  status string yes Error status
  code string yes Error code
  title string yes Error title
  details string, null yes Error details

Cancel Booking

Example Request

{
  "data": {
    "reason": "No travelling anymore",
    "note": "Some additional notes about cancellation"
  }
}

Example Response

{
  "data": {
    "partnerBookingId": "11000232"
  }
}

Example Error Response

{
  "errors": [
    {
      "status": "404",
      "code": "BookingNotFound",
      "title": "Booking Not Found",
      "details": "Booking #2323 not found"
    }
  ]
}

HTTP Request

POST /supplier/{partnerSupplierId}/booking/{bookingId}/cancellation

Path

Parameter Type Required Description
partnerSupplierId string yes Internal Partner Supplier ID. This ID will be provided to ExperienceBank by Partner
bookingId string yes ExperienceBank Booking Id

Body

Parameter Type Required Description
data object yes Cancellation data
  reason string, null yes Cancellation reason. Can be null
  note string, null yes Cancellation note. Can be null

Responses

Name Type Required Description
data object yes Cancellation response data
  partnerBookingId string yes Booking Id from Partner's system

Error

Name Type Required Description
errors array yes Array of errors
  status string yes Error status
  code string yes Error code
  title string yes Error title
  details string, null yes Error details

Create Reservation (Optional)

Example Request

{
  "data": {
    "bookingId": "boo_35b4951f-644a-4af6-85ce-c02209598f61",
    "bookingItems": [
      {
        "date": "2019-08-01",
        "optionId": "434131423412-0900",
        "guests": [
          {
            "occupancy": 1,
            "ticketCategory": "123422"
          },
          {
            "occupancy": 1,
            "ticketCategory": "123422"
          }
        ]
      }
    ],
    "marketplace": {
      "id": "mar_22550105-a751-4e65-88f4-9ff47d335652"
    },
    "language": "en",
    "holdDurationInSeconds": 300
  }
}

Example Response

{
  "data": {
    "partnerReservationReference": "REF11A000232DEF"
  }
}

Example Error Response

{
  "errors": [
    {
      "status": "500",
      "code": "InternalServerError",
      "title": "Internal Server Error",
      "details": "Something went wrong"
    }
  ]
}

HTTP Request

POST /supplier/{partnerSupplierId}/reservation

Path

Parameter Type Required Description
partnerSupplierId string yes Internal Partner Supplier ID. This ID will be provided to ExperienceBank by Partner

Body

Parameter Type Required Description
data
object
yes Request data
  bookingId string yes Booking Id from ExperienceBank system
  bookingItems array yes Array of Booking Items
    date string yes Activity/Trip date. Has YYYY-MM-DD format, e.g. 2018-12-10. More details
    optionId string yes Option Id
    guests array yes Array of guests
      occupancy integer yes Guest occupancy. Cannot be less than 1
      ticketCategory string yes Ticket category id
  marketplace object yes Marketplace info
    id string yes Marketplace id from ExperienceBank system
  holdDurationInSeconds int yes Number of seconds for which spots must be reserved and bookable for ExperienceBank
  language string,null no Customer's language. Can be null

Response

Name Type Required Description
data
object
yes Response data
  partnerReservationReference string yes Reservation Reference from Partner System which then will be used in Create Booking Request

Error

Name Type Required Description
errors array yes Array of errors
  status string yes Error status
  code string yes Error code
  title string yes Error title
  details string, null yes Error details

Public API

Public API is used by clients to create suppliers in ExperienceBank system, pull Marketplaces info, etc. In order to have access to API you must have public key and secret key which are provided by ExperienceBank. when account is created for your marketplace. Please contact us for more details

The base URL for all API requests is https://api.experiencebank.io/v1. The API only speaks JSON-RPC. All response bodies are JSON and all request bodies are expected to be JSON.

All requests must contain a valid Authorization header authenticating the client and proving the integrity of the request.

If you system speaks PHP you can use our SDK to speed up your integration

Authorization

If you test requests with Postman you can use this pre-request script to sign all requests to ExperienceBank

var apiKey = postman.getEnvironmentVariable('publicKey'),
    apiSecret = postman.getEnvironmentVariable('secretKey'),
    hash = CryptoJS.HmacSHA256(base64url(request.data), apiSecret);

pm.environment.set('authToken', "Basic " + b64EncodeUnicode(apiKey+':'+hash));
function base64url(input) {
    var base64String = b64EncodeUnicode(input);
    base64String = base64String.replace(/=+$/, '');
    base64String = base64String.replace(/\+/g, '-');
    base64String = base64String.replace(/\//g, '_');

    return base64String;
}

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

Clients must send an Authorization header in the following format:

Authorization: "Basic " + BASE64($PUBLICKEY + ":" + HMAC_SHA256(BASE64_WITHOUT_PADDING($REQUEST_BODY), $SECRETKEY))

$PUBLICKEY - The client's public key, e.g. pub_b0f41d7fe0e51ea45018358df7f1e12d09580053c3

$SECRETKEY - The client's secret key, e.g. sec_dacd7d383558188d90c6d0b8bdc36a9b028500c6f3

$REQUEST_BODY - Request body, e.g. {"jsonrpc":"2.0","method":"activity.find","params":{"query":{"supplierId":"sup_16648235-3751-4dbd-a3fd-81470fd913d3","activityIds":[],"cursor":null}},"id":1}

Create Supplier

Example Request

{
  "jsonrpc": "2.0",
  "method": "supplier.create",
  "params": {
    "name": "Amazing Supplier",
    "partner": "par_a136d0c8-8e3a-4590-bed6-37ca35a7f9eb",
    "partnerSupplierId": "110154",
    "centralContract": {
      "isApplied": true,
      "commissionLevel": 10.67
    },
    "contact": {
      "name": "John Doe",
      "email": "john.doe@example.com",
      "websiteUrl": "https://hello.com",
      "address": "1-y zavulak Akrescina, 36А, Belarus, Minsk"
    },
    "termsAndConditionsDocumentUrl": "https://example.com/terms-and-conditions"
  },
  "id": 1
}
$response = $apiClient->supplier()->create([
    'name'=> 'Amazing Demo Activities',
    'partnerSupplierId' => '15873',
    'partner' => 'par_049a72c3-7a8d-48aa-94d1-0ba5a8e9e9f2',
    'centralContract' => [
        'isApplied' => true,
        'commissionLevel' => 10.67,
    ],
    'contact' => [
        'name' => 'John Doe',
        'email' => 'another@example.com',
        'websiteUrl' => 'https://hello.com',
        'address' => '1-y zavulak Akrescina, 36А, Belarus, Minsk'
    ],
    'termsAndConditionsDocumentUrl' => 'https://example.com/terms-and-conditions'
]);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "supplierId": "sup_a26498a0-094a-4133-8b42-e8bdbe6fbd65"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.create

Params

Name Type Required Description
name
string yes Supplier name
partner string yes Partner Id from ExperienceBank system
partnerSupplierId string yes Supplier Id from Partner's system
centralContract object yes Central Contract object
  isApplied boolean yes Is Central Contract Applied?
  commissionLevel float yes Central Contract Commission Level. If is not applied then set it to 0.0
contact object yes Contact object. This data will be used to create Supplier Admin User
  name string yes Contact person name
  email string yes Contact person email
  websiteUrl string no Supplier website url
  address string no Full supplier's address
termsAndConditionsDocumentUrl string yes Url to a publicly accessible page with Terms and Conditions. Can be empty ""

Result

Name Type Description
supplierId
string
Supplier Id from ExperienceBank system

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Update Supplier

Example Request

{
  "jsonrpc": "2.0",
  "method": "supplier.update",
  "params": {
    "supplierId": "sup_a26498a0-094a-4133-8b42-e8bdbe6fbd65",
    "name": "Amazing Supplier",
    "partner": "par_a136d0c8-8e3a-4590-bed6-37ca35a7f9eb",
    "partnerSupplierId": "110154",
    "centralContract": {
      "isApplied": true,
      "commissionLevel": 10.67
    },
    "contact": {
      "name": "John Doe",
      "email": "john.doe@example.com",
      "websiteUrl": "https://hello.com",
      "address": "1-y zavulak Akrescina, 36А, Belarus, Minsk"
    },
    "termsAndConditionsDocumentUrl": "https://example.com/terms-and-conditions"
  },
  "id": 1
}
$response = $apiClient->supplier()->update([
    'supplierId' => 'sup_a26498a0-094a-4133-8b42-e8bdbe6fbd65',
    'name'=> 'Amazing Demo Activities',
    'partnerSupplierId' => '15873',
    'partner' => 'par_049a72c3-7a8d-48aa-94d1-0ba5a8e9e9f2',
    'centralContract' => [
            'isApplied' => true,
            'commissionLevel' => 10.67,
        ],
    'contact' => [
        'name' => 'John Doe',
        'email' => 'another@example.com',
        'websiteUrl' => 'https://hello.com',
        'address' => '1-y zavulak Akrescina, 36А, Belarus, Minsk'
    ],
    'termsAndConditionsDocumentUrl' => 'https://example.com/terms-and-conditions'
]);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "supplierId": "sup_a26498a0-094a-4133-8b42-e8bdbe6fbd65"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.update

Params

Name Type Required Description
supplierId
string yes Supplier Id
name string yes Supplier name
partner string yes Partner Id from ExperienceBank system
partnerSupplierId string yes Supplier Id from Partner's system
centralContract object yes Central Contract object
  isApplied boolean yes Is Central Contract Applied?
  commissionLevel float yes Central Contract Commission Level. If is not applied then set it to 0.0
contact object yes Contact object. This data will be used to create Supplier Admin User
  name string yes Contact person name
  email string yes Contact person email
  websiteUrl string no Supplier website url
  address string no Full supplier's address
termsAndConditionsDocumentUrl string yes Url to a publicly accessible page with Terms and Conditions. Can be empty ""

Result

Name Type Description
supplierId
string
Supplier Id from ExperienceBank system

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Enable Supplier

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "supplier.enable",
  "params": {
    "supplierId" : "sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44"
  },
  "id": 1
}
$response = $apiClient->supplier()->enable('sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44');

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.enable

Params

Name Type Required Description
supplierId
string yes Supplier Id from ExperienceBank

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Disable Supplier

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "supplier.disable",
  "params": {
    "supplierId" : "sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44"
  },
  "id": 1
}
$response = $apiClient->supplier()->disable('sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44');

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.disable

Params

Name Type Required Description
supplierId
string yes Supplier Id from ExperienceBank

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Delete Supplier

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "supplier.delete",
  "params": {
    "supplierId" : "sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44"
  },
  "id": 1
}
$response = $apiClient->supplier()->delete('sup_b9c2f6a1-7f77-4065-a016-bc84a6522d44');

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.delete

Params

Name Type Required Description
supplierId
string yes Supplier Id from ExperienceBank

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Enable Mapping

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "mapping.enable",
  "params": {
    "supplierId" : "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
    "marketplaceId" : "mar_31ff966a-3430-4176-869e-1958e922f82c",
    "partnerId": "par_7c2acbce-f407-45d3-bef7-c5e16bb484c2"
  },
  "id": 1
}
$response = $apiClient->mapping()->enable($supplierId, $marketplaceId, $partnerId);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
      "mappingId" : "map_23638c44-3f5c-45aa-a352-877bda99c415"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

mapping.enable

Params

Name Type Required Description
supplierId
string yes Supplier Id from ExperienceBank
marketplaceId string yes Marketplace Id from ExperienceBank
partnerId string yes Partner Id

Result

Name Type Description
mappingId
string
Marketplace Mapping Id from ExperienceBank system

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Disable Mapping

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "mapping.disable",
  "params": {
    "mappingId" : "map_f6ce4ebe-2534-4515-8b3d-aed2814337db"
  },
  "id": 1
}
$response = $apiClient->mapping()->disable($mappingId);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
      "mappingId" : "map_f6ce4ebe-2534-4515-8b3d-aed2814337db"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

mapping.disable

Params

Name Type Required Description
mappingId
string yes Marketplace Mapping Id from ExperienceBank

Result

Name Type Description
mappingId
string
Marketplace Mapping Id from ExperienceBank system

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Marketplaces List

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "marketplace.find",
  "params": {
    "query" : {
        "marketplaces": [],
        "statuses": ["enabled"]
    }
  },
  "id": 1
}

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "data": [
            {
                "id": "mar_af330f69-3a02-4629-8d60-d763113230c8",
                "name": "HotelBeds Group",
                "description": "Hotelbeds Group is the largest distributor of tours and activities in the world. Connect now to distribute your products across a large network of re-sellers.",
                "status": "enabled",
                "isEnabled": true
            }
        ]
    },
    "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

marketplace.find

Params

Name Type Required Description
query
object yes Query
  marketplaces array yes Marketplaces Ids. Can be empty []
  statuses array yes Statuses. Can be empty []. Allowed values: enabled, disabled, coming soon

Result

Name Type Description
data
array
Marketplaces data
  id string Marketplace id
  name string Marketplace name
  description string Marketplace description
  status string Marketplace status. Possible values: enabled, disabled, coming soon
  isEnabled boolean Is marketplace enabled

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Generate Auto Login Url

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "supplier.generateAutoLoginUrl",
  "params": {
      "supplierId" : "sup_ee9f3fbe-72b7-4677-8a91-a76c5325b635",
      "email": "john.doe@example.com",
      "redirectUrl" : {
        "targetPage" : "mapping",
        "data" : {
          "mappingId" : "map_ddc45875-bdf5-4811-9519-f3a5d99eebdf"
        }
      }
  },
  "id": 1
}
$response = $apiClient->supplier()
    ->generateAutoLoginUrl('sup_ee9f3fbe-72b7-4677-8a91-a76c5325b635', 'john.doe@example.com')
    ->forMapping('map_ddc45875-bdf5-4811-9519-f3a5d99eebdf');

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "url": "https://app.experiencebank.io/a/l/auto_71d3b0b7534ce6e3047bef397e0958e60fe43f9f97"
    },
    "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": 1
}

Method

supplier.generateAutoLoginUrl

Params

Name Type Required Description
supplierId
string yes Supplier Id from ExperienceBank
email string yes User email
redirectUrl object yes Redirect Url settings
  targetPage string yes Page you want to redirect the user. It can be dashboard or mapping page for a specific marketplace. Possible values: dashboard, mapping
  data object yes Redirect url data
    mappingId string, null yes Mapping Id is used when targetPage is mapping. Can be null. If null and targetPage is mapping the user will be redirected to Dashboard anyway

Result

Name Type Description
url
string
Auto Login Url

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Notification API

In order to have access to API you must have public key and secret key which are provided by ExperienceBank. Please contact us for more details

The base URL for all API requests is https://api.experiencebank.io/v1. The API only speaks JSON-RPC. All response bodies are JSON and all request bodies are expected to be JSON.

All requests must contain a valid Authorization header authenticating the client and proving the integrity of the request.

If you system speaks PHP you can use our SDK to speed up your integration

Authorization

If you test requests with Postman you can use this pre-request script to sign all requests to ExperienceBank

var apiKey = postman.getEnvironmentVariable('publicKey'),
    apiSecret = postman.getEnvironmentVariable('secretKey'),
    hash = CryptoJS.HmacSHA256(base64url(request.data), apiSecret);

pm.environment.set('authToken', "Basic " + b64EncodeUnicode(apiKey+':'+hash));
function base64url(input) {
    var base64String = b64EncodeUnicode(input);
    base64String = base64String.replace(/=+$/, '');
    base64String = base64String.replace(/\+/g, '-');
    base64String = base64String.replace(/\//g, '_');

    return base64String;
}

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

Clients must send an Authorization header in the following format:

Authorization: "Basic " + BASE64($PUBLICKEY + ":" + HMAC_SHA256(BASE64_WITHOUT_PADDING($REQUEST_BODY), $SECRETKEY))

$PUBLICKEY - The client's public key, e.g. pub_b0f41d7fe0e51ea45018358df7f1e12d09580053c3

$SECRETKEY - The client's secret key, e.g. sec_dacd7d383558188d90c6d0b8bdc36a9b028500c6f3

$REQUEST_BODY - Request body, e.g. {"jsonrpc":"2.0","method":"activity.find","params":{"query":{"supplierId":"sup_16648235-3751-4dbd-a3fd-81470fd913d3","activityIds":[],"cursor":null}},"id":1}

Activity Updated

Example Request

{
  "jsonrpc": "2.0",
  "method": "activity.updated",
  "params": {
    "activityId": "23222",
    "partnerSupplierId": "15873"
  },
  "id": null
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": null
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": null
}

Method

activity.updated

Params

Name Type Required Description
activityId
string yes Activity Id from Partner's system
partnerSupplierId string yes Supplier Id from Partner's system

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Availability Updated

Example Request

{
  "jsonrpc": "2.0",
  "method": "availability.updated",
  "params": {
    "activityId": "23222",
    "partnerSupplierId": "15873",
    "optionId": "49239022023-0900",
    "fromDate": "2018-01-18",
    "toDate": "2018-01-18"
  },
  "id": null
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": null
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": null
}

Method

availability.updated

Params

Name Type Required Description
activityId
string yes Activity Id from Partner's system
partnerSupplierId string yes Supplier Id from Partner's system
optionId string yes Option Id from Partner's system
fromDate string yes Date from which to update availabilities. Must have YYYY-MM-DD format. More details
toDate string yes Date to which to update availabilities. Must have YYYY-MM-DD format. More details

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Booking Cancelled

Example Request

{
  "jsonrpc": "2.0",
  "method": "booking.cancelled",
  "params": {
    "bookingId": "boo_35b4951f-644a-4af6-85ce-c02209598f61"
  },
  "id": null
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": null
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": null
}

Method

booking.cancelled

Params

Name Type Required Description
bookingId
string yes Booking Id from ExperienceBank

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Ticket Affected

Example Request

{
  "jsonrpc": "2.0",
  "method": "ticket.affected",
  "params": {
    "ticketId": "tic_3cf83d4e-59c7-456a-b60a-ad1bacb4bb37",
    "status": "cancelled",
    "date": "2018-06-07T17:01:21+0000"
  },
  "id": null
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": null
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / is not available."
  },
  "id": null
}

Method

ticket.affected

Params

Name Type Required Description
ticketId
string yes Ticket Id from ExperienceBank
status string yes Status. Possible values: created, cancelled, redeemed
date string yes Date of action. Must be datetime format (e.g. 2018-12-11T14:00:00+02:00) ISO 8601

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Distributor API

Distributor API is used by distributors to pull inventory and create/cancel bookings in ExperienceBank system. In order to have access to API you must have public key and secret key which are provided by ExperienceBank when account is created for your marketplace. Please contact us for more details

The base URL for all API requests is https://api.experiencebank.io/v1. The API only speaks JSON-RPC. All response bodies are JSON and all request bodies are expected to be JSON.

All requests must contain a valid Authorization header authenticating the client and proving the integrity of the request.

If you system speaks PHP you can use our SDK to speed up your integration

Authorization

If you test requests with Postman you can use this pre-request script to sign all requests to ExperienceBank

var apiKey = postman.getEnvironmentVariable('publicKey'),
    apiSecret = postman.getEnvironmentVariable('secretKey'),
    hash = CryptoJS.HmacSHA256(base64url(request.data), apiSecret);

pm.environment.set('authToken', "Basic " + b64EncodeUnicode(apiKey+':'+hash));
function base64url(input) {
    var base64String = b64EncodeUnicode(input);
    base64String = base64String.replace(/=+$/, '');
    base64String = base64String.replace(/\+/g, '-');
    base64String = base64String.replace(/\//g, '_');

    return base64String;
}

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

Clients must send an Authorization header in the following format:

Authorization: "Basic " + BASE64($PUBLICKEY + ":" + HMAC_SHA256(BASE64_WITHOUT_PADDING($REQUEST_BODY), $SECRETKEY))

$PUBLICKEY - The client's public key, e.g. pub_b0f41d7fe0e51ea45018358df7f1e12d09580053c3

$SECRETKEY - The client's secret key, e.g. sec_dacd7d383558188d90c6d0b8bdc36a9b028500c6f3

$REQUEST_BODY - Request body, e.g. {"jsonrpc":"2.0","method":"activity.find","params":{"query":{"supplierId":"sup_16648235-3751-4dbd-a3fd-81470fd913d3","activityIds":[],"cursor":null}},"id":1}

Activities List

Example Request

{
  "jsonrpc": "2.0",
  "method": "activity.find",
  "params": {
    "query": {
      "supplierId": "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
      "activityIds": [
        "act_28f8a3d7-611d-47a2-a34c-16cc780745de"
      ],
      "cursor": null,
      "categoryIds": [
        "2"
      ]
    }
  },
  "id": 1
}
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Activity\Query;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->activity()->find(
    new Query(
        'sup_16648235-3751-4dbd-a3fd-81470fd913d3',
        ['act_28f8a3d7-611d-47a2-a34c-16cc780745de'],
        null, // it's cursor
        ['2'] // categories ids array
    )
);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "cursor": {
      "next": "MAe="
    },
    "data": [
      {
        "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
        "supplierId": "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
        "title": "Amazing Walking Tour",
        "description": "<p>lorem ipsum</p>",
        "highlights": "<p>Tlorem ipsum</p>",
        "itinerary": "<p>Tlorem ipsum</p>",
        "language": "en",
        "categories": ["1", "2", "5"],
        "inclusions": ["Drinks"],
        "exclusions": ["Lunch"],
        "importantInfo": ["Alcoholic beverages are only for guests aged 18 or older. Photo ID is required for all passengers consuming alcoholic beverages."],
        "destination": {
          "countryCode": "NL",
          "code": "AMS",
          "name": "Amsterdam"
        },
        "media": {
          "images": {
            "header": "https://cdn.example.com/185105/600x400-1-50-e4d927f71de3263b99ad46fae2a1d146.jpg",
            "teaser": "https://cdn.example.com/185105/600x400-1-50-e4d927f71de3263b99ad46fae2a1d146.jpg",
            "gallery": [
              "https://cdn.example.com/185105/600x400-1-50-f4d923f71de2263b99a246fae2a3d146.jpg",
              "https://cdn.example.com/285105/600x400-1-50-a4de7f71dee3b99ad46fae2a36.jpg",
              "https://cdn.example.com/385105/600x400-1-50-e4d927f71de26339ad46fae2a1d146.jpg",
              "https://cdn.example.com/485105/600x400-1-50-h4d9df71de3263b99ad46fae2a1d146.jpg"
            ]
          },
          "videos": [
            "//www.youtube.com/watch?v=-1V1oZ3IGPw"
          ]
        },
        "rating" : {
          "averageValue": 4.8,
          "totalCount": 1067
        },
        "meetingPoints": [
          {
            "name": "Zürich",
            "latitude": "47.376887",
            "longitude": "8.541694",
            "address": "100/F, International Commerce Centre"
          }
        ],
        "route": [
          {
            "name": "The Lodge at Vail",
            "latitude": "39.640132",
            "longitude": "-106.374740"
          },
          {
            "name": "Mill Creek Rd.",
            "latitude": "39.639640",
            "longitude": "-106.374229"
          }
        ],
        "cancellationPolicy": {
          "isFreeCancellation": false,
          "refundConditions": [
            {
              "minDurationBeforeStartTimeSec": 604800,
              "refundPercentage": 50
            },
            {
              "minDurationBeforeStartTimeSec": 172800,
              "refundPercentage": 100
            }
          ]
        },
        "options": [
          {
            "optionId": "opt_cd1adf6b-3e68-4780-9779-dbd0f6dbef46",
            "name": "09:00 AM Walking Tour",
            "duration": "PT4H",
            "startTime": "00:00:00",
            "openingHours": [
              {
                "fromTime": "09:00:00",
                "toTime": "20:30:00"
              }
            ],
            "fromDate": "2018-10-29",
            "untilDate": "2018-11-30",
            "cutOffInMinutes": 0,
            "weekdays": [
              "mon",
              "sat",
              "sun"
            ],
            "isActive": true,
            "ticketCategories": [
              {
                "ticketCategoryId": "ADULT",
                "name": "Adult",
                "minSeats": 1,
                "maxSeats": 1,
                "price": {
                  "type": "fixed",
                  "amount": "23.00",
                  "currency": "EUR"
                },
                "isActive": true,
                "type": "Adult",
                "ageLimit": {
                  "minAge": 18,
                  "maxAge": 65
                },
                "translations": [
                  {
                    "language": "be",
                    "name": "Дарослы"
                  }
                ]
              }
            ],
            "translations": [
              {
                "language": "be",
                "name": "Пешаходная экскурсія"
              }
            ]
          },
          {
            "optionId": "opt_fad3864a-7058-41d1-99e6-5d32a5a4f785",
            "name": "09:00 AM Walking Tour",
            "duration": "PT4H",
            "startTime": "10:00:00",
            "openingHours": [],
            "fromDate": "2018-10-29",
            "untilDate": "2018-11-30",
            "cutOffInMinutes": 0,
            "weekdays": [
              "mon",
              "tue",
              "wed",
              "thu",
              "fri",
              "sat",
              "sun"
            ],
            "isActive": true,
            "ticketCategories": [
              {
                "ticketCategoryId": "ADULT",
                "name": "Adult",
                "minSeats": 1,
                "maxSeats": 1,
                "price": {
                  "type": "fixed",
                  "amount": "23.00",
                  "currency": "EUR"
                },
                "isActive": true,
                "type": "Adult",
                "ageLimit": {
                  "minAge": 18,
                  "maxAge": 65
                },
                "translations": [
                  {
                    "language": "be",
                    "name": "Дарослы"
                  }
                ]
              },
              {
                "ticketCategoryId": "728924",
                "name": "GROUP 1-10",
                "minSeats": 1,
                "maxSeats": 10,
                "price": {
                  "type": "variable",
                  "amount": "10.00",
                  "currency": "EUR"
                },
                "isActive": true,
                "type": "Group",
                "ageLimit": null,
                "translations": [
                  {
                    "language": "be",
                    "name": "Група 1-10"
                  }
                ]
              }
            ],
            "translations": [
              {
                "language": "be",
                "name": "Пешаходная экскурсія"
              }
            ]
          }
        ],
        "addons": [
          {
            "addonId": "23453234",
            "title": "T-Shirt",
            "description": "Amazing T-Shirt",
            "type": "guest",
            "price": {
              "amount": "10.00",
              "currency": "USD"
            },
            "translations": [
              {
                "language": "be",
                "title": "Цiшотка",
                "description": "Цiшотка з малюнкам"
              }
            ]
          }
        ],
        "guestFields": [
          {
            "code": "gender",
            "label": "Gender",
            "type": "radio",
            "required": true,
            "options": [
              {
                "key": "m",
                "value": "Male",
                "translations": [
                  {
                    "language": "be",
                    "value": "Мужчына"
                  }
                ]
              },
              {
                "key": "f",
                "value": "Female",
                "translations": [
                  {
                    "language": "be",
                    "value": "Жанчына"
                  }
                ]
              }
            ],
            "translations": [
              {
                "language": "be",
                "label": "Пол"
              }
            ]
          }
        ],
        "translations": [
          {
            "language": "es",
            "title": "<p>lorem ipsum</p>",
            "description": "<p>lorem ipsum</p>",
            "highlights": "<p>lorem ipsum</p>",
            "itinerary": "<p>lorem ipsum</p>",
            "inclusions": ["Getränke"],
            "exclusions": ["Mittagessen"],
            "importantInfo": ["Alkoholische Getränke sind nur für Gäste ab 18 Jahren. Für alle Passagiere, die alkoholische Getränke konsumieren, ist ein Lichtbildausweis erforderlich."]
          }
        ]
      }
    ]
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / not available."
  },
  "id": 1
}

Method

activity.find

Params

Name Type Required Description
query
object
yes Query object
  supplierId string yes Supplier Id
  activityIds array yes Array of activity ids. Can be empty array [] to get data about all activities
  categoryIds array no Array of category ids
  cursor string, null yes Cursor to the next batch of data. Can be null

Result

Name Type Description
cursor
object
Cursor object
  next string, null Cursor pointer to the next data batch. Can be null if all data was returned
data array Array of activities
  activityId string Activity Id
  supplierId string Supplier Id
  title string Activity Title
  description string Activity Description. Can contain HTML
  highlights string Activity Highlights. Can contain HTML
  itinerary string Activity Itinerary. Can contain HTML
  inclusions array Array of items that are included in the activity. Can be empty array []
  exclusions array Array of items that are excluded in the activity. Can be empty array []
  importantInfo array Array of items that are important to know before the activity. Can be empty array []
  language string Activity language. Example en, en_GB, es, etc
  categories array Array of Activity categories ids. Can be empty array []
  destination object Object contains information about activity destination
    countryCode string, null Destination country code
    code string, null Destination location code
    name string, null Destination location name
  media object Object contains information about media resources (images, videos)
    images object Object contains information about header, teaser and gallery images
      header string, null Header image url. Can be null
      teaser string, null Teaser image url . Can be null
      gallery array Array of image urls. Can be empty array []
    videos array Array of videos urls. Can be empty array []
  rating object, null Object contains information about Activity rating
    averageValue float Rating average value
    totalCount integer Total count of ratings
  addons array Array of activity addons
    addonId string Addon Id
    title string Addon Title
    description string Addon Description
    type string Addon Type. Can be guest or item. Depends on this value you should add this addon on guest or booking item level on booking request.
    price object Addon Price Information
      amount string Addon Price amount
      currency string Addon Price currency
    translations array Array of translations. Can be empty array [] if not supported
      language string Translation language
      title string Title Translation
      description string Description Translation
  guestFields array Array of activity guest fields
    code string Guest field code
    label string Guest field label
    type string Guest field type. Can be radio, text, select, etc
    required boolean Is guest field required?
    options array Array of options if available. Some types like radio or select can have options.
      key mixed Guest field option key
      value mixed Guest field option value
      translations array Array of translations. Can be empty array [] if not supported
        language string Translation language
        value string Value Translation
    translations array Array of translations. Can be empty array [] if not supported
      language string Translation language
      label string Label Translation
  meetingPoints array Array of meeting points points. Can be empty array [] if not supported
    name string Meeting point name
    latitude string Meeting point latitude
    longitude string Meeting point longitude
    address string Meeting point address
  route array Array of trip route points. Can be empty []
    name string Name of route point. Can be empty ""
    latitude string Point latitude
    longitude string Point longitude
  cancellationPolicy object, null Object contains information about refund conditions
    isFreeCancellation boolean Whether is free cancellation or not
    refundConditions array Array of refund conditions. Can be []
      minDurationBeforeStartTimeSec int Duration in seconds before the start time, until when the customer can receive a refund for part of the activity's cost specified in refundPercentage. When set to 0 (default), the activity can be cancelled at any time.
      refundPercentage int The percent that can be refunded, as long as the activity booking is cancelled at least minDurationBeforeStartTimeSec before the activity start time, in the range of [0, 100]. When set to 0 (default), the activity is not refundable. When set to 100 this activity is fully refundable
  options array Array of activity options
    optionId string Option Id
    name string Option name
    duration string Option duration. Has PnYnMnDTnHnMnS format. More details
    startTime string Option start time. Has hh:mm:ss format. More details. Can be 00:00:00 if doesn't have a specific start time
    openingHours array Array of opening hours. Can be empty array [] if has a specific start time
      fromTime string From time. Has hh:mm:ss format, e.g. 09:00:00. More details
      toTime string To time. Has hh:mm:ss format, e.g. 17:00:00. More details
    fromDate string Option from date. Has YYYY-MM-DD format. More details
    untilDate string Option until date. Has YYYY-MM-DD format. More details
    cutOffInMinutes integer Minutes before activity start when bookings are not allowed
    weekdays array Array of weekdays when activity is available. Possible values: mon, tue, wed, thu, fri, sat, sun. Can be empty [] if option is not recurrent.
    isActive boolean Option state
    ticketCategories array Array of option ticket categories
      ticketCategoryId string Ticket Category Id
      name string Ticket Category name
      minSeats integer Minimum seats required to book this ticket category. If minSeats more than 1 then ticket category is GROUP which means that one ticket will be applicable to several guests
      maxSeats integer Maximum seats allowed to book this ticket category. If maxSeats more than 1 then ticket category is GROUP which means that one ticket will be applicable to several guests
      isActive boolean Ticket Category state
      type string Ticket Category type. Can be empty string "". Supported types: Adult, Child, Infant, Senior, Youth, Student, Military, Group, Traveller, Family, Transfer, Room, Other
      ageLimit object, null Ticket Category age limit. Can be null
        minAge integer Age limit minimum age
        maxAge integer Age limit maximum age
      price object Ticket Category price information
        type string Can be fixed or variable. If fixed total amount for booked guests will be price of this ticket category. If variable - price will be multiplied by guests count, e.g. if ticket category Adult has fixed price 100 EUR and 5 guests were booked total price will be still 100 EUR. If it had variable price type total price would be 500 EUR
        amount string Price amount
        currency string Price currency
      translations array Array of translations. Can be empty array [] if not supported
        language string Translation language
        name string Name Translation
    translations array Array of translations. Can be empty array [] if not supported
      language string Translation language
      name string Name Translation
  translations array Array of translations
    language string Translation language. Example en, en_GB, es, etc
    title string, null Translated title. Can be empty "" or null
    description string, null Translated description. Can be empty "" or null
    highlights string, null Translated highlights. Can be empty "" or null
    itinerary string, null Translated itinerary. Can be empty "" or null
    inclusions array Array of items that are included in the activity. Can be empty array []
    exclusions array Array of items that are excluded in the activity. Can be empty array []
    importantInfo array Array of items that are important to know before the activity. Can be empty array []

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Availabilities List

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "availability.find",
  "params": {
    "query" : {
        "supplierId" : "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
        "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
        "fromDate": "2018-11-14",
        "untilDate": "2020-11-10",
        "optionIds": ["opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5"],
        "cursor": "MAe="
    }
  },
  "id": 1
}
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Availability\Query;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->availability()->find(
    new Query(
        'sup_16648235-3751-4dbd-a3fd-81470fd913d3',
        'act_28f8a3d7-611d-47a2-a34c-16cc780745de',
        '2018-11-14',
        '2020-11-10',
        ['opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5'],
        'MAe='
    )
);

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "cursor": {
            "next": "MAe="
        },
        "data": [
            {
                "supplierId": "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
                "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
                "optionId": "opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5",
                "localDate": "2019-05-30",
                "localTime": "00:00:00",
                "openingHours": [
                  {
                    "fromTime": "09:00:00",
                    "toTime": "20:30:00"
                  }
                ],
                "availableCapacity": 999,
                "maximumCapacity": 999,
                "canBeBookedAfterStartTime": true,
                "ticketCategories" : [
                    {
                        "ticketCategoryId" : "8388433",
                        "name": "Adult",
                        "minSeats": 1,
                        "maxSeats": 1,
                        "availableCapacity": 999,
                        "price": {
                            "type": "variable",
                            "amount": "59.00",
                            "currency": "EUR"
                        },
                        "type": "Adult",
                        "ageLimit": {
                            "minAge": 18,
                            "maxAge": 65
                        }
                    },
                    {
                        "ticketCategoryId" : "5388435",
                        "name": "Child",
                        "minSeats": 1,
                        "maxSeats": 1,
                        "availableCapacity": 999,
                        "price": {
                            "type": "fixed",
                            "amount": "45.00",
                            "currency": "EUR"
                        },
                        "type": "",
                        "ageLimit": null
                    }
                ]
            },
            {
                "supplierId": "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
                "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
                "optionId": "opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5",
                "localDate": "2019-05-31",
                "localTime": "09:00:00",
                "openingHours": [],
                "availableCapacity": 980,
                "maximumCapacity": 999,
                "canBeBookedAfterStartTime": true,
                "ticketCategories" : [
                    {
                        "ticketCategoryId" : "8388433",
                        "name": "Adult",
                        "minSeats": 1,
                        "maxSeats": 1,
                        "availableCapacity": null,
                        "price": {
                            "type": "variable",
                            "amount": "59.00",
                            "currency": "EUR"
                        },
                        "type": "Adult",
                        "ageLimit": {
                            "minAge": 18,
                            "maxAge": 65
                        }
                    },
                    {
                        "ticketCategoryId" : "5388435",
                        "name": "Child",
                        "minSeats": 1,
                        "maxSeats": 1,
                        "availableCapacity": null,
                        "price": {
                            "type": "fixed",
                            "amount": "45.00",
                            "currency": "EUR"
                        },
                        "type": "Child",
                        "ageLimit": null
                    }
                ]
            }
        ]
    },
    "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / not available."
  },
  "id": 1
}

Method

availability.find

Params

Name Type Required Description
query
object
yes Query object
  supplierId string yes Supplier Id
  activityId string yes Activity Id
  fromDate string yes Date range from date. Must have YYYY-MM-DD format. More details
  untilDate string yes Date range until date. Must have YYYY-MM-DD format. More details
  optionIds array yes Array of option ids. Can be empty array [] to get availabilities for all option
  cursor string, null yes Cursor to the next batch of data. Can be null

Result

Name Type Description
cursor
object
Cursor object
  next string, null Cursor pointer to the next data batch. Can be null if all data was returned
data array Array of availabilities
  supplierId string Supplier Id
  activityId string Activity Id
  optionId string Option Id
  localDate string Local Date
  localTime string Local start time. Has hh:mm:ss format. More details
  openingHours array Array of opening hours. Can be empty array [] if has a specific start time
    fromTime string From time. Has hh:mm:ss format, e.g. 09:00:00. More details
    toTime string To time. Has hh:mm:ss format, e.g. 17:00:00. More details
  availableCapacity integer Option Available capacity
  maximumCapacity integer Option Maximum capacity
  canBeBookedAfterStartTime boolean If true then this availability can be booked after its start time, f.e. if start time is 09:00:00 it can be booked at 10:00:00 or 11:00:00 and so on. Works for museums, etc
  ticketCategories array Array of ticket categories available capacities. Can be empty [] if available capacities by ticket categories are not supported
    ticketCategoryId string Ticket category id
    availableCapacity integer, null Ticket category available capacity. Can be null if not applicable. If null it means that there is no limitation on a ticket category level and you should check availableCapacity on an option level
      name string Ticket Category name
      minSeats integer Minimum seats required to book this ticket category
      maxSeats integer Maximum seats allowed to book this ticket category
      type string Ticket Category type. Can be empty string "". Supported types: Adult, Child, Infant, Senior, Youth, Student, Military, Group, Person, Family, Transfer, Room
      ageLimit object, null Ticket Category age limit. Can be null
        minAge integer Age limit minimum age
        maxAge integer Age limit maximum age
      price object Ticket Category price information
        type string Can be fixed or variable. If fixed total amount for booked guests will be price of this ticket category. If variable - price will be multiplied by guests count, e.g. if ticket category Adult has fixed price 100 EUR and 5 guests were booked total price will be still 100 EUR. If it had variable price type total price would be 500 EUR
        amount string Price amount
        currency string Price currency

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Create Booking

Example Request

{
  "jsonrpc": "2.0",
  "method": "booking.create",
  "params": {
    "supplierId": "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
    "bookingItems": [
      {
        "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
        "optionId": "opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5",
        "date": "2019-05-30",
        "ticketCategories": [
          {
            "ticketCategory": "8892762",
            "count": 1
          },
          {
            "ticketCategory": "8892762",
            "count": 1
          },
          {
            "ticketCategory": "8892762",
            "count": 1
          }
        ]
      }
    ],
    "language": "en",
    "holdDurationSeconds": 300
  },
  "id": 1
}

use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\CreateBookingRequest;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\BookingItem;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\TicketCategory;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->booking()->create(
    new CreateBookingRequest(
    'sup_16648235-3751-4dbd-a3fd-81470fd913d3',
     300,
     [
        new BookingItem(
            'act_28f8a3d7-611d-47a2-a34c-16cc780745de',
            'opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5',
            '2019-05-30',
            [
                new TicketCategory('8892762', 3)
            ]
        )
     ]
    )
);

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "bookingId": "boo_aa31d25d-e6b1-4dda-a13d-3e719fc4f114",
        "expiresAt": 1543486437
    },
    "id": 1
}

Example Error Response

{
    "jsonrpc": "2.0",
    "error": {
        "code": 0,
        "message": "Availability for Option Id \"opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5\" and date \"2018-05-30\" was not found"
    },
    "id": 1
}

Method

booking.create

Params

Name Type Required Description
supplierId
string yes Supplier Id
holdDurationSeconds integer yes Duration in seconds for which availabilities should be reserved. Maximum allowed is 5400 (1.5h)
language string no Customer's language
bookingItems array yes Array of Booking Items
  activityId string yes Activity Id
  optionId string yes Option Id
  date string yes Local date. Must have YYYY-MM-DD format. More details
  ticketCategories array yes Array of Ticket Categories. Cannot be empty
    ticketCategory string yes Ticket Category id
    count integer yes Ticket Category count. For ticket categories which are not GROUP you should send them with count: 1. So if you have 5 Adult which are not GROUP you should send 5 ticket categories with count: 1. In case of GROUP ticket category you can pass count more than 1 like count: 5

Result

Name Type Description
bookingId
string
Booking Id
expiresAt integer Timestamp when reservation expires

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Commit Booking

Please note that while guest additional fields goes to activity owner, non-required guest fields country, nationality and gender are for ExperienceBank statistics purposes only.

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "booking.commit",
  "params": {
    "supplierId" : "sup_16648235-3751-4dbd-a3fd-81470fd913d3",
    "bookingId": "boo_8dd17a9e-17f4-4e6f-a5c4-dca7682c8321",
    "bookingItems" : [
      {
        "activityId": "act_28f8a3d7-611d-47a2-a34c-16cc780745de",
        "optionId" : "opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5",
        "date": "2019-05-30",
        "ticketCategories" : [
          {
            "ticketCategory" : "8892762",
            "count" : 1,
            "externalTicketId": "ext_1"
          }
        ],
        "guests": [
          {
            "firstName": "John",
            "lastName": "Doe",
            "emailAddress": "johndoe@example.com",
            "phoneNumber": "+12345678901",
            "addons" : [
                {
                  "id": "44267",
                  "quantity": 2
                }
            ],
            "additionalFields" : [
                {
                  "key" : "gender",
                  "value" : "m"
                },
                {
                  "key" : "nationality",
                  "value" : "CH"
                }
            ],
            "country": "US", 
            "nationality": "CH", 
            "gender": "m" 
          }
        ],
        "addons" : [
          {
            "id": "44268",
            "quantity": 5
          }
        ]
      }
    ],
    "externalBookingReference": "4434531234354",
    "notes": "Some special requirements",
    "language": "en",
    "payment" : {
      "amount" : "50",
      "currency" : "USD"
    },
    "contact" : {
      "fullName": "John Doe",
      "emailAddress": "john.doe@example.com",
      "phoneNumber": "+474998799654"
    }
  },
  "id": 1
}

use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\CommitBookingRequest;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\Commit\BookingItem;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\TicketCategory;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\Payment;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\Contact;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\Guest;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\AdditionalField;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\Addon;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->booking()->commit(
    new CommitBookingRequest(
      'sup_16648235-3751-4dbd-a3fd-81470fd913d3',
      'boo_8dd17a9e-17f4-4e6f-a5c4-dca7682c8321',
      '4434531234354',
      'Some special requirements',
      new Payment('50', 'USD'),
      new Contact('John Doe', 'john.doe@example.com', '+474998799654'),
       [
          new BookingItem(
              'act_28f8a3d7-611d-47a2-a34c-16cc780745de',
              'opt_f4e6624b-75c8-43f9-b9f7-06200acc59c5',
              '2019-05-30',
              [
                  new TicketCategory('8892762', 1, 'ext_1')
              ],
              [
                  new Guest(
                      'John',
                      'Doe',
                      'johndoe@example.com',
                      '+12345678901',
                      [
                          new AdditionalField('gender', 'm'),
                          new AdditionalField('nationality', 'CH'),
                      ],
                      [
                          new Addon('44267', 2),
                      ],
                      'US',
                      'CH',
                      'm'
                  )
              ],
              [
                  new Addon('44268', 5),
              ]
          )
       ]
    )
);

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "bookingId": "boo_8dd17a9e-17f4-4e6f-a5c4-dca7682c8321",
        "externalBookingReference": "20200809",
        "tickets": [
            {
                "ticketId": "tic_06ed5e8e-f638-47b5-ac02-b829d82f3476",
                "ticketCategory": "8892762",
                "ticketCode": "tic_06ed5e8e-f638-47b5-ac02-b829d82f3476",
                "ticketCodeType": "QR_CODE"
            }
        ]
    },
    "id": 1
}

Example Error Response

{
    "jsonrpc": "2.0",
    "error": {
        "code": 400,
        "message": "Request validation failed: contact.emailAddress:required, contact:type, contact:oneOf",
        "data": {
            "errors": {
                "contact.emailAddress": "The property emailAddress is required",
                "contact": "Failed to match exactly one schema"
            }
        }
    },
    "id": 1
}

Method

booking.commit

Params

Name Type Required Description
supplierId
string
yes Supplier Id
bookingId string yes Booking Id from the 1st step of booking process
externalBookingReference string yes Booking Reference from Distributor side
notes string yes Booking notes
language string no Customer's language
bookingItems array yes Array of Booking Items
  activityId string yes Activity Id
  optionId string yes Option Id
  date string yes Local date. Must have YYYY-MM-DD format. More details
  ticketCategories array yes Array of Ticket Categories. Cannot be empty
    ticketCategory string yes Ticket Category id
    count integer yes Ticket Category count. For ticket categories which are not GROUP you should send them with count: 1. So if you have 5 Adult which are not GROUP you should send 5 ticket categories with count: 1. In case of GROUP ticket category you can pass count more than 1 like count: 5
    externalTicketId string, null yes Ticket Id on Distributor side. Can be null
  guests array yes Array of Guests. Cannot be empty
    firstName string, null yes Guest first name. Can be null
    lastName string, null yes Guest last name. Can be null
    emailAddress string, null yes Guest email address. Can be null
    phoneNumber string, null yes Guest phone number. Can be null
    addons array yes Array of addons. Can be empty []
      id string yes Addon Id
      quantity integer yes Addon Quantity
    additionalFields array yes Array of Additional Fields. Can be empty []
      key string yes Additional Field key
      value string yes Additional Field value
    country string no Guest country in ISO 3166-1 alpha-2 format.
    nationality string no Guest nationality in ISO 3166-1 alpha-2 format.
    gender string no Guest gender ("m"/"f").
payment object, null yes Payment Info. Can be null if no payment info
  amount string yes Payment amount
  currency string yes Payment currency
contact object, null yes Contact Info. Can be null if no contact info
  fullName string, null yes Contact person full name. Can be null
  emailAddress string, null yes Contact person email address. Can be null
  phoneNumber string, null yes Contact person phone number. Can be null

Result

Name Type Description
bookingId
string
Booking Id
externalBookingReference null,string A booking reference from a booking system. If a booking is done in an asynchronous way this field can be empty for some time
tickets array Array of tickets data
  ticketId string ExperienceBank ticket id
  ticketCategory string Requested ticket category
  ticketCode string ExperienceBank ticket code
  ticketCodeType string ExperienceBank ticket code type. Supported types: QR_CODE, BARCODE_39, BARCODE_128, TICKET_IMAGE_URL, PDF_FILE, JSON_FILE

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object. See example for more details

Get Booking

Example Request

{
  "jsonrpc": "2.0",
  "method": "booking.get",
  "params": {
    "bookingId": "boo_d98b3525-2e76-4280-8b78-8c6a13dd6822"
  },
  "id": 1
}

use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\GetBookingRequest;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->booking()->get(
    new GetBookingRequest(
      'boo_d98b3525-2e76-4280-8b78-8c6a13dd6822'
    )
);

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "bookingId": "boo_017e1576-bdb6-4a82-8018-e58131b74c4c",
    "externalBookingReference": "20200809",
    "supplierId": "sup_33c13b78-fc8d-4244-9c76-1551aec380be",
    "bookingItems": [
      {
        "activityId": "act_f7489b25-3ab0-4f6d-8530-7a536d0c796d",
        "optionId": "opt_c67ec565-7344-49c2-92f5-53763279b68a",
        "date": "2019-04-28",
        "tickets": [
          {
            "ticketId": "tic_1b9fc19a-768a-474e-9343-200f5171d04a",
            "ticketCategoryId": "9483444",
            "occupancy": 1,
            "ticketCode": "tic_1b9fc19a-768a-474e-9343-200f5171d04a",
            "ticketCodeType": "QR_CODE"
          }
        ],
        "guests": [
          {
            "guestId": "gue_b1227814-e45e-4503-83bb-3cf745edccc9",
            "firstName": "John",
            "lastName": "Doe",
            "emailAddress": "johndoe@server.com",
            "phoneNumber": "+12345678901",
            "addons": [
              {
                "id": "44267",
                "guestId": "gue_b1227814-e45e-4503-83bb-3cf745edccc9",
                "quantity": 2
              }
            ],
            "additionalFields": [
              {
                "key": "nationality",
                "value": "BY"
              }
            ]
          }
        ],
        "addons": [
          {
            "id": "44888",
            "bookingItemId": "boi_1",
            "quantity": 2
          }
        ]
      }
    ],
    "notes": "Need a wheelchair",
    "language": "en",
    "status": "delivered",
    "bookingSource": {
      "id": "mar_185d503e-3a6a-49e6-9fb2-e62a9202cf90",
      "bookingId": "EXTERNALBOOKING2342456365345"
    },
    "payment": {
      "amount": "61.5",
      "currency": "EUR"
    },
    "contact": {
      "fullName": "John Doe",
      "email": "johndoe@server.com",
      "phoneNumber": "+1 999999999999"
    },
    "cancellationReason": null,
    "cancellationNote": null,
    "createdAt": "2019-04-23T14:03:34+00:00"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": 400,
    "message": "Request validation failed: bookingId:minLength",
    "data": {
      "errors": {
        "bookingId": "Must be at least 1 characters long"
      }
    }
  },
  "id": 1
}

Method

booking.get

Params

Name Type Required Description
bookingId
string yes BookingId

Result

Name Type Description
bookingId
string Booking Id
externalBookingReference null,string A booking reference from a booking system. If a booking is done in an asynchronous way this field can be empty for some time
supplierId string Supplier Id
bookingItems array Booking items objects array
  activityId string Activity Id
  optionId string Option Id
  date string Activity date
  tickets array Tickets objects array
    ticketId string Ticket Id
    ticketCategoryId string Ticket category Id
    occupancy int Ticket occupancy
    ticketCode string Ticket code
    ticketCodeType string Ticket code type (QR_CODE, BARCODE_39, BARCODE_128)
  guests array Guests objects array
    guestId string Guest Id
    firstName string Guest first name
    lastName string Guest last name
    emailAddress string Guest last name
    phoneNumber string Guest phone number
    addons array Guest addons
      id string Addon Id
      guestId string Guest Id
      quantity int Addons quantity
    additionalFields array Guest additional fields
      key string Additional Field Key
      value string, integer Additional Field Value
  addons array Booking item addons
    id string Addon Id
    bookingItemId string Booking item Id
    quantity int Addons quantity
notes string Booking notes
language string, null Customer's language. Can be null
status string Booking status
bookingSource object Booking source
  id string Marketplace Id
  bookingId string Marketplace booking Id
payment object Payment object
  amount string Booking payment amount
  currency string Booking payment currency
contact object Contact person object
  fullName string Contact person full name
  email string Contact person email
  phoneNumber string Contact person phone number
cancellationReason string, null Booking notes
cancellationNote string, null Booking notes
createdAt string Created at date

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Cancel Booking

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "booking.cancel",
  "params": {
    "bookingId" : "boo_d98b3525-2e76-4280-8b78-8c6a13dd6822",
    "reason": "cancellation reason",
    "note": "cancellation note"
  },
  "id": 1
}

use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Booking\CancelBookingRequest;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->booking()->cancel(
    new CancelBookingRequest(
      'boo_d98b3525-2e76-4280-8b78-8c6a13dd6822',
      'cancellation reason',
      'cancellation note'
    )
);

Example Response

{
    "jsonrpc": "2.0",
    "result": {},
    "id": 1
}

Example Error Response

{
    "jsonrpc": "2.0",
    "error": {
        "code": 400,
        "message": "Request validation failed: bookingId:minLength",
        "data": {
            "errors": {
                "bookingId": "Must be at least 1 characters long"
            }
        }
    },
    "id": 1
}

Method

booking.cancel

Params

Name Type Required Description
bookingId
string yes BookingId
reason string, null yes Cancellation reason. Can be empty or null
note string, null yes Cancellation note. Can be empty or null

Result

Name Type Description

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Suppliers List

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "supplier.find",
  "params": {
      "query" : {
          "supplierIds": [],
          "cursor": null
        }
  },
  "id": 1
}
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Supplier\Query;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->supplier()->find(
    new Query(
        ['sup_16648235-611d-47a2-a34c-16cc780745de']
    )
);

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "cursor": {
            "next": "MAe="
        },
        "data": [
            {
                "supplierId": "sup_1cdf451c-666c-4ae9-908e-edc43ceb0f7e",
                "name": "Amazing Activities",
                "contact": {
                    "name": "John Doe",
                    "email": "hello@example.com",
                    "websiteUrl": "https://hello.com",
                    "address": "1-y zavulak Akrescina, 36А, Belarus, Minsk"
                },
                "termsAndConditionsDocumentUrl": "https://example.com/terms-and-conditions",
                "isEnabled": true
            },
            {
                "supplierId": "sup_f0bea5bb-01a3-44e7-a0d5-f6619249eff4",
                "name": "Minsk Walking Tours",
                "contact": {
                  "name": "John Doe",
                  "email": "hello@example.com",
                  "websiteUrl": "https://hello.com",
                  "address": "1-y zavulak Akrescina, 36А, Belarus, Minsk"
                },
                "termsAndConditionsDocumentUrl": "https://example.com/terms-and-conditions",
                "isEnabled": true
            }
        ]
    },
    "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / not available."
  },
  "id": 1
}

Method

supplier.find

Params

Name Type Required Description
query
object
yes Query object
  supplierIds array yes Array of supplier ids. Can be empty array [] to get data about all suppliers
  cursor string, null yes Cursor to the next batch of data. Can be null

Result

Name Type Description
cursor
object
Cursor object
  next string, null Cursor pointer to the next data batch. Can be null if all data was returned
data array Array of suppliers
  supplierId string Supplier Id  title
  name string Supplier name. Can be null
  contact object Contact object. This data will be used to create Supplier Admin User
   name string Contact person name
   email string Contact person email
   websiteUrl string Supplier website url
   address string Full supplier's address
  termsAndConditionsDocumentUrl string Url to a publicly accessible page with Terms and Conditions. Can be empty ""
  isEnabled boolean Is supplier enabled

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Categories List

Example Request

{ 
  "jsonrpc": "2.0",
  "method": "category.find",
  "params": {},
  "id": 1
}
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;
use ExperienceBank\Sdk\ApiClient\Methods\Activity\Query;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$client = new Client($credentials);
$response = $client->category()->find();

Example Response

{
    "jsonrpc": "2.0",
    "result": {
        "data": [
            {
                "id": "1",
                "name": "Walking/Hiking Tours"
            },
            {
                "id": "2",
                "name": "Watersports/Tours"
            },
            {
                "id": "3",
                "name": "Biking Tours"
            },
            {
                "id": "4",
                "name": "Attractions/Museums/Galleries/Aquariums"
            },
            {
                "id": "5",
                "name": "Adrenaline Activities"
            },
            {
                "id": "6",
                "name": "Airborne Experiences"
            },
            {
                "id": "7",
                "name": "Vehicle Tours"
            },
            {
                "id": "8",
                "name": "Events"
            },
            {
                "id": "9",
                "name": "Equipment/Gear Rental"
            },
            {
                "id": "10",
                "name": "Natural Attractions "
            },
            {
                "id": "11",
                "name": "Special Interest"
            },
            {
                "id": "12",
                "name": "Theme Parks"
            },
            {
                "id": "13",
                "name": "Family Experiences"
            },
            {
                "id": "14",
                "name": "Food/Wine Tours"
            },
            {
                "id": "15",
                "name": "Nightlife Experiences"
            },
            {
                "id": "16",
                "name": "Transportation"
            },
            {
                "id": "17",
                "name": "Miscellaneous"
            },
            {
              "id": "18",
              "name": "Sightseeing Tours"
            }
        ]
    },
    "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / not available."
  },
  "id": 1
}

Method

category.find

Params

No params required

Result

Name Type Description
data array Array of categories
  id string Category Id
  name string Category name

Error

Name Type Description
code integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Webhook API

In order to have access to API you must have public key and secret key which are provided by ExperienceBank. Please contact us for more details

The base URL for all API requests is https://api.experiencebank.io/v1. The API only speaks JSON-RPC. All response bodies are JSON and all request bodies are expected to be JSON.

All requests must contain a valid Authorization header authenticating the client and proving the integrity of the request.

If you system speaks PHP you can use our SDK to speed up your integration

Authorization

If you test requests with Postman you can use this pre-request script to sign all requests to ExperienceBank

var apiKey = postman.getEnvironmentVariable('publicKey'),
    apiSecret = postman.getEnvironmentVariable('secretKey'),
    hash = CryptoJS.HmacSHA256(base64url(request.data), apiSecret);

pm.environment.set('authToken', "Basic " + b64EncodeUnicode(apiKey+':'+hash));
function base64url(input) {
    var base64String = b64EncodeUnicode(input);
    base64String = base64String.replace(/=+$/, '');
    base64String = base64String.replace(/\+/g, '-');
    base64String = base64String.replace(/\//g, '_');

    return base64String;
}

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function toSolidBytes(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}

Clients must send an Authorization header in the following format:

Authorization: "Basic " + BASE64($PUBLICKEY + ":" + HMAC_SHA256(BASE64_WITHOUT_PADDING($REQUEST_BODY), $SECRETKEY))

$PUBLICKEY - The client's public key, e.g. pub_b0f41d7fe0e51ea45018358df7f1e12d09580053c3

$SECRETKEY - The client's secret key, e.g. sec_dacd7d383558188d90c6d0b8bdc36a9b028500c6f3

$REQUEST_BODY - Request body, e.g. {"jsonrpc":"2.0","method":"webhook.subscribe","params":{"event":"AvailabilityUpdated","url":"https://webhook.site/daf883cc-b385-44c3-a11b-c0cc79bf25c3"},"id":1}

Subscribe

Example Request

{
  "jsonrpc": "2.0",
  "method": "webhook.subscribe",
  "params": {
    "event": "AvailabilityUpdated",
    "url": "https://webhook.site/daf883cc-b385-44c3-a11b-c0cc79bf25c3"
  },
  "id": 1
}

Example AvailabilityUpdated Payload

{
  "supplierId": "sup_1",
  "activityId": "act_1",
  "optionId": "opt_1",
  "localDateTime": "2021-08-28T10:00:00+01:00",
  "availableCapacity": 16,
  "oldCapacity": 17,
  "ticketCategories": [
    {
      "ticketCategoryId": "10427223",
      "availableCapacity": 16
    },
    {
      "ticketCategoryId": "10436632",
      "availableCapacity": 16
    },
    {
      "ticketCategoryId": "10436633",
      "availableCapacity": 16
    },
    {
      "ticketCategoryId": "10436634",
      "availableCapacity": 16
    }
  ]
}

Example ActivityUpdated Payload

{
  "supplierId": "sup_1",
  "activityId": "act_1"
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "webhookId": "webhook_d4a17a23-a7b2-4550-9356-595a370f8e9e",
    "event": "AvailabilityUpdated",
    "url": "https://webhook.site/daf883cc-b385-44c3-a11b-c0cc79bf25c3",
    "createdAt": "2021-02-25T09:29:26+00:00"
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": 0,
    "message": "Webhook for event \"AvailabilityUpdated\" already exists. You cannot create several webhooks for one event"
  },
  "id": 1
}

Method

webhook.subscribe

Params

Name Type Required Description
event
string yes Event name. See "Support Events" section to get a list of supported events
url string yes Webhook url to which we will send notifications

Supported Events

Event Payload Notes
AvailabilityUpdated
Field
TypeDescription
supplierIdstringSupplier Id
activityIdstringActivity Id
optionIdstringOption Id
localDateTimestringLocal date time using the ISO 8601 datetime format (e.g. 2021-02-25T09:29:26+00:00)
availableCapacityintegerAvailable Capacity
oldCapacityintegerCapacity before update
ticketCategoriesarrayArray of ticket categories available capacities. Can be empty []
  ticketCategoryIdstringTicket category id
  availableCapacityinteger, nullTicket category available capacity. Can be null if not applicable.
This notification will be send if available capacity is less than 30 or capacity became more than 0. You can update cache on your side without making requests to ExperienceBank as you will have all data needed
ActivityUpdated
Field
TypeDescription
supplierIdstringSupplier Id
activityIdstringActivity Id
You will get this notification when an activity is updated

Result

Name Type Description
webhookId
string Webhook Id
event string Event name
url string Webhook url to which we will send notifications
createdAt string Created at date using the ISO 8601 datetime format (e.g. 2021-02-25T09:29:26+00:00)

Error

Name Type Description
code
integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Unsubscribe

Example Request

{
  "jsonrpc": "2.0",
  "method": "webhook.unsubscribe",
  "params": {
    "webhookId": "webhook_46d63dab-8bfc-46ce-baec-0656bf683d20"
  },
  "id": 1
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {},
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": 0,
    "message": "Webhook not found"
  },
  "id": 1
}

Method

webhook.unsubscribe

Params

Name Type Required Description
webhookId
string yes Webhook Id

Result

Name Type Description

Error

Name Type Description
code
integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Find Webhooks

Example Request

{
  "jsonrpc": "2.0",
  "method": "webhook.find",
  "params": {
    "query" : {
      "webhookIds": [],
      "cursor": null
    }
  },
  "id": 1
}

Example Response

{
  "jsonrpc": "2.0",
  "result": {
    "cursor": {
      "next": null
    },
    "data": [
      {
        "webhookId": "webhook_46d63dab-8bfc-46ce-baec-0656bf683d20",
        "event": "AvailabilityUpdated",
        "url": "https://webhook.site/82c72976-74ef-4f3e-9f6a-aec54ba6acea",
        "createdAt": "2021-02-18T14:14:06+00:00"
      },
      {
        "webhookId": "webhook_6369aa75-7675-45b2-9bb1-c0a324c03674",
        "event": "ActivityUpdated",
        "url": "https://webhook.site/82c72976-74ef-4f3e-9f6a-aec54ba6acea",
        "createdAt": "2021-02-22T13:54:06+00:00"
      }
    ]
  },
  "id": 1
}

Example Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "The method does not exist / not available."
  },
  "id": 1
}

Method

webhook.find

Params

Name Type Required Description
query
object
yes Query object
  webhookIds array yes Array of webhook ids. Can be empty array [] to get all webhooks
  cursor string, null yes Cursor to the next batch of data. Can be null

Result

Name Type Description
cursor
object
Cursor object
  next string, null Cursor pointer to the next data batch. Can be null if all data was returned
data array Array of webhooks
  webhookId
string Webhook Id
  event string Event name
  url string Webhook url to which we will send notifications
  createdAt string Created at date using the ISO 8601 datetime format (e.g. 2021-02-25T09:29:26+00:00)

Error

Name Type Description
code
integer Error code. See JSON RPC Specification
message string Error message
data object Error details if available
  errors object Errors key-value object

Activity Categories

Id Name Description
1 Walking/Hiking Tours Walking Tours, Outdoor activities, etc
2 Watersports/Tours Cruises Sailing and water tours, kayaking, jetskis, watersports, etc
3 Biking Tours  
4 Attractions/Museums/Galleries/Acquariums  
5 Adrenaline Activities Paragliding, Bungee jumps
6 Airborne Experiences Helicopter, Air & balloon tours
7 Vehicle Tours Bus Tours, Quads, 4x4s
8 Events Shows Concerts & Sports
9 Equipment/Gear Rental Ski rental, etc
10 Natural Attractions Safari & Wildlife Tours, Cave tours, Geysers, Mountain hikes, etc
11 Special Interest Culture & theme tours
12 Theme Parks  
13 Family Experiences Anything that is family friendly
14 Food/Wine Tours  
15 Nightlife Experiences  
16 Transportation  
17 Miscellaneous Weddings & Honeymoons, Shopping & Fashion
18 Sightseeing Tours City & Sightseeing Tours, Hop On Hop Off Buses, etc

Error Codes

Code Description
100404 Activity not found
100403 Activity not shared
200103 Not enough capacity
200404 Availability not found
200100 Cut off time passed
300400 Max seats exceeded
300401 Min seats less than required

Glossary