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.
Clients must send
Accept
header which permits theapplication/json
content type.Clients must send a
Content-Type
:application/json
for all requests.
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 shopping avenue Bahnhofstrasse and Zürich's famous financial district. Picture stop at the port of "Enge" where you enjoy beautiful vistas of the crystal-clear Lake Zürich. Continue along the lake, passing by the renowned Opera House to the "Zürichberg" district with many superb mansions of glorious past times. A great experience is the ride uphill by cogwheel train (Dolderbahn) to a viewpoint 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 university quarter, you see the Swiss Federal Institute of Technology (ETH), the University of Zürich and Zürich's art museum before reaching the charming Old Town. The last picture stop of this versatile excursion offers views of the patriarchal guild houses, the St. Peter church with Europe's largest clock-face, the Grossmünster church and the Fraumü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 Limmatquai at Sihlquai bus parking.</p>\r\n\r\n<p> </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 "" |
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 |
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"
}
]
}
- If you get a request with BookingId that was already used in reservation you should prolong existing reservation
- Cancel Booking endpoint should support a reservation cancellation as well
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.
Clients must send
Accept
header which permits theapplication/json
content type.Clients must send a valid JSON-RPC request body.
Clients must send
POST
requests only.Clients must send a
Content-Type
:application/json
for all requests.
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 |
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 |
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 |
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.
Clients must send
Accept
header which permits theapplication/json
content type.Clients must send a valid JSON-RPC request body.
Clients must send
POST
requests only.Clients must send a
Content-Type
:application/json
for all requests.
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.
Clients must send
Accept
header which permits theapplication/json
content type.Clients must send a valid JSON-RPC request body.
Clients must send
POST
requests only.Clients must send a
Content-Type
:application/json
for all requests.
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 |
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 |
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.
Clients must send
Accept
header which permits theapplication/json
content type.Clients must send a valid JSON-RPC request body.
Clients must send
POST
requests only.Clients must send a
Content-Type
:application/json
for all requests.
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 |
|
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 |
|
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
- Activity - This is the Product you provide/sell/redistribute, it can be Activities, Tours, Products, Concerts etc...
- Partner - Provider of content/activities. A booking software used by suppliers
- Supplier - Provider of activities like an adventure or a bus company (Selling their Offers trough a Partner)
- Distribution Partner - Marketplaces that resell Activities like DMO's and OTA's