Introduction
Welcome to the Grand Canyon OnePoint API service. This API can be used to check availbility and book reservations on Papillon Helicopters, Grand Canyon Airlines, Grand Canyon Helicopters, and Scenic Airlines.
The service presents a single endpoint (https://api.grandcanyononepoint.com/) and all messages should be POSTed there as JSON. We typically provide a single set of authentiation credentials and - initially - place your account into 'test' mode. This permits developers to build integrations against production data and eliminate remapping resources for production.
Authentication
Nearly every call in the GCOP API requires a valid sessionKey, which will be generated for you by the "authenticate" message. By default session keys expire 24 hours from the time they are created. As a developer, you are free to override this default with either a shorter or longer expiration depending on your needs. Note that requesting a password reset from our technical support staff will cause all currently-issued session keys to be invalidated.
Request Fields
To get an security key POST the following request filling in the appropriate fields with your information: Note that the lifetime key is optional. By default the session key will expire in 24 hours from its creation. However, you are free to define how long you wish this session key to be valid. Values are in seconds.
{
"request":"authenticate",
"userName":"yourUserName",
"password":"yourPassword",
"agencyID":"yourAgencyID",
"lifetime":86400
}
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
userName | no | Your user name provided for you by our integration team |
password | no | The password provided by the integration team |
agencyID | no | The UUID agency identifer, you guessed it, also provided by the integration team |
lifetime | yes | The number of seconds that you want this session to live. Default: 86400 (24 hours) if not specified. |
Response Fields
You should get a result similar to the following:
{
"success": 1,
"errors": [],
"sessionKey": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJQYXBpbGxvbkdyb3VwIiwic3ViIjoiRGlyZWN0Q29ubmVjdEFjY2VzcyIsImF1ZCI6ImQ0OGQ3MDA4LTA2ZTktMTFlOC1iYTg5LTBlZDVmODlmNzE4YiIsImV4cCI6MTU1NDgzNjA4NiwibmJmIjoxNTIzMzAwMDg2LCJpYXQiOjE1MjMzMDAwODZ9.801602c0b13d246cce4c88f8a1e5a35d9d6b00ddeb66510ed8dbfe423b9e5587"
}
Field | Description |
---|---|
success | Defines success or failure |
sessionKey | The session key generated by your request for use in subsequent calls. |
Errors
The 'success' field is the primary indicator if the call requested succeeded or not.
{
"success": 0,
"errors" : {
message: "An error message describing what went wrong.",
"code": 801092
}
}
Errors are rendered using a simple datamodel illustrated here. All calls are entirely succesful or complete failure. All responses from our API contain a "success" field that will be either 1 or 0 depending on the call's success or failure. An error will also provide a message describing the problem and an error code. Should you run into any odd or unsolveable errors we will need both the message and the error code.
Products Catalog
Product Universes
{
"sessionKey":"yourSessionKey",
"request":"listProductUniverses"
}
The above command returns JSON structured like this:
{
"success": 1,
"universe": [
{
"name": "Universe name #1",
"uuid": "25280c6a-b58a-493b-bd24-7adb497c1fe7"
},
{
"name": "Universe name #2",
"uuid": "7f7b624b-e21f-487c-bd3f-bce724fbda7f"
}
]
}
In our API, the term 'Universe' and 'Category' are often used interchangably. A product universe is simply a collection of products that share a common attribute. In the case of the most current version of our API the universes group together the tours that are offered by our different brands. Thus all tours offered by Grand Canyon Helicopters will be contained within a single universe as would all products by Scenic Airlines. The only exception to this rule is that we may, from time to time, create a universe to house promotional tours.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
universe | An array of Universe Objects detailing the product universe to which the agency is subscribed. |
Universe Object Structure
Field | Description |
---|---|
name | Defines the name of the product universe/category. |
uuid | The unique identifier of that category. |
Product Universe Contents
{
"request":"showProductUniverse",
"sessionKey":"yourSessionKey",
"universeID":"aProductUniverseUUID"
}
The above command returns JSON structured like this:
{
"success": 1,
"universeID": "25280c6a-b58a-493b-bd24-7adb497c1fe7",
"products": [
{
"name": "Grand Celebration",
"code": "PBW4",
"productID": "925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"cityCode": "LAS",
"airportCode": "BVU"
},
...
...
Each product universe will contain a list of productIDs and some meta information about that product such as the name, originating city & airport code, as well as the products code (similar to product SKU).
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
universeID | no | A valid product universe UUID |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
universeID | The UUID of the product universe requested for listing. |
products | An array of Product Objects. |
Product Object Structure:
Field | Description |
---|---|
name | The brochure name of the tour/product. |
code | The brochure code / tour code / sku of the product |
productID | The API uuid for this particular product |
cityCode | The IATA city code identifiying the departing city for this tour |
airportCode | The IATA airport code defining the departing airport for this tour (if relevant). If this tour is not by aerial conveyance then it will just match the cityCode. |
Get All Categories & Products
{
"request":"getEntireCatalog",
"sessionKey":"yourSessionKey"
}
The above command returns JSON structured like this:
{
"success": 1,
"catalog": [
{
"name": "To West Rim External",
"uuid": "25280c6a-b58a-493b-bd24-7adb497c1fe7",
"products": [
{
"name": "Grand Celebration G1",
"code": "PBW4",
"productID": "925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"cityCode": "LAS",
"airportCode": "BVU"
},
{
"name": "Golden Eagle G1",
"code": "PBW1",
"productID": "c456c056-06e7-11e8-ba89-0ed5f89f718b",
"cityCode": "LAS",
"airportCode": "BVU"
}
],
},
{
"name": "To South Rim External",
"uuid": "7f7b624b-e21f-487c-bd3f-bce724fbda7f",
"products": [
{
"name": "Canyon Conniessour G1",
"code": "SBG4",
"productID": "e0f2e7df-0a21-4cec-a5f2-e1da4e53c487",
"cityCode": "LAS",
"airportCode": "BVU"
},
...
...
By far the easiest and most direct way to find all the products and categories an agency is subscribed to is the "getEntireCatalog" call. Primarily a convenience feature, it wraps the functionality of both "listProductUniverses" and "showProductUniverse" into a single result.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
catalog | A list of product universe lists with their products nested inside. |
Universe Structure:
Field | Description |
---|---|
name | Defines the name of the product universe/category. |
uuid | The unique identifier of that category. |
products | A list of Product Objects that belong to its parent category. |
Get Product Descriptions
{
"request":"getDescription",
"sessionKey":"yourSessionKey",
"productID":"productUUID"
}
The above command returns JSON structured like this:
{
"success":1,
"shortDesc":"A undecorated short line of description that will be less that 350 characters",
"longDesc":"A possibly lengthy description that may contain simple html formatting like bold, paragraph, and the like",
"textAvailable":true,
"imagesAvailable":false,
"hash":"e914a315882e3a7df45fa19bf10ec8633d1c1403"
}
The call will return several fields that, at the moment, return a short and long description of the product id passed in. In addition we provide a hash of the values so that consumers can quickly check to see if either the descriptions or images have changed. If the hash does not match your stored hash you should consider that all fields in the return values have changed.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
productID | no | The UUID of the product for which the description should be fetched. |
Response Fields
Field | Type | Description |
---|---|---|
success | int | Defines success or failure |
shortDesc | string | An undecorated string containing a very short description of the product (350 chr or less) |
longDesc | string | A detailed description of the product, may contain basic html elements. |
textAvailable | boolean | True if the text description for this product is available. |
imagesAvailable | boolean | True if images for this product is available. |
hash | string | A hash representing the state of the images and descriptions. If it changes, consider all the descriptive content invalid. |
Availability & Price
Our tours, availability structure, and pricing are built around a day model and are contingent upon how many passengers you are looking for. While this might seem strange, one must understand that - for the most part - our tours and experiences are operated on smaller and more personal aircraft; thus we make every effort to ensure that groups and families are not separated. Thus it is important for us to know how many of each (adult vs child) are planning to take the experience so we can validate space for them.
When presented with the requirement (eg: 2 adults, 1 child, on August 10) we will process your request and return ONLY the itineraries that match your criteria.
The "getCalendar" request is the only exception to this rule. The "getCalendar" call will show you all itineraries that have at least 2 seats available.
Single Day Availability Search
Request
{
"request": "checkAvailability",
"sessionKey": "yourSessionKey",
"productID": "aProductUUID",
"adult": 1,
"child": 1,
"date": "YYYY-MM-DD",
"withHotels": true
}
Response
{
"success": 1,
"Attributes": [{
"AttributeId": "test1",
"Name": "ext1"
}, {
"AttributeId": "1a119a38-ffbe-11e7-ba89-0ed5f89f718b",
"Name": "Special Service Notes"
}, {
"AttributeId": "2dea9802-ffbe-11e7-ba89-0ed5f89f718b",
"Name": "VoucherID"
}],
"Itineraries": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": "PC303",
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30"
},
...
...
{
"ItineraryID": 1080,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "18:00",
"EndRangeTime": "18:00",
"EstPickupTime": false,
"PickupClass": "PC304",
"AdultPrice": 294,
"AdultFees": 85,
"ChildPrice": 274,
"ChildFees": 85,
"TotalPrice": 738,
"DeptTime": "Sunset Fare at 18:00"
}],
"PickupServiceAvailable": true,
"PickupClassHotelList": {
"PC303": [{
"id": "1067",
"lable": "Alexis Park",
"estimatedMinsPrior": 80
}, {
"id": "1070",
"lable": "Americana 5 At Industrial Rd",
"estimatedMinsPrior": 75
}, {
"id": "1232",
"lable": "Americas Best Value Inn",
"estimatedMinsPrior": 75
}, {
"id": "1843",
"lable": "Aria Resort",
"estimatedMinsPrior": 90
}, {
"id": "192",
"lable": "Arizona Charlie's (Boulder Hwy)",
"estimatedMinsPrior": 65
}, {
"id": "193",
"lable": "Arizona Charlie's (Decatur)",
"estimatedMinsPrior": 125
}, {
"id": "1505",
"lable": "Artisan Hotel Boutique",
"estimatedMinsPrior": 90
},
...
}
}
This call will return all available itineraries for a specific day, any additional attributes necessary to book the product, and if desired or necessary the hotel pickup lists (yes, potentially plural).
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
productID | no | The UUID of the product you want to check availability for |
adult | no | The integer number of adults |
child | no | The integer number of children |
date | no | The date that you need to look at in Year-Month-Day format eg 2019-06-02 |
withHotels | yes | Include the hotel pickup class definitions in the result |
Response Fields
Root Response Object
Field | Description |
---|---|
success | Defines success or failure |
Attributes | An array of attributes that can, but do not have to, contain additional information. We use these fields to satisfy different integration requirements client by client. Some fields such as the voucher id are common among many implemenations. This should be a point of discussion during integration. |
Itineraries | An array of available itineraries for this specific day. |
PickupServiceAvailable | A boolean that informs if we offer hotel pickup service on this product. |
PickupClassHotelList | An object whose keys are the titles of Pickup Classes. Contained inside each pickup class is a list of hotels services by that pickup class. |
Attributes
Field | Description |
---|---|
AttributeId | The UUID assigned to this partiuclar attribute. |
Name | The label of this particular field. |
Itineraries
Field | Description |
---|---|
ItineraryID | An integer id representing this specific itinerary. Additionally, it's also the number of minutes elapsed since midnight (00:00) of the departing day. |
NoAdults | Number of adults as specified in the request |
NoChildren | Number of children as specified in the request |
StartTimeRange | Effectively the departure time of this itineary in 24hr format. |
EndRangeTime | Depreciated, originally our itineraries covered a time span. This is no longer true and this field may be removed in future versions. |
PickupClass | Defines the pickup class hotel list to use when displaying a choice of hotel pickups. If pickup is not available on the product this will be boolean false. |
AdultPrice | The base price per adult guest |
AdultFees | The fees per adult |
ChildPrice | The base price per child guest |
ChildFees | The fees per child |
TotalPrice | The purchase total for this itinerary based of on the total of adults, children, and associated fees. |
DeptTime | An english describing both the fare type and the departure time |
Pickup Classes
All itineraries return a PickupClass value in their itineraries and that value serves as a lookup for values in the PickupClassHotelList. This is necessary because pickup availability and the estimated mins before pickup can change from itinerary to itinerary due to known weather patterns, traffic patterns, airspace congestion, shuttle size, and a variety of other variables. We do our best to ensure that passengers spend as little time in shuttles and as much time as possible on their actual experince.
Field | Description |
---|---|
{PickupClass ID} | An array of hotels at which pickup occurs. |
Hotel Structure
Field | Description |
---|---|
id | A potentially alphanumeric code representing a specific hotel |
label | An english language label for the hotel, usually the hotel name. |
estimatedMinsPrior | The time the pickup will occur represented by the number of mins to subtract from the departure time of the guests' selected itinerary. |
Date Span Availabity Search
Single Product Request
{
"request":"checkAvailabilitySpan",
"sessionKey":"",
"productID":"925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"adult": 1,
"child": 1,
"startDate": "2018-06-01",
"endDate":"2018-06-30",
"withHotels": true
}
Single Product Response
{
"PickupClassHotelList": {
"PC303": [{
"id": "1067",
"lable": "Alexis Park",
"estimatedMinsPrior": 80
}, {
"id": "1070",
"lable": "Americana 5 At Industrial Rd",
"estimatedMinsPrior": 75
}
...
},
"Dates": {
"2018-06-01": [
{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": "PC303",
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
}, ...]
...
...
"2018-06-30": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": "PC303",
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30"
},
Multi-Product Request
{
"request":"checkAvailabilitySpan",
"sessionKey":"",
"productList":"925d8ee4-6bb6-4779-b8b5-aaa23498ea08,925d8ee4-6bb6-4779-b8b5-aaa23498ea08,925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"adult": 1,
"child": 1,
"startDate": "2018-06-01",
"endDate":"2018-06-30",
"withHotels": true
}
Multi-Product Response
{
"success":1,
"errors":{},
"productList":["925d8ee4-6bb6-4779-b8b5-aaa23498ea08","925d8ee4-6bb6-4779-b8b5-aaa23498ea08","925d8ee4-6bb6-4779-b8b5-aaa23498ea08"],
"productAvailability":{
"925d8ee4-6bb6-4779-b8b5-aaa23498ea08": {
"PickupClassHotelList":{
... see single product response
},
"Dates":{
... see single product response
}
}
}
}
In addition to the single day search, developers can now get batch availability by specifying a start date and an end date. Note that the end date is INCLUSIVE! Currently the distance between the start date and end date cannot exceed 180 days.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
productID | no | The UUID of the product for which you want to check availability |
productList | yes | If checking multiple products provide a comma sepearted list of UUIDs |
adult | no | The integer number of adults |
child | no | The integer number of children |
startDate | no | The starting date for the search formatted in YYYY-MM-DD (eg. 2019-06-01) |
endDate | no | The ending date (inclusive) of the search also in YYYY-MM-DD |
withHotels | yes | Include the hotel pickup class definitions in the result |
Response Fields
Root Response Object
Field | Description |
---|---|
success | Defines success or failure |
PickupClassHotelList | An object whose keys are the titles of Pickup Classes. Contained inside each pickup class is a list of hotels services by that pickup class. |
Dates | An object whose keys are the dates returned in the search, starting at startDate and ending with endDate |
Date Specific Object
Field | Description |
---|---|
{YYYY-MM-DD} | An array of Itineraries that match, for the date specified in the key, the adult/child availability criteria. |
For the description of the itinerary object see 'Single Day Availability' search documentation above.
Get Calendar
Request
{
"request":"getCalendar",
"sessionKey":"",
"productID":"925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"month":6,
"year":2018
}
Response
{
"success": 1,
"dayArray": {
"1": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
"seatsAvailable": 44
}, {
"ItineraryID": 1095,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "18:15",
"EndRangeTime": "18:15",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 294,
"AdultFees": 85,
"ChildPrice": 274,
"ChildFees": 85,
"TotalPrice": 738,
"DeptTime": "Sunset Fare at 18:15",
"seatsAvailable": 54
}],
...
"30": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
"seatsAvailable": 46
}, {
"ItineraryID": 1110,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "18:30",
"EndRangeTime": "18:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 294,
"AdultFees": 85,
"ChildPrice": 274,
"ChildFees": 85,
"TotalPrice": 738,
"DeptTime": "Sunset Fare at 18:30",
"seatsAvailable": 54
}]
},
"dateArray": {
"2018-06-01": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
"seatsAvailable": 44
}, {
"ItineraryID": 555,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "09:15",
"EndRangeTime": "09:15",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 284,
"AdultFees": 85,
"ChildPrice": 264,
"ChildFees": 85,
"TotalPrice": 718,
"DeptTime": "Prime Time Fare at 09:15",
"seatsAvailable": 37
}],
...
"2018-06-30": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
"seatsAvailable": 46
}, {
"ItineraryID": 1110,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "18:30",
"EndRangeTime": "18:30",
"EstPickupTime": false,
"PickupClass": false,
"AdultPrice": 294,
"AdultFees": 85,
"ChildPrice": 274,
"ChildFees": 85,
"TotalPrice": 738,
"DeptTime": "Sunset Fare at 18:30",
"seatsAvailable": 54
}]
}
}
This is the only availability and pricing check function that does NOT require a number of adults and children and is intended, primarily, to get a sense of the available departure time and prices for a calendar month.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
productID | no | The UUID of the product you want to check availability for |
month | no | An integer representing the month requested |
year | no | A integer representing the year requested |
Response Fields
Root Response Object
Field | Description |
---|---|
success | Defines success or failure |
dayArray | An object who's keys represent the day of the month searched for. Each one contains an array of Itineraries for the day in question. |
dateArray | The exact same information in dayArray but the object keys are the date in YYYY-MM-DD format for convenience. |
In both cases see 'Single Day Availability Search' for an explaination of the contents of the itinerary object.
Making Reservations
There are two different workflows for making reservations through our API. The workflow that is relevant to you depends on if your agency has billing/voucher privileges with our activity providers.
Non-Billing Agency Workflow
- Create a Quote : This guarentees the prices on a product for a specific day for a specific number of guests.
- Quotes have a specific liftime and can expire.
- It is rare but possible for the price of an itinerary to change between the time you run your check availability call and the time you create a quote. The availability and pricing information presented in the quote is authoritative.
- This step does NOT guarentee seating availability, only price.
- Process the Reservation : This step pulls the seats out of inventory and creates a reservation number.
- Reservations must be paid within the alloted time or they will expire and be automatically cancelled.
- This step guarantees seating availability.
- Tender Payment
- Using the resources provided you must tender payment on the reservation before it expires (10 mins by default).
- Verify Payment
- Verify that the quote is no longer 'pending'.
Billing/Voucher Workflow
- Create a Quote : This guarantees the prices on a product for a specific day for a specific number of guests.
- It is rare but possible for the price of an itinerary to change between the time you run your check availability call and the time you create a quote. The availability and pricing information presented in the quote is authoritative.
- Quotes have a specific liftime and can expire.
- This step does NOT guarantee seating availability, only price.
- Process the Reservation : This step pulls the seats out of inventory and creates a reservation number.
- This step guarantees seating availability.
- Reservations must be paid within the alloted time or they will expire and be automatically cancelled.
Create Quote
Request
{
"request": "quote",
"sessionKey": "yourSessionKey",
"productID": "925d8ee4-6bb6-4779-b8b5-aaa23498ea08",
"adult": "1",
"child": "1",
"date": "2018-05-22",
"withHotels": true
}
Response
{
"success": 1,
"Attributes": [{
"AttributeId": "test1",
"Name": "ext1"
}, {
"AttributeId": "1a119a38-ffbe-11e7-ba89-0ed5f89f718b",
"Name": "At what hotel are the guests staying"
}, {
"AttributeId": "2dea9802-ffbe-11e7-ba89-0ed5f89f718b",
"Name": "VoucherID"
}],
"Itineraries": [{
"ItineraryID": 390,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "06:30",
"EndRangeTime": "06:30",
"EstPickupTime": false,
"PickupClass": "PC303",
"AdultPrice": 259,
"AdultFees": 85,
"ChildPrice": 239,
"ChildFees": 85,
"TotalPrice": 668,
"DeptTime": "Early Bird Fare at 06:30",
"seatsAvailable": 44
},
...
...
{
"ItineraryID": 1080,
"NoAdults": 1,
"NoChildren": 1,
"StartRangeTime": "18:00",
"EndRangeTime": "18:00",
"EstPickupTime": false,
"PickupClass": "PC304",
"AdultPrice": 294,
"AdultFees": 85,
"ChildPrice": 274,
"ChildFees": 85,
"TotalPrice": 738,
"DeptTime": "Sunset Fare at 18:00",
"seatsAvailable": 54
}],
"PickupServiceAvailable": true,
"PickupClassHotelList": {
"PC303": [{
"id": "1067",
"lable": "Alexis Park",
"estimatedMinsPrior": 80
}, {
"id": "1070",
"lable": "Americana 5 At Industrial Rd",
"estimatedMinsPrior": 75
},
...
...
{
"id": "1523",
"lable": "Wynn Las Vegas",
"estimatedMinsPrior": 115
}]
},
"QuoteID": "9f79b180-1dd5-11b2-bb1a-6f0d4cb7849e",
"QuoteCreated": 1523321695,
"QuoteExpires": 1523322895,
"date": "2018-05-22"
}
Does the format of the quote response look familiar? If you're thinking that it looks a great deal like the "Single Day Availability Search" you would be correct. 99% of the format is identical. However, it's the differences that are very important.
A few notes about Quotes:
- Quotes have a time life. Once expired they cannot be used to create a new reservation.
- The time at which a quote expires is noted in the response payload.
- A quote can be use only once and the passenger counts on the quote and the reservation must match exactly.
- The target date of a quote and the date of a new reservation must also match exactly.
- Should the number of adults or children change or should the tour start date change, a NEW quote is required.
- A quote can be used only once to create a single reservation.
- It is possible though rare that the price of an itinerary might change between the availability search and the quote generation. At all times the information on the quote is authoritative.
- A quote guarantees price ONLY. Seats are not guaranteed until the reservation ("reserve") call is completed.
- The Net Rates delivered at the Quote stage are the rates that the activity operator ("Scenic Airlines", "Papillon Helicotpers", etc, etc) will expect to collect. These prices are not Sale prices and should not be exposed directly to your customers. They are the net rates to YOU as the agency and do not have markup or commission built into them.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
productID | no | The UUID of the product you want to check availability for |
adult | no | The integer number of adults |
child | no | The integer number of children |
date | no | The date that you need to look at in Year-Month-Day format eg 2019-06-02 |
withHotels | yes | Include the hotel pickup class definitions in the result |
Response Fields
Root Response Object
Field | Description |
---|---|
success | Defines success or failure |
Attributes | See the "Single Day Availability Search for an explanation." |
Itineraries | See the "Single Day Availability Search for an explanation." |
PickupServiceAvailable | See the "Single Day Availability Search for an explanation." |
PickupClassHotelList | See the "Single Day Availability Search for an explanation." |
QuoteID | This the UUID of this specific quote. You will need this during the reservation phase of this process. |
Reserve Seats
Request
{
"request":"reserve",
"quoteID":"9f442ae0-1dd5-11b2-ac02-bd9d5c5a9c61",
"sessionKey": "yourSessionKey",
"itineraryID":555,
"hotelID": 1441,
"masterFirstName":"Roper",
"masterLastName":"Clayton",
"emailAddress":"coy@papillon.com",
"phoneNumber":"7024085411",
"markup": {
"adult":440,
"child":420
},
"paxArray": [
{
"FirstName": "Coy",
"LastName": "Clayton",
"BodyWeight": "280",
"Type": "Adult"
},
{
"FirstName": "Logan",
"LastName": "Fischer",
"BodyWeight": "55",
"Type": "Child"
}
],
"attribArray": [
{
"id": "2dea9802-ffbe-11e7-ba89-0ed5f89f718b",
"value": "XV298107-1290-20091"
},
{
"id": "1a119a38-ffbe-11e7-ba89-0ed5f89f718b",
"value": "Luxor"
}
]
}
Response
javascript { "orl": "2459828", "hotel": "Hilton Grand Vacation Suites At The Flamingo", "pickup": "Outside - Main Entrance", "pickupTime": "07:30", "adultNetRate": 369, "childNetRate": 349, "adultSaleRate": 440, "childSaleRate": 420, "totalSale": 860, "quoteID": "9f7a0700-1dd5-11b2-8ce1-a3abbdc3c9df", "resExpires": true, "resExpireAfter": 1523324855, "ccPaymentReady": true, "ccPaymentRequired": true, "ccPaymentLink": "https:\/\/ourPaymentGateway.com\/card\/do\/en\/63da5fcc-6abf-48bd-8aef-abdb9bbaec6b%7C5acc1d267bbba%7Ca89fb1fc-4525-487d-8ebb-42e500258759", "ccPaymentExpires": 1523324855, "success": 1, "errors": [] }
This call its the call that guarantees seats! This is the call that generates an actual, living, breathing reservation. It's powerful, but not overly complex. There are a few things to keep in mind, however.
- Any reservation may be cancelled regardless of cancellation policy so long as:
- It's status is NOT paid.
- It is cancelled within 10 mins of its creation.
- If you are on billing/voucher, within the products cancellation penalty window, and the reservation has lived LONGER than 10 mins you may be billed for the seats.
- If the seats on your chosen itinerary are no longer available (because they were sold in the interim) this 'reserve' call will fail with an error code. You may use your existing quote to book any other itinerary but you may not change days or passenger counts without requoting.
- If the product provides a pickup then a hotelID entry is required. That hotelID can be the "Unknown" hotel if necessary, but accurate pickup information allows us to provide instant pickup information to you (and thus your guest). If you omit this field or do not provide a valid hotelID you will receive an error.
- The submision of a quoteID is required. This demonstrates to us that either yourself, your system, or your agent has seen the rate that we will bill/charge for these seats and, as stated in our rate agreement, agree to pay them.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
quoteID | no | The UUID of a valid, unexpired quote that matches the pax count, and date exactly. |
itineraryID | no | The integer itineraryID of the time you wish to book |
hotelID | yes | The hotelID that identifies where the guest is staying. Optional only if the product does NOT provide hotel pickup. For consistency you may provide this field as boolean false if you would like to send it regardless. |
masterFirstName | no | The primary contact's first name. This will be the name that the reservation is searchable under. |
masterLastName | no | The primary contact's last name. |
emailAddress | no | The primary contact's email address. |
phoneNumber | no | The primary contact's best reach phone number, often cell phone number, in the event of inclement weather or other such unlikely disruption. |
markup | yes | An json object that defines the target SALE price. See Below* |
paxArray | no | An array of javascript object(s) that describe the names and weights of the guests to travel. See Below* |
attribArray | no | An array of objects that describe the values for various custom attributes as defined in the availability and quote stages. |
Markup Object
API useres are free to define their own sale prices based on our variable net rate. This is accomplished by submitting a 'markup' object along with the 'reserve' request. The sale price is a price ABOVE the net rate that has been quoted to you. For example, if we deliver $240 adult & $220 child net rate you may include a markup object that says you want to charge $260 adult and $240 child. This configuration would result in a $20 adult / $20 child commission back to you.
Field | Optional | Description |
---|---|---|
adult | no | A price that you wish to charge for a adult. |
child | no | A price that you wish to charge for a child. |
In all cases the adult and child value may NOT be less that the net rate quoted to you for the specific itinerary.
paxArray
The paxArray (short for Passenger Array) defines the information that we need about every person traveling on this reservation. Each person represents a different passenger object within the paxArray array. Passenger are defined like this:
Field | Optional | Description |
---|---|---|
FirstName | no | The first name of the passenger |
LastName | no | The last name of the passenger |
BodyWeight | no | The passengers weight in US Pounds (lbs) only please. |
Type | no | The passenger type either 'Adult' or 'Child' |
Note that the system will count the number of adults and number of children and validate that against the number of adults and children used to build the quote.
attribArray During both the quote and availability phase there were fields marked "Attributes". Each attribute was associated with a UUID. To provide values for those attributes add 1 json object (as defined below) to the attribArray. 1 object per attribute.
Field | Optional | Description |
---|---|---|
id | no | The UUID of the attribute for which you are providing a value |
value | no | The value of that attribute. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
orl | Provides the Order Reservation Locator, or Reservation Number in general parlance. |
hotel | The hotel at which the guest will be picked up at. |
pickup | The specific pickup point for the guests |
pickupTime | The time at which the guests will be picked up in 24hour format. |
adultNetRate | The total Net Rate (including fees) quoted and booked for adults on this reservation |
childNetRate | The total Net Rate (including fees) quoted and booked for children on this reservation if applicable |
totalSale | The final amount that will be billed or charged to a credit card |
quoteID | The ID of the quote used to create this reservation |
resExpires | A boolean indicating if the reservation expires. Voucher/billing agencies reservations do not expire and, in fact, the rest of the fields are irrelevant to you. |
resExpiresAfter | A unix timestamp indicating when the reservation will expire if left unpaid. |
ccPaymentReady | In most cases this will be true indicating that we have a credit card payment session waiting to be paid. In the unlikely event that this is false a payment session can be initiated using the 'pay' call. |
ccPaymentLink | A link to our payment processing gateway that can be used to submit payment on this reservation. |
ccPaymentExpires | The unix timestamp after which the payment link will die and be unavailable. Another payment session and link can be created using the 'pay' call. |
Create Payment
Request
{
"request":"pay",
"quoteID":"9f7a0700-1dd5-11b2-8ce1-a3abbdc3c9df",
"sessionKey":"yourSessionKey"
}
Response
{
"success": 1,
"ccPaymentReady": true,
"ccPaymentRequired": true,
"ccPaymentLink": "https:\/\/ourPaymentGateway.com\/card\/do\/en\/63da5fcc-6abf-48bd-8aef-abdb9bbaec6b%7C5acc1d267bbba%7Ca89fb1fc-4525-487d-8ebb-42e500258759",
"ccPaymentExpires": 1523340646,
"orl": "2459828"
}
Our payment system is entirely separate from our API gateway infrastructure to improve security and PCI compliance. Transactions are processed directly by Authorize.net in order to guarentee the best in payment card security. As such, our payment sessions have a time life. Should a payment session expire or not immediately be available you can easily generate one with this call and the quoteID attached to the reservation you wish to pay.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
quoteID | no | The UUID of a valid and reserved quote. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
ccPaymentReady | This will always be true. |
ccPaymentLink | A link to our payment processing gateway that can be used to submit payment on this reservation. |
ccPaymentExpires | The unix timestamp after which the payment link will die and be unavailable. |
Payment Status
Request
{
"request":"paymentStatus",
"quoteID":"9f9f6e80-1dd5-11b2-8721-c37297e66fab",
"sessionKey":"your session key"
}
Response
{
"success":1,
"paid":true,
"seatsHeld":true,
"expired":true
}
You may use the 'paymentStatus' call to directly inquire to the payment, seat status, and expiration status of an existing quote.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
quoteID | no | The UUID of a valid and reserved quote. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
paid | Boolean true or false depending upon if the payment has been fully recieved and processed. |
seatsHeld | Boolean true or false depending upon if the quote in question is holding seats pending payment (if applicable) |
expired | Boolean true or false depending upon if the quote itself has expired. |
View Pending
Request
{
"request":"pending",
"sessionKey": "your session key"
}
Response
{
"success": 1,
"quotes": [
{
"quoteID": "9f7a7630-1dd5-11b2-bfdb-73fd76637600",
"created": 1523326731,
"expires": 1523327631,
"orl": "2459829",
"lastName": "Clayton",
"createdLocal": "2018-04-09 19:18:51 PDT",
"expiresLocal": "2018-04-09 19:33:51 PDT"
},
...
]
}
Depending on your use case you may wish to defer payment of a booking until later. The pending call lists all quotes & reservations that have been 'reserved' but not yet paid for. You can then use the quoteID to create a new payment section.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
quotes | An array of quote objects or an empty array if no items are pending. |
Quote Objects
Field | Description |
---|---|
quoteID | The quote that is attached to this pending reservation. |
created | A unix timestamp that marks when the reservation was created. |
expires | A unix timestamp indicating when this reservation will expire and auto-cancel |
orl | The order reservation locator or reservation number under which this is booked. |
lastName | The master last name of the primary contact on the reservation |
createdLocal | The readable representation of the created timestamp in PT |
expiresLocal | The readable representation of the expires in PT |
Cancel a Booking
Request
{
"sessionKey": "your session key",
"request":"cancel",
"ResLocator":"2459829"
}
Response
{
"success": 1,
"ResLocator": "2459829"
}
Sometimes things just don't work out. The client decides they don't like to fly, are afraid of heights, or cancel for any number of reasons. That is what this 'cancel' call is used for. There are a couple caveats in its use however. Iterated below:
- A reservation can be cancelled through the API if:
- It is UNPAID or does not require payment.
- It is outside the product's cancellation window OR the reservation was created less than 10 mins ago
- All of our UNPAID reservations come with a 10 min grace period during which you may freely cancel the reservation.
- This is useful when as a billing/voucher client, you need to insure payment from a guest
- need just a little more time to sell the guest on an experience.
Request Fields
Field | Optional | Description |
---|---|---|
request | no | Defines what action is being requested |
sessionKey | no | Your session key generated by a call to the 'authenticate' function. |
ResLocator | no | the ORL/Reservation number you wish to cancel |
Response Fields
Field | Description |
---|---|
success | Defines success or failure |
ResLocator | The ResLocator submitted in the request |