A trip in our system is a representation of a trip in the real world. A trip in the real world has many components, such as prices, operating days, operational constraints etc. Similarly, a trip in our system is composed of different components such as pricing rules, availability data, trip related settings etc.
If a trip/tour in which all groups that have booked for the same departure, travel together, then such trip/tour is called as group tour in our system. Whereas if a trip/tour is conducted privately for a person or a family then such trips/tours are called as private tours. Trips which are conducted on special request may also be called private tours.
All content related fields of a trip such as the name of the trip, location, detailed itinerary, highlights, inclusions, exclusions etc are all stored in the Trip model in our system. Whereas the transaction related fields such as the pricing rules, operating days, booking lead time seconds(how close to a departure can customers make bookings through the storefront), minimum and maximum number of passengers for the trip etc are all stored in Trip option (a.k.a Trip variant). Every trip in our system will have atleast one Trip option. Whenever a new trip is created, by default a trip option is added to a trip with all transaction related fields in it.
NOTE: Trip option or Trip variant are the SAME thing in our system.
A single trip can have multiple trip options or trip variants. For example, consider you have a trip which operates in peak season with different pricing and in off season with different pricing. This clearly means that there are 2 variants of the same trip. Since all the pricing rules and operating days are stored in trip options, you can easily model this trip in our system, by creating a single trip with 2 trip options, one for each season. You don't have to create 2 trips unnecessarily.
Besides trip options, A trip also has Addons, Pax types (passenger types), Custom fields etc which will be explained in detail shortly.
Trip option is the most vital part of the trip model as all important transaction related fields which are used while booking a trip are stored in a trip option.
The two most important things that are stored in trip options are Pricing rules and Open Slots.
Open slots stores recurrence rules which are used to compute operating days of the trip. The main fields which specifies the recurrence rules are starts_at, ends_at, days_of_week and excluded_times.
For example if the entry in the Open slots looks something like this:
{ "starts_at": "2014-08-01", "ends_at": "2014-08-31", "days_of_week": [false, true, true, true, true, true, false], "excluded_times": ["2014-08-15"], ... }then it means that the trip is operating on all WEEKDAYS from 1st August 2014 till 31st Aug 2014 except on 15th August 2014. For the period between `starts_at` and `ends_at`, `days_of_week` array specifies the days on which the trip is operating. `days_of_week` array starts from Sunday. The boolean value specifies whether the trip is operating on that day or not. For example, the first value is false, which means that the trip is not operating on the Sundays which falls in the specified period. If the trip is not operating on some days within the specified range then they will be listed in `excluded_times` array.
Pricing rules are used to define pricing for your trip. They basically represents the pricing model of your trip.
Vacation Labs offers 3 types of pricing for any trip.
In Per pax pricing (per passenger pricing), you can specify different rates for different passenger types. For example, if you have 2 pax types defined, say Adult and Child, then you can specify that the Adult should be charged 2000 INR, whereas the Child should be charged 1500 INR only.This type of pricing is called per pax pricing.
If a trip has per pax pricing defined, then in the API response it will represented as follows:
"pricing_rules": [ { "client_id": 64, "id": 4005, "name": "Per Passenger charge", "trip_option_id": null, "pricing_type": "per_pax_pricing", "per_pax_pricing_items": [ { "pax_type_code": "adult", "cost": 2000 }, { "pax_type_code": "child", "cost": 1500 } ] } ]The 'per_pax_pricing_items' fields lists all the pax_types and their rates respectively.
In slab based pricing, the per passenger price depends on the total number of passengers being booked.
For example, you can define slab prices like this:
If a trip has slab based pricing defined, then in API response it will be represented as follows:
"pricing_rules": [ { "client_id": 64, "id": 4004, "name": "Default slab pricing", "trip_option_id": 518, "pricing_type": "per_pax_pricing", "slabs": [ [5, 5000], [10, 4000], [15, 3000] ] } ]The slabs in the response should be interpreted as, from 1 to 5, the rate is 5000, from 6 to 10, rate is 4000, and from 10 to 15 the rate is 3000.
This is a very advanced pricing type. In Multi component pricing you can specify rates for each component such as transport pricing, hotel pricing, passenger pricing, per booking charges.
If a trip has multi component pricing defined, then the pricing rules will have an entry for each component in the API response as shown below:"pricing_rules": [ { "client_id": 64, "id": 3930, "name": "Per Passenger charge", "trip_option_id": null, "pricing_type": "per_pax_pricing", "per_pax_pricing_items": [ { "pax_type_code": "passenger", "cost": 2000 } ], "pricing_map": { "passenger": 2000 } }, { "amount": 500, "client_id": 64, "id": 220, "name": "Per-Booking Charge", "pricing_type": "per_booking_pricing" }, { "base_occupancy": 1, "base_rate": 2000, "client_id": 64, "extra_occupancy_rates": { "passenger": { "1": 500, "2": 1000 } }, "id": 450, "max_occupancy": 3, "name": "Hotel Cost", "special_rates": {}, "pricing_type": "hotel_pricing" }, { "capacity": [ 30 ], "client_id": 64, "id": 313, "name": "Car / Transport Charge", "rate": [ 5000 ], "ref": [ "4a0be790-f56a-4e9a-863f-d9cf4122dfbf" ], "vehicle_name": [ "Bus" ], "pricing_type": "transport_pricing", "vehicles": [ { "vehicle_name": "Bus", "ref": "4a0be790-f56a-4e9a-863f-d9cf4122dfbf", "capacity": 30, "rate": 5000 } ] } ]
NOTE: Depending on the type of the pricing used, the pricing_rule item's data will vary. If per pax pricing is used, then the pricing rule item will have 'per_pax_pricing_items' field. If slab based pricing rules is used, then it will have 'slabs' field. Or if multi component pricing is used then they each component will have fields related to that component. For example, 'transport_pricing' will have 'vehicle' field in it.
Other than Open Slots and Pricing rules, trip option also stores other trip related settings such the minimum and the maximum number of passenger for the trip, minimum deposit required to confirm a booking for the trip and booking lead time seconds which indicates how close to a departure can customers make bookings through the storefront.
Addons are the extra facilities or services which the trip operator can offers along with the trip. It can be anything, such as Taxi pickup and drop, or Food, or CD/Dvd of your trip. Addons may/may not have extra charges.
Pax types are basically passenger types. A trip can have many passenger types, such as adult, child, infant, senior citizen etc. Trip pricing can also be set based on pax types. For more info on setting trip pricing on based on pax types, refer per pax pricing documentation under Pricing rules.
Vacation Labs allows the users to assign custom fields to a trip. Custom fields can be thought of as tags for the trip, or any extra piece of information which you want to link to the trip.
For example if you want to categorize your trip, then you can create a custom field, say 'Category' and give it some values such as 'Adventure', 'Trek', 'Sports' etc. Once a custom field is created, you can assign any of the supplied values to the trip. Custom fields can then also be used to fetch trips matching some value via Trips API. For example, fetching trips where 'Category' is 'Adventure'.
There are 5 types of custom fields:A trip is conducted when there are confirmed bookings against a trip. Departures specify when you HAVE to conduct your next trip/tour. Departures are only created when there is at-least one confirmed booking against a trip. If you want to know when you have to operate your trips because there are confirmed bookings against them, then you can use departures API to fetch your upcoming departures.
Departures also contains other operational data, such as number of bookings for the departure, confirmed and pending booking ids, payments data, trip and trip option identifiers, available seats etc.
NOTE: Each private tour will have a separate departure and a private departure will always contain the contact details of the person who has booked the trip.
Open slots are recurrence rules which specifies the operating days (time slots) for a trip (technically trip option). For example, If you are operating a trip daily for a month of september, then there will be a single entry in open slots i.e. a recurrence rule which will specify the operating days for the trip. the entry in open slots will look like this:
{ "id": 10304, "client_id": 64, "trip_id": 2802, "trip_option_id": 3237 "starts_at": "2014-09-01", "ends_at": "2014-09-30", "days_of_week": [true, true, true, true, true, true, true], "excluded_times": [], ... }
Single recurrence rule is enough to specify these operating days because open slots only specifies when the trip operator can operate a trip.
Availability gives operational data for each open slot. In the previous example, single recurrence rule was enough to specify that the trip will be operating daily, for a month because it was only specifying the possible operating days for a trip and nothing else. Whereas availability gives operational data for each open slot, in this case its each day. So if a trip is operating daily, for 30 days, then the availability data will have 30 entries, one for each day. Each entry will give availability information for that day, for example, total seats, the number of booked seats, the number of available seats etc. and it will look like this:
"availability_keys": [ "starts_at", "ends_at", "min_pax", "available_seats", "total_capacity" ], "availability": { "trip_id": 2802, "data": { "2014-09-01": { "3237": [ [ "2014-09-01T00:00:00", "2014-09-01T07:00:00", 2, 30, 30 ] ] }, "2014-09-02": { "3237": [ [ "2014-09-02T00:00:00", "2014-09-02T07:00:00", 2, 30, 30 ] ] }, "2014-09-03": { "3237": [ [ "2014-09-03T00:00:00", "2014-09-03T07:00:00", 2, 30, 30 ] ] }, "2014-09-04": { "3237": [ [ "2014-09-04T00:00:00", "2014-09-04T07:00:00", 2, 30, 30 ] ] }, "2014-09-05": { "3237": [ [ "2014-09-05T00:00:00", "2014-09-05T07:00:00", 2, 30, 30 ] ] }, "2014-09-06": { "3237": [ [ "2014-09-06T00:00:00", "2014-09-06T07:00:00", 2, 30, 30 ] ] }, "2014-09-07": { "3237": [ [ "2014-09-07T00:00:00", "2014-09-07T07:00:00", 2, 30, 30 ] ] }, "2014-09-08": { "3237": [ [ "2014-09-08T00:00:00", "2014-09-08T07:00:00", 2, 30, 30 ] ] }, "2014-09-09": { "3237": [ [ "2014-09-09T00:00:00", "2014-09-09T07:00:00", 2, 30, 30 ] ] }, "2014-09-10": { "3237": [ [ "2014-09-10T00:00:00", "2014-09-10T07:00:00", 2, 30, 30 ] ] }, "2014-09-11": { "3237": [ [ "2014-09-11T00:00:00", "2014-09-11T07:00:00", 2, 30, 30 ] ] }, "2014-09-12": { "3237": [ [ "2014-09-12T00:00:00", "2014-09-12T07:00:00", 2, 30, 30 ] ] }, "2014-09-13": { "3237": [ [ "2014-09-13T00:00:00", "2014-09-13T07:00:00", 2, 30, 30 ] ] }, "2014-09-14": { "3237": [ [ "2014-09-14T00:00:00", "2014-09-14T07:00:00", 2, 30, 30 ] ] }, "2014-09-15": { "3237": [ [ "2014-09-15T00:00:00", "2014-09-15T07:00:00", 2, 30, 30 ] ] }, "2014-09-16": { "3237": [ [ "2014-09-16T00:00:00", "2014-09-16T07:00:00", 2, 30, 30 ] ] }, "2014-09-17": { "3237": [ [ "2014-09-17T00:00:00", "2014-09-17T07:00:00", 2, 30, 30 ] ] }, "2014-09-18": { "3237": [ [ "2014-09-18T00:00:00", "2014-09-18T07:00:00", 2, 30, 30 ] ] }, "2014-09-19": { "3237": [ [ "2014-09-19T00:00:00", "2014-09-19T07:00:00", 2, 30, 30 ] ] }, "2014-09-20": { "3237": [ [ "2014-09-20T00:00:00", "2014-09-20T07:00:00", 2, 30, 30 ] ] }, "2014-09-21": { "3237": [ [ "2014-09-21T00:00:00", "2014-09-21T07:00:00", 2, 30, 30 ] ] }, "2014-09-22": { "3237": [ [ "2014-09-22T00:00:00", "2014-09-22T07:00:00", 2, 30, 30 ] ] }, "2014-09-23": { "3237": [ [ "2014-09-23T00:00:00", "2014-09-23T07:00:00", 2, 30, 30 ] ] }, "2014-09-24": { "3237": [ [ "2014-09-24T00:00:00", "2014-09-24T07:00:00", 2, 30, 30 ] ] }, "2014-09-25": { "3237": [ [ "2014-09-25T00:00:00", "2014-09-25T07:00:00", 2, 30, 30 ] ] }, "2014-09-26": { "3237": [ [ "2014-09-26T00:00:00", "2014-09-26T07:00:00", 2, 30, 30 ] ] }, "2014-09-27": { "3237": [ [ "2014-09-27T00:00:00", "2014-09-27T07:00:00", 2, 30, 30 ] ] }, "2014-09-28": { "3237": [ [ "2014-09-28T00:00:00", "2014-09-28T07:00:00", 2, 30, 30 ] ] }, "2014-09-29": { "3237": [ [ "2014-09-29T00:00:00", "2014-09-29T07:00:00", 2, 30, 30 ] ] } } }
Availability keys specifies the keys whose values will be available in the availability json in the same order. The `data` key in availability has all the availability data in it. This is the first entry in data:
"2014-09-01": { "3237": [ [ "2014-09-01T00:00:00", "2014-09-01T07:00:00", 2, 30, 30 ] ] }
This specifies the availability data for 1st september 2014. The number 3237 is actually the id of the trip option this availability data belongs to. The value is a data array. The first element in the inner array is the `starts_at` date as specified in the `availability_keys`. The rest of the elements are `ends_at`, `min_pax`, `available_seats` and `total_capacity` respectively. So the key names are specified in the `availability_keys` and the data is specified in `availability`.
NOTE: When a booking a made for a trip, its availability data will change as the number of booked seats for that open slot will increase and the number of available seats will decrease.
Departures are somewhat different from open slots and availability. Departures are created if there is a confirmed booking against a trip. Departures only stores the number of available seats for that departure. The response json for departures will be something like this:
{ "departures": [ { "available_seats": 28, "booking_count": 2, "client_id": 64, "confirmed_booking_ids": [ 32783, 32782 ], "currency": "INR", "departure_type": "group_tour", "ends_at": "2014-09-05T07:00:00", "id": 1697, "pax_count": 2, "starts_at": "2014-09-05T00:00:00", "state": "confirmed", "time_significance": false, "trip_id": 2802, "trip_option_id": 3237, "amount": 3000, "payment": 3000, "bookings_checked_in": 0, "pax_checked_in": 0, "booking_items": [ { "category": "pax", "name": "Passenger", "quantity": 4 } ], "pending_booking_ids": [], "comment_count": 0, "pending_payment": 0, "booking_ids": [ 32783, 32782 ] }, { "available_seats": 29, "booking_count": 1, "client_id": 64, "confirmed_booking_ids": [ 32784 ], "currency": "INR", "departure_type": "group_tour", "ends_at": "2014-09-06T07:00:00", "id": 1698, "pax_count": 1, "starts_at": "2014-09-06T00:00:00", "state": "confirmed", "time_significance": false, "trip_id": 2802, "trip_option_id": 3237, "amount": 1500, "payment": 1500, "bookings_checked_in": 0, "pax_checked_in": 0, "booking_items": [ { "category": "pax", "name": "Passenger", "quantity": 2 } ], "pending_booking_ids": [], "comment_count": 0, "pending_payment": 0, "booking_ids": [ 32784 ] } ] }
A private trip will always have separate departures, even if multiple bookings are made for the same day. The repsonse json for private departures will look something like this:
{ "departures": [ { "available_seats": 12, "booking_count": 1, "client_id": 64, "confirmed_booking_ids": [ 32785 ], "currency": "INR", "departure_type": "private_tour", "ends_at": "2014-09-07T07:00:00", "id": 1699, "pax_count": 1, "starts_at": "2014-09-07T00:00:00", "state": "confirmed", "time_significance": false, "trip_id": 2773, "trip_option_id": 3204, "amount": 2500, "payment": 2500, "bookings_checked_in": 0, "pax_checked_in": 0, "booking_items": [ { "category": "pax", "name": "Passenger", "quantity": 1 } ], "pending_booking_ids": [], "comment_count": 0, "pending_payment": 0, "booking_ids": [ 32785 ], "contact_details": { "email": "saurabh@vacationlabs.com", "full_name": "Saurabh Nanda", "phone": "+91 7798722177", "title": "Mr" } }, { "available_seats": 12, "booking_count": 1, "client_id": 64, "confirmed_booking_ids": [ 32786 ], "currency": "INR", "departure_type": "private_tour", "ends_at": "2014-09-07T07:00:00", "id": 1700, "pax_count": 1, "starts_at": "2014-09-07T00:00:00", "state": "confirmed", "time_significance": false, "trip_id": 2773, "trip_option_id": 3204, "amount": 2500, "payment": 2500, "bookings_checked_in": 0, "pax_checked_in": 0, "booking_items": [ { "category": "pax", "name": "Passenger", "quantity": 1 } ], "pending_booking_ids": [], "comment_count": 0, "pending_payment": 0, "booking_ids": [ 32786 ], "contact_details": { "email": "rajdeep@vacationlabs.com", "full_name": "Rajdeep Mandrekar", "phone": "99999 88888", "title": "Mr" } } ] }
Notice that the bookings are for the same day, still 2 departures are created, and each departure also has the contact details of the person who has booked the trip. For more info on departures, refer documentation for departures.
Every API request is authenticated by Vacation Labs. In-order to consume the API's you need to authenticate yourself by sending your account's API key and the user's secret key as query parameters in every API request you make to our API's.
You can get the Account API key and the user secret key from settings, under user & permissions tab, once you log in to your account. Click on `Action` button next to any user's name and then click on `View API key`.
If the sent ac_api_key and user_secret are correct, then your account will be authenticated, and the request will be processed, or else appropriate error message will be sent in the response.
Some API operations requires the user to have certain permissions. If the user, whose user_secret is sent in the API request, does not have the required permissions for the API operation, then response will contain HTTP status 401 ie. Unauthorized.
Most of the listing API operations in our system, such as listing trips, listing users, uses pagination. By default, every such operation will return 10 result only. If you need more than 10 results then you need to use limit query parameter when making an API call. If you send limit=20, it will return 20 results. However the maximum number of result you can get at a time is limited to 50. If you send limit=60, it will still send 50 results, as 50 is the upper limit.
You can also use offset along with limit to paginate through the results.Suppose you are querying the trips listing API, and if you have more then 10 trips then by default the result will only contain 10 trips. Now to get the next 10 trips you can send offset=10, which means, it will return the next set of trips starting from the offset, i.e 10. By default the offset is set to ZERO.
NOTE: It is always advisable to specify the order, when using limit and offset to paginate through the result. Though specifying the order is useful, its not mandatory. You can specify the order by sending the order query param. If you dont send the order query param, then default ordering will be applied, which will be mentioned in every API operation.
Sometimes, when requesting for a particular resource, we need some extra data along with the resource. For example, when querying for a particular user, we get the user details along with the roles and the permissions that the user is assigned. But what if we want to see the all possible permissions in the system just to check which permissions were not assigned to the user? In-order to do that we will have to make an extra API call to get all the permission.
Only to make this easier and to reduce the number of API calls to fetch necessary data, we use query parameters to get this extra data as side-data along with the resource. In the above example, we can fetch all permissions as side data when requesting to fetch the data for the user, by sending 'include_permissions' query parameter as true. The response for this request will look something like this:
{ "user": { ... ... } "permissions": { ... ... } }
NOTE: 'user' and 'permission' data is excluded to keep the example simple.
There are many API operation which supports inclusion of side-data.
NOTE: All query parameters used to fetch side data will begin with 'include'. For example 'include_availability', 'include_roles'.
NOTE: All API operations MUST provide Account API key and User secret. These can be obtained by the account owner/super-user from the Vacation Labs backoffice (Settings → Users & Permissions → Against any user click the "Actions" buttons → View API key).