NAV
bash php

Introduction

Welcome to the Innstant API! You can use our API to access Innstant’s various API endpoints.

This document is meant for developers with at least some experience in API developments.

For any question, credentials, or request, please contact your account manager at Innstant.

Authentication

There are basically 3 different methods you can choose to use for authentication.

  1. Persistent Authentication - This method is used when you need a session that expires.
    To use this method you send a “login” call with the user details, and get the LoginToken in the response.
    This token is your session ID and you can send it instead of sending the account/agent/password on each call, and once it expires you simply get a new session code.
  2. One-off Authentication - This method is used when you don’t need a session, and have the login credentials handy. to use it, you simply send the account/agent/password combination on each call.
  3. Token Based Authentication - This method is used for searching and booking content on Mishor, but can also be used for all other services.
    To use this method you simply save a unique login token for each agent/account combination.

Persistent Authentication

The Persistent authentication method is used to establish a “session” and avoid having to send all the authentication details on each call to the API.

The first phase is to send a login call with the specific agent login details, and then used to received token to conduct all other calls.

GET https://example.com/login/agent/

Login

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://example.com/login/agent/",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "aether-application-key: [app-key]",
    "aether-account: [account]",
    "aether-agent: [agent]",
    "aether-customization: [customization]",
    "aether-password: [password]",
    "cache-control: no-cache"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);
curl \
  -H "aether-application-key: [app-key]" \ 
  -H "aether-account: [account]" \
  -H "aether-agent: [agent]" \
  -H "aether-customization: [customization]" \
  -H "aether-password: [password]" \
  -H "cache-control: no-cache" \
  https://example.com/login/agent/
Header Mandatory Description
aether-application-key Yes Your unique application key issued by your account manager
aether-account Yes The account that is making the request
aether-agent Yes The agent that is making the request
aether-password Yes The agent that is making the request
aether-customization No The whitelabel domain that is making the request. This is used in cases that require some customization like setting logos or emails, etc.

The login request returns JSON structured like this:

{
  "content": {
    "LoginToken": "example12345",
    "UserName": "example",
    "FirstName": "example",
    "LastName": "example",
    "AccountID": 12345,
    "AgentID": 12345,
    "Permissions": {
      "12345": {
        "PermissionID": 12345,
        "PermissionValue": "enabled"
      }
    },
    "AccountLoginName": "example",
    "AccountCompanyName": "example",
    "AccountCurrencies": {
      "EUR": {
        "IsDefault": 1,
        "Currency": "EUR"
      },
      "USD": {
        "IsDefault": 0,
        "Currency": "USD"
      }
    },
    "AgentMeta": {
      "AgentID": 1
    },
    "AccountMeta": {
      "AccountID": 1
    },
    "OnAccounts": [
      {
        "AccessToken": "$6h$14$.gAH439wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a",
        "AccountID": 1,
        "LoginName": "example",
        "CompanyName": "example",
        "Type": "test",
        "Status": "enabled",
        "Market": "EU",
        "Country": "DE",
        "City": "Berlin",
        "Address": "Some street"
      }
    ],
    "ProfileVersion": "dcc81048a744a12345a33bf6728550f700"
  },
  "status": "done"
}

Then, Once you have the LoginToken you can send it instead of the full credentials on each call.

Example of using the LoginToken to authenticate

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "[API endpoint]",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "aether-application-key: [application-key]",
    "aether-customization: [customization]",
    "aether-login-token: [login-token]
    "cache-control: no-cache"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);
curl \
  -H "aether-application-key: [app-key]" \ 
  -H "aether-customization: [customization]" \
  -H "aether-login-token: [login-token]" \
  -H "cache-control: no-cache" \
  [API endpoint]

Make sure to replace all items in square brackets [] with the requests’ details.

One-off Authentication

These headers must be sent with every call:

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "[API endpoint]",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "aether-application-key: [app-key]",
    "aether-account: [account]",
    "aether-agent: [agent]",
    "aether-customization: [customization]",
    "aether-password: [password]",
    "cache-control: no-cache"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);
curl \
  -H "aether-application-key: [app-key]" \ 
  -H "aether-account: [account]" \
  -H "aether-agent: [agent]" \
  -H "aether-customization: [customization]" \
  -H "aether-password: [password]" \
  -H "cache-control: no-cache" \
  [API endpoint]

Make sure to replace all items in square brackets [] with the requests’ details.

The One-Off authentication method is used in cases you do not want to keep a “session”.

The API expects for all of the above headers to be included in all API requests to the server in a header that looks like the example on the right:

Header Mandatory Description
aether-application-key Yes Your unique application key issued by your account manager
aether-account Yes The account that is making the request
aether-agent Yes The agent that is making the request
aether-password Yes The agent that is making the request
aether-customization No The whitelabel domain that is making the request. This is used in cases that require some customization like setting logos or emails, etc.

Token based authentication

The Token authentication method is a combination of the 2 previous methods, and is mainly used for searching and booking content through Mishor. However, you can use this method for all of your authentication needs, it’ll work either way.

curl \
  -H "aether-application-key: [app-key]" \ 
  -H "aether-access-token: [account]" \
  -H "aether-customization: [customization]" \
  -H "cache-control: no-cache" \
  [API endpoint]

Make sure to replace all items in square brackets [] with the requests’ details.

The aether-access-token can be retrieved through the login method above, and saved locally for all future use. it will not change until you actively change it through the back-office, although Innstant may initiate a rotation of all tokens once every period for security purposes.

Remote login to the Innstant UI

In order to perform a silent login from your UI to the Innstant UI so that your users will not need to enter their credentials, you can use the following method.
Basically, you need to hold the credentials of your agents or users, and send them to the Innstant API.

After we get the data from JSON, we’ll try to login with received credentials. If an attempt fails, we register a new user.

For registration we need all the fields. For login it can be only “email” and “password”. But we recommend sending the whole record each time.

Request

POST https://yourWhitelabelDomain.com/api/remote/login

Remote login request:

{
  "firstName": "testName",
  "lastName": "testLastName",
  "email": "some@email.com",
  "phone": "+44 123 456 789"
  "password": "test"
}
Attribute Description
firstName First name of the agent, required for registration
lastName Last name of the agent, required for registration
email email of the agent, required always
password The password of the agent, which is performing the login, required always
phone optional

Response

Remote login response:

{
    "auth_key": "$2y$10$GgE9IqVAt9BhRtjKADliWusRknKj0JlLWUZBAnT/OlQM5M0ykv03q",
    "url": "http://{WLURL}?auth_key=$2y$10$GgE9IqVAt9BhRtjKADliWusRknKj0JlLWUZBAnT/OlQM5M0ykv03q"
}

In response you are getting an URL and auth_key. You should redirect your user to this URL:

http://{WLURL}?auth_key=$2y$10$GgE9IqVAt9BhRtjKADliWusRknKj0JlLWUZBAnT/OlQM5M0ykv03q

Attribute Description
auth_key should be send to url for authorisation
url the url to send your user’s browser to.

Errors

There are two kinds of errors that can be received as a response:

You are trying to login with wrong password or register with existing e-mail:

{ "status": "error", "errorMessage": "Account with the email first@last.email already exists.", "errorCode": 500 }

Other errors:

{ "status": "error", "errorMessage": "The operation was unsuccessful [#205].", "errorCode": 500 }

Aether

Aether is the full fledged back office system that allows management of the bookings, accounting, setting of accounts and agents, and all other entities in the system.

Currency rates

Request

curl \
    -H "aether-application-key: [app-key]" \ 
    -H "aether-account: [account]" \
    -H "aether-agent: [agent]" \
    -H "aether-customization: [customization]" \
    -H "aether-password: [password]" \
    -H "cache-control: no-cache" \
  https://example.com/currency-rates/get/USD,EUR

Response

{
    "content": {
        "Status": "done",
        "Message": [
            {
                "FromCurrency": "EUR",
                "ToCurrency": "USD",
                "Rate": 1.24607
            },
            {
                "FromCurrency": "USD",
                "ToCurrency": "EUR",
                "Rate": 0.802523
            }
        ],
        "ProfileVersion": "xxx"
    },
    "status": "done"
}

GET https://example.com/currency-rates/get/[comma separated currencies]

Attribute Description
FromCurrency 3 letter ISO 4217 currency code
ToCurrency 3 letter ISO 4217 currency code
Rate Float, value of the currency pair

Accounting

In order to use the accounting, you will need to use the same authentication methods described above.

Documents

Get Document

Request

curl \
    -H "aether-application-key: [app-key]" \
    -H "aether-account: [account]" \
    -H "aether-agent: [agent]" \
    -H "aether-customization: [customization]" \
    -H "aether-password: [password]" \
    -H "cache-control: no-cache" \
    -d '{"ID":22}' \
    -X POST
  https://example.com/accounting/document/get

Response

{
  "content": {
    "Accounting": {
      "Balance": 30,
      "Currency": "USD",
      "GrossAmount": 30,
      "NetAmount": 30,
      "PaymentMethod": "cash",
      "Tax": 0
    },
    "ActionPermissions": {
      "AddLine": true,
      "Cancel": true,
      "Finalize": true,
      "Pay": true
    },
    "Booking": ["35"],
    "Covered": [],
    "CreateDate": "2018-02-05 15:10:49",
    "CreateType": "manual",
    "DisplayName": "Sales Order",
    "DocumentID": 48,
    "DueDate": "2018-02-06 10:20:58",
    "From": {
      "AccountAlias": "test travel",
      "AccountID": 101,
      "AccountType": "Account",
      "ContactAddress": "test",
      "ContactCity": "test",
      "ContactEmail": "stest@mail.com",
      "ContactName": "testy mctestington"
    },
    "IssueDate": "2018-02-06 10:20:58",
    "LeadName": "TEST TEST",
    "LineSubTotals": {
      "hotels": 30
    },
    "Lines": [
      {
        "Accounting": {
          "Amount": 15,
          "Conversion": 15,
          "Currency": "EUR"
        },
        "BookingItem": {
          "BookingID": "35",
          "BookingItemID": 1,
          "EndDate": "2018-01-15",
          "LeadName": "TEST TEST",
          "ServiceType": "hotels",
          "StartDate": "2018-01-09"
        },
        "Details": {
          "ItemDescription": "A TEST ROOM IN A FAKE HOTEL",
          "ItemName": "hotels Booking",
          "LineType": "hotels",
          "ProductID": 1,
          "Quantity": 1
        },
        "DocumentID": 48,
        "LineID": 42
      },
      {
        "Accounting": {
          "Amount": 15,
          "Conversion": 15,
          "Currency": "EUR"
        },
        "BookingItem": {
          "BookingID": "35",
          "BookingItemID": 2,
          "EndDate": "2018-01-15",
          "LeadName": "TEST TEST",
          "ServiceType": "hotels",
          "StartDate": "2018-01-09"
        },
        "Details": {
          "ItemDescription": "A TEST ROOM IN A FAKE HOTEL",
          "ItemName": "hotels Booking",
          "LineType": "hotels",
          "ProductID": 2,
          "Quantity": 1
        },
        "DocumentID": 48,
        "LineID": 43
      }
    ],
    "PaymentDetails": null,
    "Payments": [],
    "ProfileVersion": "1108c82ffac3914820eee3c4b227299e909e1cd5",
    "Reference": "s51",
    "Status": "open",
    "To": {
      "AccountAlias": "jeff travel",
      "AccountID": 3,
      "AccountType": "Account",
      "ContactAddress": "test",
      "ContactCity": "test",
      "ContactEmail": "N/A",
      "ContactName": "N/A"
    },
    "ToProvider": false,
    "Type": "invoice"
  },
  "status": "done"
}

POST https://example.com/accounting/document/get

Attribute Description
DocumentID The ID of this document
CreateDate The timestamp of the document creation
CreateType How was this document created. possible values are: manual, custom, scenario
IssueDate The deciding timestamp of when the document was issue, can be different than the actual creation timestamp
DueDate The timestamp stating when the document is due to be covered
Type Whether the document is an invoice or a payment. possible values are: invoice, payment
DisplayName The category name that the condition of this document falls under. Can be one of the following (Sales Order, Invoice, Receipt, Credit, Refund, Purchase Order, Provider Invoice, Provider Receipt, Provider Credit, Provider Payout, Provider Payment, Provider Refund)
Status The status of the document. possible values are: open, finalized, cancelled
Reference The reference number generated for this document
ToProvider Boolean, indicates the direction of the document. if false it means it’s a client facing document, otherwise it’s provider facing
LeadName Name of the lead Pax the document refers to
From The Contact element which is issuing the document, see details below
To The Contact element which is receiving the document, see details below
Accounting.NetAmount The net amount of the document
Accounting.GrossAmount The gross amount of the document
Accounting.Currency The currency of the document
Accounting.Tax Tax value included in the document
Accounting.Balance The remaining balance for the document
ActionsPermissions See ActionsPermissions section below
Lines See the “Get lines” section for details
LineSubTotals An array/object of sub-totals regarding the lines, grouped by line type
Payments Array of payments that covers this document
Covered Array of documents this document covers
PaymentDetails See PaymentDetails section below

Contact element

Note that the contact can be of a Customer or of an account.

Attribute Description
ContactName The name of the Customer and/or the account holder
ContactAddress The address of the Customer and/or the account holder
ContactCity The city of the Customer and/or the account holder
ContactEmail The email of the Customer and/or the account holder
AccountID The ID of the contact
AccountType Whether it’s an “Account” or a “Customer”
AccountAlias Name of the account

ActionsPermissions element

Attribute Description
Pay Indicates that a payment can be made to this document
AddLine Indicates whether a line could be added to this document
Finalize Indicates whether this document is open and can be finalized
Cancel Indicates whether this document can be cancelled

PaymentDetails element

The PaymentDetails can be one of the following:

Each of these elements have different structure, and is shown on the “Type” attribute:

Bank Transfer
Attribute Description
Date Date of the payment, structure YYYY-MM-DD HH:MM:SS
Sum Value of the payment
Comment Free text comment
Type always “Bank Transfer”
Reference Transaction reference, free text
Credit Card
Attribute Description
Date Date of the payment, structure YYYY-MM-DD HH:MM:SS
Sum Value of the payment
Comment Free text comment
CardType the card type used for payment. Free text.
Last4Digits last 4 digits of the credit card used for the payment
VCC
Attribute Description
Date Date of the payment, structure YYYY-MM-DD HH:MM:SS
Sum Value of the payment
Comment Free text comment
CardType the card type used for payment. Free text.
Last4Digits last 4 digits of the credit card used for the payment
Cash
Attribute Description
Date Date of the payment, structure YYYY-MM-DD HH:MM:SS
Sum Value of the payment
Comment Free text comment
Details Free text
Cheque
Attribute Description
Date Date of the payment, structure YYYY-MM-DD HH:MM:SS
Sum Value of the payment
Comment Free text comment
AccountNumber Number of the account used for payment
ChequeNumber Identifier of the Cheque used for payment

Get Line

Request

curl \
    -H "aether-application-key: [app-key]" \
    -H "aether-account: [account]" \
    -H "aether-agent: [agent]" \
    -H "aether-customization: [customization]" \
    -H "aether-password: [password]" \
    -H "cache-control: no-cache" \
    -d '{"ID":44}' \
    -X POST
  https://example.com/accounting/line/get

Response

{
  "content": {
    "ActionPermissions": {
      "Edit": true,
      "Remove": true
    },
    "ProfileVersion": "347...",
    "LineID": 9,
    "DocumentID": 6,
    "Details": {
      "LineType": "Product",
      "ProductID": 1,
      "ItemName": "dinner",
      "ItemDescription": "super awesome delux dinner for 2",
      "Quantity": 1
    },
    "BookingItem": {
      "BookingID": null,
      "BookingItemID": null,
      "ServiceType": null,
      "LeadName": null,
      "StartDate": null,
      "EndDate": null
    },
    "Accounting": {
      "Amount": 100,
      "Currency": "EUR",
      "Conversion": 125
    }
  },
  "status": "done"
}

This method retrieves document lines.

Attribute Description
LineID The ID of the line
DocumentID The ID of the document the line belongs to
ActionPermissions What can be done with this line, see below
Details Line details, see below
BookingItem The booking item the line covers, see below
Accounting Accounting aspects of the line, see below
ActionPermissions
Attribute Description
Edit boolean, can the line be edited
Remove boolean, can the line be removed
Details
Attribute Description
LineType The type of item the line refers to, possible values are: Product, Tax, but it can also be anything the user defines when setting the line.
ProductID The product id for the line. Note that this can be any product and not necessarily the booking item id.
ItemName The name of the Item the line refers to, free text.
ItemDescription Free text description of the item.
Quantity How many products does this line covers
BookingItem
Attribute Description
BookingID The booking ID the line covers
BookingItemID The booking item ID the line covers
ServiceType The service type the line covers
LeadName Lead name of the booking
StartDate Start date of the booking
EndDate End date of the booking
Accounting
Attribute Description
Amount Value of the line
Currency Currency of the line
Conversion The value of this line converted into the documents default currency

List Documents

Request

curl \
    -H "aether-application-key: [app-key]" \
    -H "aether-account: [account]" \
    -H "aether-agent: [agent]" \
    -H "aether-customization: [customization]" \
    -H "aether-password: [password]" \
    -H "cache-control: no-cache" \
    -d '{"filters":{"FromID": 1},"resultsPerPage": 10,"currentPage": 1}' \
    -X POST
  https://example.com/accounting/document/list

This method retrieves documents based of filters and pagination.

Attribute Description
resultsPerPage Number of results to return per page, max is 50
currentPage Current page
filters available filters object, optional, see below for details
(optional) Request Filters

you can include multiple filters on the request to narrow your search. all filters are optional

Attribute Description
DocumentIDs array of document IDs
FromIDs array of account IDs the document was issued from
ToIDs array of account IDs the document was issued to
BookingIDs array of booking IDs the document was issued for
AgentIDs array of booking IDs the document was issued by
CreatedAfter_value Timestamp, get bookings created after this date, format is: YYYY-MM-DD HH:MM:SS
CreatedBefore_value Timestamp, get bookings created before this date, format is: YYYY-MM-DD HH:MM:SS
IssuedAfter_value Timestamp, get bookings issued after this date, format is: YYYY-MM-DD HH:MM:SS
IssuedBefore_value Timestamp, get bookings issued before this date, format is: YYYY-MM-DD HH:MM:SS
DueAfter_value Timestamp, get bookings due after this date, format is: YYYY-MM-DD HH:MM:SS
DueBefore_value Timestamp, get bookings due before this date, format is: YYYY-MM-DD HH:MM:SS
Types array, possible values are invoice, payment
PaymentMethods array, see PaymentDetails for possible values
Statuses array, possible values are open, finalized, cancelled
Currencies array, list of currencies
References array, list of document references
DisplayNames array, possible values Sales Order, Invoice, Receipt, Credit, Refund, Purchase Order, Provider Invoice, Provider Receipt, Provider Credit, Provider Payout, Provider Payment, Provider Refund
Direction string, possible values Account, Provider, Both

Response

{
  "content": {
    "currentPage": 1,
    "totalResults": 86,
    "resultsPerPage": 10,
    "records": [
      /*...documents...*/
    ],
    "ProfileVersion": "7efd..."
  },
  "status": "done"
}

POST https://example.com/accounting/document/list

Attribute Description
records a list of document objects as described in the /accounting/document/get method

Mishor

Introduction

Mishor is an API switch for multiple travel content providers.

Products

Hotels

Flow

The common case usage is quite simple:

  1. Initiate a search
  2. Poll to get results
  3. [optional] poll the same search to get better results providing timestamp of the last poll
  4. [optional] get the cancellation policy, if it’s not returned as part of the search/poll results
  5. run a pre-book call
  6. book

Please note - changing any method of the API requires a new fresh certification.

Request

curl \
  -H "aether-application-key: [app-key]" \
  -X POST
  -d @request-file.json
  https://example.com/hotels/search

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ],
  "service": "hotels"
}

Request

POST https://example.com/hotels/search

Attribute Description
client Information about the client who is running the search. This node is optional, but sending it may provide special rates, for example for mobile users.
.client/ip The IP of the end-client
.client/userAgent The user agent of the end-client
currencies A list of currencies you wish to get your results in. The first currency on the list will be the default currency of the search
customerCountry 2 letter ISO code of the customer country running the search. Note: that the same customer country must be used on the booking, and giving a wrong or inaccurate customer country may result in the hotel not honoring the booking.
customFields See below
dates The from and to dates, format: YYYY-MM-DD
destinations The search destinations array
.destinations/[item]/type can be either hotel or location
.destinations/[item]/id the entity id based on the type
filters See below
pax See below

Filters

In order to better fit your needs, the API allows sending filters to include additional content.
All the filters are optional.

Example of a filter in the request

{
  "name": "payAtTheHotel",
  "value": true
},
{ 
  "name":"showWhenCheckinDateWithin",
  "value":8 
},
{ 
  "name":"hideWhenCancellationDeadlineWithin",
  "value":18
}
Filter Type Description
payAtTheHotel bool Include post-pay content
onRequest bool Include on-request content, which is not immediately confirmed
showSpecialDeals bool Include the special deals offers and descriptions in the response
getPackageRates bool Include rates which mustn’t be sold as-is, but only as part of a package. This feature must be enabled on your account by your account manager
showRoomDescriptions bool Whether to show the rooms descriptions where available
showRoomBedding bool Whether to show the bedding setup for the room
showRoomCategories bool Whether to show the category of the room
showWhenCheckinDateWithin int Show all results regardless of the free cancellation deadline if the arrival date is within the days specified in the filter
hideWhenCancellationDeadlineWithin int Hide results if the deadline for free cancellation is within the days specified in the filter

Custom Fields

This part is relevant for deep-integrations only, where you have your own suppliers connected via this API and need to pass parameters to specific providers.
An example of such a use-case is a B2B system that wants the agents using the system to collect loyalty points from a specific directly-contracted provider. In order to achieve that, you need to pass the agent credentials for that specific provider during search, and these credentials will be used to contact the provider.

Example of custom fields in the request

{
  "customFields": {
    "agentId": 1,
    "whatever": "shalgon"
  }
}

Pax

The pax array specifies the desired room configuration.
Each room is an object and each object consists of adults and children, where the children element is an array with their ages.
For example: in order to search for a room with 1 adult and 2 children ages 12 and 14, you need to create an object that looks like this:
{
“adults”: 1,
“children”: [12,14]
}

Note that different hotels and different channels treat “child” differently, so even if you send a child aged 15, some properties may treat it as an adult while others as a child.

Example of pax in the request

{
  "pax": [
    {
      "adults": 2
    },
    {
      "adults": 1,
      "children": [12, 14]
    }
  ]
}

Response

The response will return the results received until the search was completed.

Response

{
  "results": [
    {
      "items": [
        {
          "name": "Classic Double",
          "category": "standard",
          "bedding": "double",
          "board": "BB",
          "hotelId": 3090,
          "pax": {
            "adults": 2,
            "children": []
          },
          "quantity": {
            "min": 1,
            "max": 1
          }
        },
        {
          "name": "Classic Double",
          "category": "standard",
          "bedding": "double",
          "board": "BB",
          "hotelId": 3090,
          "pax": {
            "adults": 2,
            "children": []
          },
          "quantity": {
            "min": 1,
            "max": 1
          }
        }
      ],
      "code": "3090:::BB:5aeffedce7c86:qPo",
      "price": {
        "amount": 1096.62,
        "currency": "USD"
      },
      "netPrice": {
        "amount": 722.25,
        "currency": "EUR"
      },
      "barRate": {
        "amount": 631.8,
        "currency": "EUR"
      },
      "confirmation": "immediate",
      "payment": "pre",
      "packageRate": false,
      "commissionable": true,
      "cancellation": {
        "type": "non-refundable"
      }
    }
  ],
  "sessionId": "1234",
  "status": "done",
  "timestamp": 1533640316,
  "requestTime": "2018-08-07 14:11:56",
  "completed": 100,
  "processTime": 530
}

The response is an array of results, each result consists of these attributes:

Attribute Description
items An array of items the result id holds. The booking will be made on the result including all the items in it. The prices are only on the result level.
.item/name The name of the offered room
.item/category The category of the room
.item/bedding the bedding type available for this room
.item/board the available board for this offer, available list of boards exists in the lookups section
.item/hotelId The hotel id, taken from the static data
.item/pax the corresponding pax from your search which this result is suitable to
.item/quantity min/max availability. how many items of this result can be booked. If the min value is larger than 1, it means you must book at least the minimum quantity of results. Note that the price element in any case is the total price of the minimum quantity of items offered.
barRate Price (amount/currency) of the BAR, the price which you are not allowed to sell below on B2C platforms.
cancellation See below
code The result code, use this for the next steps
commissionable boolean, indicates whether you can apply a commission on top of the price or not
confirmation immediate or on-request
netPrice The net price (amount/currency) of this result
packageRate boolean, indicates whether this result can be sold as a stand-alone offer or if it requires to be sold as part of a package
payment pre or post, indicates whether this is a pre-paid result or a pay-at-the-hotel result
price The gross price of the result

In addition, there are several other attributes that are of interest:

Attribute Description
sessionId The session ID of the search
status The status of the search, whether it is done, working, or failed
timestamp The server timestamp of the response. this can be used to poll by delta
requestTime The request date time in Human readable format
completed Integer, percentage of the progress. 0 means no tasks were completed, 100 means all tasks were completed, everything in between in “in process”. Please note this attribute is for Innstant’s internal use only. To check if the search was completed or not please refer only to the status property.
processTime Processing time in milliseconds.

In case of post-payment results, you might get a transaction node in the response. This node will be returned in case you defined a “transaction fee” markup for this purpose.
This is being used in case the user has to pay a gross amount directly to the hotel, but you still want to collect something for the booking.

Example of a transaction fee in the response

"transactionFee": {
    "amount": 25.7,
    "currency": "EUR"
}

Cancellation Policy

The cancellation policy is build from frames.
Each frame has a start date (from), end date(to), and a penalty.
These frames tells you exactly what will be the penalty on each date starting from the booking date until the check-in date.
After the check-in date the cancellation penalty should be assumed as 100%.

Poll

Request

curl \
  -H "aether-application-key: [app-key]" \
  -X POST
  -d @request-file.json
  https://example.com/hotels/poll[/timestamp]

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST https://example.com/hotels/poll[/timestamp]

The poll request & response are identical to the search request & response with the exception of the endpoint.
You can send as many polls as you like until the status in the response is working. Once it finishes, the status changes to done and this means no new results will show up in your next poll.
Check out the Flow chapter in the beginning to get a better understanding of this method.
You can add an optional timestamp to the URL, the timestamp must be the one returned in the previous search/poll response in order to get the details.
If you do not send the timestamp in the URL, you will get ALL results every time.

Note that the search and poll requests must be identical.

Progress

Request

curl \
  -H "aether-application-key: [app-key]" \
  -X POST
  -d @request-file.json
  https://example.com/hotels/progress

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST https://example.com/hotels/progress

The progress request & response are identical to the search request & response with the exception of the endpoint. This call doesn’t return any results, but status of the search.
You can send as many progress calls as you like until the status in the response is working. Once it finishes, the status changes to done and this means you can now use poll request to grab all of the results.
Check out the Flow chapter in the beginning to get a better understanding of this method.

Note that the search and progress requests much be identical.

Get cancellation policy

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST http://example.com/hotels/cancellation/[room code]

The request consists of the desired room code (in the url) and the original search (in the request body).

Response

The response is exactly the same as the poll response, but with the cancellation frames in place.
Note that if you searched for multiple rooms and received multiple room codes for a single result, you MUST send multiple calls in order to get the cancellation policy for each separate code.

Pre-Book

Request content

{
  "services": [
    {
      "searchCodes": [
        {
          "code": "17512:standard:double:BB:5c06a3747437b$118h120U",
          "pax": [
            {
              "adults": 2,
              "children": []
            }
          ]
        },
        {
          "code": "17512:standard:double:BB:5c06a378bbb90$118h120U",
          "pax": [
            {
              "adults": 1,
              "children": []
            }
          ]
        }
      ],
      "searchRequest": {
        "currencies": ["USD"],
        "customerCountry": "IL",
        "dates": {
          "from": "2018-05-04",
          "to": "2018-05-05"
        },
        "destinations": [
          {
            "id": 5252,
            "type": "location"
          }
        ],
        "filters": [
          {
            "name": "payAtTheHotel",
            "value": true
          }
        ],
        "pax": [
          {
            "adults": 2
          },
          {
            "adults": 1
          }
        ],
        "service": "hotels"
      }
    }
  ]
}

Request

POST http://example-booking.com/pre-book

Note that this request is being send to a different domain than the one used for searching

Element Description
searchCodes The result codes you are planning to book. you can send as many search codes as you like in this array.
.code the code from the result
.pax the pax related to the specific code
searchRequest the original, unchanged, search request

Response

Response content

{
  "content": {
    "PaymentMethods": [
      {
        "methodDescription": "",
        "methodName": "account_credit",
        "paymentSettings": {
          "creditCardForm": false,
          "requiredFields": []
        },
        "status": "disabled"
      },
      {
        "methodDescription": "",
        "methodName": "enett",
        "paymentSettings": {
          "creditCardForm": false,
          "requiredFields": [
            {
              "enettId": "test"
            }
          ]
        },
        "status": "enabled"
      },
      {
        "methodDescription": "",
        "methodName": "credit_card",
        "paymentSettings": {
          "creditCardForm": true,
          "requiredFields": []
        },
        "status": "enabled"
      }
    ],
    "Services": {
      "hotels": [
        {
          "barRate": {
            "amount": 690,
            "currency": "EUR"
          },
          "cancellation": {
            "frames": [
              {
                "from": "2018-05-21",
                "penalty": {
                  "amount": 0,
                  "currency": "USD"
                },
                "to": "2018-06-18"
              },
              {
                "from": "2018-06-18",
                "penalty": {
                  "amount": 247.71,
                  "currency": "EUR"
                },
                "to": "2018-06-21"
              }
            ],
            "type": "fully-refundable"
          },
          "code": "33823:standard:double:BB:5afd296a87736$33823:standard:double:BB:5afd296a87775$qPo",
          "commissionable": true,
          "confirmation": "immediate",
          "items": [
            {
              "bedding": "double",
              "board": "BB",
              "boardName": "Breakfast Continental",
              "category": "standard",
              "hotel": {
                "address": "Via Marghera 15/17",
                "city": "Rome",
                "fax": null,
                "latitude": "41.90224110705",
                "longitude": "12.503670528531",
                "name": "Hotel Corot",
                "phone": "+39644700900",
                "rating": "3",
                "zip": "00185"
              },
              "hotelId": 33823,
              "name": "Standard Double or Twin Room",
              "pax": {
                "adults": 2,
                "children": []
              },
              "quantity": {
                "max": 1,
                "min": 1
              },
              "remarks": {
                "general": "this is a remark that should be shown to the customer"
              }
            },
            {
              "bedding": "double",
              "board": "BB",
              "boardName": "Breakfast Continental",
              "category": "standard",
              "hotel": {
                "address": "Via Marghera 15/17",
                "city": "Rome",
                "fax": null,
                "latitude": "41.90224110705",
                "longitude": "12.503670528531",
                "name": "Hotel Corot",
                "phone": "+39644700900",
                "rating": "3",
                "zip": "00185"
              },
              "hotelId": 33823,
              "name": "Standard Double or Twin Room",
              "pax": {
                "adults": 2,
                "children": []
              },
              "quantity": {
                "max": 1,
                "min": 1
              },
              "remarks": {
                "general": "this is a remark that should be shown to the customer <b>including HTML</b>"
              }
            }
          ],
          "netPrice": {
            "amount": 788.77,
            "currency": "EUR"
          },
          "packageRate": false,
          "paymentMethod": "direct",
          "price": {
            "amount": 1196.4,
            "currency": "USD"
          },
          "surcharges": [],
          "requestCode": "319229:standard:double:RO:4bf3d2665b474$119yo",
          "token": "65DDBED2"
        }
      ]
    }
  },
  "status": "done"
}
Element Description
PaymentMethods The acceptable payment methods for this booking
.methodName the name of the payment method. a standard integration will use account_credit or credit_card.
.methodDescription additional description of the method, for example if the method is a saved credit card token on the account, the description can say something like “Credit card ending with 1234”
.status whether this option is enabled for this booking
.paymentSettings specific settings for the payment method
..creditCardForm boolean, specifies if you need to show the credit card form to the user
..requiredFields key/value array of objects, consists of required fields to request from the user. for example the enett agent id in case of enett payment integration
Services The services that are about to be booked
.hotels an array of hotel rooms that are about to be booked
..barRate The minimum price (amount/currency) that can be shown on B2C website
..cancellation The cancellation policies, see the search response for details
..code The room code
..commissionable Whether or not you can add commission to the final price
..confirmation immediate or on-request
..items a collection of items
..item.bedding The offered bedding configuration
..item.board The offered board code
..item.board The offered board name
..item.category The offered room category
..item.hotel The hotel information. Note that it is mandatory to show the hotel information received in this response to the user prior to them making the booking, and use this information on the voucher issued to the user. It is NOT allowed to use the information from the static data.
..item.hotelId The booked hotel ID
..item.name The booked room name. Note that it is mandatory to show the room name received in this response to the user prior to them making the booking, and show this information on the voucher issued to the user. It is NOT allowed to use the information from the search response.
..item.pax The pax suitable for this room
..item.quantity See the search response for details
..item.remarks object that includes keys and free text remarks received from the hotel. the default key is called general, and additional keys may be included in certain cases. Note that is is mandatory to show these remarks to the user before the booking and it is also mandatory to put them on the voucher.
..netPrice The net price (amount/currency) of the booking, i.e. the amount that you need to pay the provider
..packageRate if true, this offer cannot be sold as a stand-alone booking, and the price must never be shown to the user without it being bundled as a package with other products.
..payment pre or post
..price The gross price (amount/currency) of the booking, i.e. the amount you charge your customer
..requestCode the code you sent in the request. this is used in case the result changed due to price or availability. it is for your use only and should not be sent in further requests.
..token the booking token you will have to send in order to make the actual booking
..warnings optional node, returned only in case of price or availability change
"warnings": [
            {
                "code": 2100,
                "message": "Your item is not available under the originally requested price, please review the selected alternative or go back to select another result."
            }
        ]

Book

Request

POST http://example-booking.com/book

Note that this request is being send to a different domain than the one used for searching

{
  "creditCard": {
    "cardNumber": "4111 1111 1111 1111",
    "cvc": "555",
    "expiry": {
      "month": "12",
      "year": "2019"
    },
    "name": {
      "first": "Yogi",
      "last": "Berra"
    }
  },
  "customer": {
    "birthDate": "1975-09-14",
    "contact": {
      "address": "housington 66",
      "city": "cityngton",
      "country": "NL",
      "email": "test@example.com",
      "phone": "555-4433222",
      "state": "N/A",
      "zip": "88776"
    },
    "name": {
      "first": "Yogi",
      "last": "Berra"
    },
    "title": "M"
  },
  "paymentMethod": {
    "methodName": "account_credit"
  },
  "reference": {
    "agency": "my agency reference",
    "voucherEmail": "test@example.com"
  },
  "services": [
    {
      "bookingRequest": [
        {
          "code": "3742:::RO:5acb6bcf725bf:qPo",
          "pax": [
            {
              "adults": [
                {
                  "contact": {
                    "address": "housington 66",
                    "city": "cityngton",
                    "country": "NL",
                    "email": "test@example.com",
                    "phone": "555-4433222",
                    "state": "N/A",
                    "zip": "88776"
                  },
                  "lead": true,
                  "name": {
                    "first": "Yogi",
                    "last": "Berra"
                  },
                  "title": "M"
                },
                {
                  "name": {
                    "first": "Mona",
                    "last": "Lisa"
                  },
                  "title": "F"
                }
              ]
            }
          ],
          "token": "1515BEE8"
        }
      ],
      "searchRequest": {
        "currencies": ["USD"],
        "customerCountry": "NL",
        "dates": {
          "from": "2018-05-04",
          "to": "2018-05-05"
        },
        "destinations": [
          {
            "id": 5252,
            "type": "location"
          }
        ],
        "filters": [
          {
            "name": "payAtTheHotel",
            "value": true
          }
        ],
        "pax": [
          {
            "adults": 2,
            "children": []
          }
        ],
        "service": "hotels"
      }
    }
  ]
}
Element Description
creditCard In case you are paying with a credit card, you need to send all relevant details
customer The customer details of the customer that is making the booking. It doesn’t have to be the same details as the travelers
payment how are you going to pay for the booking. this value must be one of the options returned in the pre-book
.method one of: “credit_card”, “account_credit”, or “enett”
.securePaymentUrl in case the payment method is credit_card, you need to supply a URL where to send the user after the payment process.
reference your references
.agency free text of your agency reference, i.e. your internal booking id
.voucherEmail an email address to send the voucher to
services this array of elements consists of the desired items you want to book. Each element contains 2 sub-elements: the original search request, and the booking request.
.searchRequest the original search request
.bookingRequest this element will contain the guest information and the payment details.
..code The result code you wish to book, this code comes from the search/poll response
..token the token from the pre-book call
..pax The pax configuration array for the booked properties. Each element in the array is a booked room
…adults the details of the adults in the room
….name first/last names of the guest
….title M for male, F for female (for children - see below)
….lead boolean, set to true if this is the lead pax. each booking must have one lead. do not set this flag on more than one.
….contact contact details of the lead pax, can be different than the customer on the booking.

In case you want to send a booking request for children, the child element must include another attribute called “birthDate” with a date value in the format YYYY-MM-DD. It is important to note that the age of the children is calculated based on the booking date.

Example of a children node:

“children”: [
{
    ”birthDate”: “2014-04-20”
    ”name”: {
        ”first”: “test”,
        ”last”: “test”
    },
    ”title”: “C”
}
]

Please ensure the “birthDate” attribute is present and correctly formatted to prevent any issues during the booking process.

Response

Response content

{
  "content": {
    "bookingID": "1000255",
    "customer": {
      "birthDate": "1985-01-01",
      "contact": {
        "address": "housington 66",
        "city": "cityington",
        "country": "NL",
        "email": "test@example.com",
        "phone": "555-4433222",
        "state": "N/A",
        "zip": "88776"
      },
      "name": {
        "first": "Yogi",
        "last": "Berra"
      },
      "title": "M"
    },
    "netPrice": {
      "amount": 55.2,
      "currency": "EUR"
    },
    "payment": {
      "method": "account_credit",
      "clearingState": null,
      "paymentStatus": "unpaid"
    },
    "price": {
      "amount": 60.72,
      "currency": "EUR"
    },
    "services": [
      {
        "cancellation": {
          "frames": [
            {
              "from": "2018-05-13",
              "penalty": {
                "amount": 60.72,
                "currency": "EUR"
              },
              "to": "2018-07-17"
            }
          ],
          "type": "refundable"
        },
        "code": "10666:standard:double:BB:5af95d6668163:qPo",
        "hotel": {
          "address": "Via San Lino Papa 35",
          "city": "Rome",
          "fax": null,
          "latitude": "41.919755493726",
          "longitude": "12.420943826437",
          "name": "Hotel Pineta Palace",
          "phone": "+3963013800",
          "rating": "4",
          "room": {
            "bedding": "double",
            "board": "BB",
            "boardName": null,
            "category": "standard",
            "name": "Economy Double or Twin Room",
            "token": "9179F6DB"
          },
          "zip": "00167"
        },
        "itemId": 1,
        "netPrice": {
          "amount": 55.2,
          "currency": "EUR"
        },
        "pax": [
          {
            "adults": [
              {
                "birthDate": "1985-01-01",
                "contact": {
                  "address": "housington 66",
                  "city": "cityington",
                  "country": "NL",
                  "email": "test@example.com",
                  "phone": "555-4433222",
                  "state": "N/A",
                  "zip": "88776"
                },
                "lead": true,
                "name": {
                  "first": "Yogi",
                  "last": "Berra"
                },
                "title": "M"
              },
              {
                "birthDate": "1985-01-01",
                "lead": false,
                "name": {
                  "first": "Mona",
                  "last": "Lisa"
                },
                "title": "F"
              }
            ],
            "children": []
          }
        ],
        "price": {
          "amount": 60.72,
          "currency": "EUR"
        },
        "quantity": 1,
        "remarks": "<br>\r\n. 1 double bed, 2 single beds. Economy Double or Twin Room. <p><b>Know Before You Go</b> <br /><ul> <li>All guests, including children, must be present at check-in and show their government-issued photo ID card or passport.</li> <li>Cash transactions at this property cannot exceed EUR 2999.99, due to national regulations. For further details, please contact the property using information in the booking confirmation. </li> <li>One child 3 years old or younger stays free when occupying the parent or guardian's room, using existing bedding. </li> </ul></p><p><b>Fees</b> <br /><p>The following fees and deposits are charged by the property at time of service, check-in, or check-out. </p> <ul> <li>Self parking fee: EUR 8 per day</li> </ul> <p>The above list may not be comprehensive. Fees and deposits may not include tax and are subject to change. </p></p><p><b>Mandatory Fees and Taxes</b> <br /><p>You'll be asked to pay the following charges at the property:</p> <ul><li>A tax is imposed by the city: EUR 6 per person, per night, up to 10 nights. This tax does not apply to children under 10 years of age. </li></ul> <p>We have included all charges provided to us by the property. However, charges can vary, for example, based on length of stay or the room you book. </p></p>. -This booking is non-amendable, If you need to make an amendment, please cancel and re-book for the new dates or room type.. Breakfast Buffet. 1 double bed, 2 single beds. Economy Double or Twin Room. <p><b>Know Before You Go</b> <br /><ul> <li>All guests, including children, must be present at check-in and show their government-issued photo ID card or passport.</li> <li>Cash transactions at this property cannot exceed EUR 2999.99, due to national regulations. For further details, please contact the property using information in the booking confirmation. </li> <li>One child 3 years old or younger stays free when occupying the parent or guardian's room, using existing bedding. </li> </ul></p><p><b>Fees</b> <br /><p>The following fees and deposits are charged by the property at time of service, check-in, or check-out. </p> <ul> <li>Self parking fee: EUR 8 per day</li> </ul> <p>The above list may not be comprehensive. Fees and deposits may not include tax and are subject to change. </p></p><p><b>Mandatory Fees and Taxes</b> <br /><p>You'll be asked to pay the following charges at the property:</p> <ul><li>A tax is imposed by the city: EUR 6 per person, per night, up to 10 nights. This tax does not apply to children under 10 years of age. </li></ul> <p>We have included all charges provided to us by the property. However, charges can vary, for example, based on length of stay or the room you book. </p></p>. -This booking is non-amendable, If you need to make an amendment, please cancel and re-book for the new dates or room type.. Breakfast Buffet",
        "service": "hotels",
        "status": "confirmed",
        "supplier": {
          "reference": "BG66666GZSPL"
        }
      }
    ],
    "status": "confirmed"
  },
  "status": "done"
}

Most of the details are a reflection of the data sent by you. the following details are of notice:

Element Description
bookingID The Innstant system booking ID
payment The payment options used in the booking
.method The payment method used
.clearingState In case a credit card was used, the clearing state tells you if the booking was charged or just authorized. possible values are enrollment, authorization, payment and pre-payment
.paymentStatus paid or unpaid
services.supplier.reference the supplier reference that should appear on the voucher

Understanding the different statuses on the bookings response

We return 3 status attributes as part of the book response, each of them has a different purpose.
In order to know if a specific service within the booking was confirmed - you must check the individual statuses on each service in the booking.

Element Description
status message status - tells you if there was a communication error
content.status the booking status
content.services.status status of each service in the booking

Possible status values

Element Description
confirmed The booking/item was confirmed
initialized The booking/item started the booking process
partially_confirmed The booking was only partially confirmed, you must check each item to make sure which one was not confirmed
failed The booking/item failed to confirm
error There was an error during the booking process
cancelled The booking/item was cancelled
pending_cancellation The booking/item was not cancelled yet but is waiting to be cancelled
on_request The booking/item is pending the provider approval or rejection
rejected The booking/item was rejected
unknown ¯_(ツ)_/¯

Recoverable errors

In some cases you’ll get a “recoverable error”. This can happen if there is already a booking on that hotel for the same guest, if the price changed, or if the processing commission is too high (if you’re using the processing feature).

The response will have the error code a70x or a21xx (i.e. a702, a2100, etc) and it can be recovered by calling the endpoint: /complete-booking/ with the content:

{"completeCode":"a702","paymentSettings":{"paymentAmount":"net","paymentDate":"billing-terms","transactionFeeCharge":true},"bookingID":xx1234}

Element Description
completeCode The recoverable error code you received in the initial booking response
paymentSettings the same paymentSettings node you sent in the booking request
bookingID the booking ID from the initial booking response

Cancel

Request content

{
  "BookingID": 1234,
  "CancelReason": "The dog is sick",
  "Force": false,
  "IsManual": false
}

Request

POST https://example.com/booking-cancel

Attribute Description
BookingID The booking ID you would like to cancel
CancelReason The reason for the cancellation, can be left blank
Force Should the booking be cancelled in any case, without calling the provider - USE FALSE UNLESS YOU KNOW WHAT YOU ARE DOING
IsManual Is the booking being cancelled by a human request or by an automated process

Response

Response content

{
  "content": {
    "Status": "done",
    "Warnings": []
  },
  "status": "done"
}
Attribute Description
content.Status Was the cancellation successful (done) or unsuccessful (error)
content.Warnings This array will be returned only if force cancellation was used

Booking Details

Request

GET https://example.com/booking-details/[booking-id]

Attribute Description
BookingID The booking ID you would like to get details for

Response

The response is the same as booking response

Events

Flow

The common case usage is quite simple:

  1. Initiate a search
  2. get results
  3. [optional] poll the same search to get better results
  4. get details (times)
  5. [optional] get the cancellation policy, if it’s not returned as part of the search/poll results
  6. run a pre-book call
  7. book

Search

Request

curl \
  -H "aether-application-key: [app-key]" \
  -X POST
  -d @request-file.json
  https://example.com/events/search

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST https://example.com/events/search

Attribute Description
client Information about the client who is running the search. This node is optional, but sending it may provide special rates, for example for mobile users.
.client/ip The IP of the end-client
.client/userAgent The user agent of the end-client
currencies A list of currencies you wish to get your results in. The first currency on the list will be the default currency of the search
customerCountry 2 letter ISO code of the customer country running the search. Note: that the same customer country must be used on the booking, and giving a wrong or inaccurate customer country may result in the venue not honoring the booking.
customFields See below
dates The from and to dates, format: YYYY-MM-DD
destinations The search destinations array
.destinations/[item]/type can be location only
.destinations/[item]/id the entity id based on the type
filters See below
pax See below

Custom Fields

This part is relevant for deep-integrations only, where you have your own suppliers connected via this API and need to pass parameters to specific providers.
An example of such a use-case is a B2B system that wants the agents using the system to collect loyalty points from a specific directly-contracted provider. In order to achieve that, you need to pass the agent credentials for that specific provider during search, and these credentials will be used to contact the provider.

Example of custom fields in the request

{
  "customFields": {
    "agentId": 1,
    "whatever": "shalgon"
  }
}

Pax

The pax array specifies the desired room configuration.
Each room is an object and each object consists of adults and children, where the children element is an array with their ages.
For example: in order to search for a room with 1 adult and 2 children ages 12 and 14, you need to create an object that looks like this:
{
“adults”: 1,
“children”: [12,14]
}

Note that different suppliers and different channels treat “child” differently, so even if you send a child aged 15, some properties may treat it as an adult while others as a child.

Example of pax in the request

{
  "pax": [
    {
      "adults": 2
    },
    {
      "adults": 1,
      "children": [12, 14]
    }
  ]
}

Response

The response will return the results received until the search was completed.

Response

{
  "timestamp": 1561875522,
  "requestTime": "2019-06-30 06:18:42",
  "status": "done",
  "completed": 100,
  "sessionId": "x:y:z",
  "processTime": 113,
  "results": [
    {
      "price": {
        "amount": 176.08,
        "currency": "EUR"
      },
      "netPrice": {
        "amount": 145.38,
        "currency": "EUR"
      },
      "barRate": null,
      "confirmation": "immediate",
      "paymentType": "pre",
      "packageRate": false,
      "commissionable": true,
      "providers": [
        {
          "id": "1nb9ff34gferb435bv",
          "name": "example"
        }
      ],
      "specialOffers": [],
      "items": [
        {
          "name": "Colosseum Express private Tour - skip the line tickets!",
          "categories": [
            {
              "id": 3,
              "name": "Cultural & Theme Tours"
            },
            {
              "id": 21,
              "name": "Private & Custom Tours"
            },
            {
              "id": 18,
              "name": "Family Friendly"
            },
            {
              "id": 14,
              "name": "Walking & Biking Tours"
            }
          ],
          "images": ["https://example.com/directory/image.jpg"],
          "thumbnail": "https://example.com/directory/thumbnail.jpg",
          "locations": ["Roma, Italy"],
          "duration": "60 to 90 minutes",
          "reviews": {
            "rating": 0,
            "count": 0
          },
          "description": "Learn the history of Rome. <br>Immerse yourself in the imperial Rome and learn all about the gladiators fighting in the Roman Colosseum and the emperors who decided their fates.<br>Tickets: included.<br>Duration: up to 1h30 hours.<br>Meeting Point: Largo Gaetana Agnesi above metro stop “Colosseum”.<br>Features: Professional Certified Guides, Skip the Line and Save Time, Private Tours"
        }
      ],
      "cancellation": {
        "type": "fully-refundable",
        "frames": [
          {
            "from": "2019-06-30 00:00:00",
            "to": "2019-09-09 23:59:59",
            "penalty": {
              "amount": 0,
              "currency": "EUR"
            }
          },
          {
            "from": "2019-09-09 00:00:00",
            "to": "2019-09-12 23:59:59",
            "penalty": {
              "amount": 176.08,
              "currency": "EUR"
            }
          }
        ]
      },
      "code": "1234abcd"
    }
  ]
}

The response is an array of results, each result consists of these attributes:

Attribute Description
items An array of items the result id holds. The booking will be made on the result including all the items in it. The prices are only on the result level.
.item/name The name of the offered event
.item/categories The categories of the events
.item/images array of images of the event
.item/thumbnail thumbnail image of the event
.item/locations locations of the event
.item/duration duration of the event
.item/reviews object of 2 fields: “rating” and “count”
.item/description description of the event
barRate Price (amount/currency) of the BAR, the price which you are not allowed to sell below on B2C platforms.
cancellation See below
code The result code, use this for the next steps
commissionable boolean, indicates whether you can apply a commission on top of the price or not
confirmation immediate or on-request
netPrice The net price (amount/currency) of this result
packageRate boolean, indicates whether this result can be sold as a stand-alone offer or if it requires to be sold as part of a package
payment pre or post, indicates whether this is a pre-paid result or a pay-at-the-venue result
price The gross price of the result

In addition, there are several other attributes that are of interest:

Attribute Description
sessionId The session ID of the search
status The status of the search, whether it is done, working, or failed
timestamp The server timestamp of the response. this can be used to poll by delta
requestTime The request date time in Human readable format
completed Integer, percentage of the progress. 0 means no tasks were completed, 100 means all tasks were completed, everything in between in “in process”. Please note this attribute is for Innstant’s internal use only. To check if the search was completed or not please refer only to the status property.
processTime Processing time in milliseconds.

In case of post-payment results, you might get a transaction node in the response. This node will be returned in case you defined a “transaction fee” markup for this purpose.
This is being used in case the user has to pay a gross amount directly to the venue, but you still want to collect something for the booking.

Example of a transaction fee in the response

"transactionFee": {
    "amount": 25.7,
    "currency": "EUR"
}

Cancellation Policy

The cancellation policy is build from frames.
Each frame has a start date (from), end date(to), and a penalty.
These frames tells you exactly what will be the penalty on each date starting from the booking date until the check-in date.
After the check-in date the cancellation penalty should be assumed as 100%.

Poll

Request

curl \
  -H "aether-application-key: [app-key]" \
  -X POST
  -d @request-file.json
  https://example.com/events/poll[/timestamp]

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST https://example.com/events/poll[/timestamp]

The poll request & response are identical to the search request & response with the exception of the endpoint.
You can send as many polls as you like until the status in the response is working. Once it finishes, the status changes to done and this means no new results will show up in your next poll.
Check out the Flow chapter in the beginning to get a better understanding of this method.
You can add an optional timestamp to the URL, the timestamp must be the one returned in the previous search/poll response in order to get the deltas.
If you do not send the timestamp in the URL, you will get ALL results every time.

Note that the search and poll requests much be identical.

Get cancellation policy

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST http://example.com/events/cancellation/[event code]

The request consists of the desired event code (in the url) and the original search (in the request body).

Response

The response is exactly the same as the poll response, but with the cancellation frames in place.

Details/Times

Request content

{
  "client": {
    "ip": "1.2.3.4",
    "userAgent": "Example User Agent"
  },
  "currencies": ["USD"],
  "customerCountry": "IL",
  "customFields": [],
  "dates": {
    "from": "2018-09-20",
    "to": "2018-09-22"
  },
  "destinations": [
    {
      "id": 5252,
      "type": "location"
    }
  ],
  "filters": [],
  "pax": [
    {
      "adults": 2
    }
  ]
}

Request

POST http://example.com/events/details/[event code]

The request consists of the desired event code (in the url) and the original search (in the request body).

Response


  "timestamp": 1561875573,
  "requestTime": "2019-06they s-30 06:19:33",
  "status": "done",
  "completed": 100,
  "sessionId": "x:y:z",
  "processTime": 1900,
  "error": {
    "code": 2100,
    "message": "Price has changed. Please try to book another item or confirm new result price"
  },
  "results": [
    {
      "price": {
        "amount": 158.45,
        "currency": "EUR"
      },
      "netPrice": {
        "amount": 130.83,
        "currency": "EUR"
      },
      "barRate": {
        "amount": 163.8,
        "currency": "EUR"
      },
      "confirmation": "on request",
      "paymentType": "pre",
      "packageRate": false,
      "commissionable": true,
      "providers": [],
      "specialOffers": [],
      "items": [
        {
          "name": "Villa Borghese Bike Tour in Rome",
          "categories": [
            {
              "id": 14,
              "name": "Walking & Biking Tours"
            },
            {
              "id": 11,
              "name": "Tours & Sightseeing"
            }
          ],
          "images": [
            "https://example.com/directory/image.jpg"
          ],
          "thumbnail": "https://example.com/directory/thumbnail.jpg",
          "locations": [
            "Roma, Italy"
          ],
          "duration": "3 hours",
          "reviews": {
            "rating": 5,
            "count": 3
          },
          "description": "Unforgettable guided bike tour in Villa Borghese, Rome's most important monumental Villa (complex of gardens), house of the superb art collection of Cardinal Scipione Borghese, nephew of Pope Paul V and patron of painter Caravaggio and architect and sculptor Bernini.",
          "remarks": {
            "returnDetails": "Returns to original departure point<br />",
            "inclusions": "Italian espresso coffee, Bottled water, Local guide, Use of bicycle, Use of helmet",
            "exclusions": "Food and drinks, Entrance fees (If you want to visit the inside of the Borghese Gallery or the Bio Park, please specify when booking), Entry/Admission - Villa Borghese, Entry/Admission - Museo Pietro Canonica, Entry/Admission - Silvano Toti Globe Theatre Roma, Entry/Admission - The San Carlino Gran Teatro Dei Piccoli",
            "general": "Confirmation will be received within 48 hours of booking, subject to availability<br>\\r\\nA minimum of 2 persons per booking is required<br>\\r\\nIf you want to visit the inside of the Borghese Gallery or the Bio Park, please specify when booking",
            "termsAndConditions": null
          },
          "times": [
            {
              "id": "xxx",
              "date": "2019-09-14",
              "time": "10:00 AM",
              "type": "departure",
              "location": "Via del Fiume, 7, 00186 Roma RM, Italy<br />"
            }
          ],
          "dispatchOptions": [
            {
              "id": "yyy",
              "type": "print",
              "price": {
                "amount": 0,
                "currency": "USD"
              },
              "description": "You can present either a paper or an electronic voucher for this activity."
            }
          ]
        }
      ],
      "cancellation": {
        "type": "fully-refundable",
        "frames": [
          {
            "from": "2019-06-30 00:00:00",
            "to": "2019-09-09 23:59:59",
            "penalty": {
              "amount": 0,
              "currency": "EUR"
            }
          },
          {
            "from": "2019-09-09 00:00:00",
            "to": "2019-09-12 23:59:59",
            "penalty": {
              "amount": 158.45,
              "currency": "EUR"
            }
          }
        ]
      },
      "code": "zzzxxcc1"
    },
    ...
  ]
}

The response is exactly the same as the poll response, but has several additional fields.

Attribute Description
.item/remarks [If exists] important information about the event
.item/times List of available times for specific event. See description below
.item/dispatchOptions List of available dispatch options. See description below

Description of time object:

Attribute Description
.time/id Id of specific time option, will be used on next steps
.time/date Date of the event
.time/time Time of the event
.time/type Type of this time option. Available types: departure or return
.time/location Location of the event

Description of dispatchOption object:

Attribute Description
.dispatchOption/id Id of specific dispatch option, will be used on booking stage
.dispatchOption/type Type of this dispatch option. Available types: print, collect, post
.dispatchOption/price Price of specific dispatch option. Will be added to total price
.dispatchOption/description Description of the dispatch option

Pre-Book

Request content

{
  "services": [
    {
      "searchRequest": {
        "destinations": [
          {
            "id": 5252,
            "type": "location"
          }
        ],
        "dates": {
          "from": "2019-09-14",
          "to": "2019-09-17"
        },
        "customerCountry": "IL",
        "pax": [
          {
            "adults": 2
          }
        ],
        "currencies": ["EUR"],
        "filters": [],
        "service": "events"
      },
      "searchCodes": [
        {
          "code": "1234Jk$156",
          "options": [
            {
              "name": "time",
              "value": "aaabbbccc1"
            }
          ],
          "pax": [
            {
              "adults": 2,
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

Request

POST http://example-booking.com/pre-book

Note that this request is being send to a different domain than the one used for searching

Element Description
searchCodes The result codes you are planning to book. you can send as many search codes as you like in this array.
.code the code from the result
.pax the pax related to the specific code
.options the time value you wish to book
searchRequest the original, unchanged, search request

Response

Response content

{
  "content": {
    "ImmediateCharge": false,
    "LoyaltyPoints": [],
    "PaymentDueDate": "2019-09-09",
    "PaymentMethods": [
      {
        "methodDescription": "",
        "methodName": "account_credit",
        "paymentSettings": {
          "creditCardForm": false,
          "requiredFields": []
        },
        "status": "enabled"
      },
      {
        "methodDescription": "",
        "methodName": "credit_card",
        "paymentSettings": {
          "creditCardForm": true,
          "requiredFields": []
        },
        "status": "enabled"
      }
    ],
    "ProfileVersion": "111",
    "Services": {
      "events": [
        {
          "barRate": {
            "amount": 231,
            "currency": "EUR"
          },
          "cancellation": {
            "frames": [
              {
                "from": "2019-07-15 00:00:00",
                "penalty": {
                  "amount": 0,
                  "currency": "EUR"
                },
                "to": "2019-09-09 23:59:59"
              },
              {
                "from": "2019-09-09 00:00:00",
                "penalty": {
                  "amount": 92.25,
                  "currency": "EUR"
                },
                "to": "2019-09-12 23:59:59"
              }
            ],
            "type": "fully-refundable"
          },
          "code": "zaq123",
          "commissionable": true,
          "confirmation": "immediate",
          "items": [
            {
              "categories": [
                {
                  "id": "14",
                  "name": "Walking & Biking Tours"
                },
                {
                  "id": "11",
                  "name": "Tours & Sightseeing"
                }
              ],
              "description": "Explore Rome on a relaxed bike tour with a guide, discovering sights like Castel Sant'Angelo, Piazza Navona, the Pantheon, Trevi Fountain, the Spanish Steps, and the Colosseum. <br>Biking is a great way to soak up the atmosphere of this historical city.",
              "dispatchOptions": [
                {
                  "description": "You can present either a paper or an electronic voucher for this activity.",
                  "id": "5ecf17ca",
                  "price": {
                    "amount": 0,
                    "currency": "EUR"
                  },
                  "type": "print"
                }
              ],
              "duration": "4 hours",
              "images": ["https://example.com/image.jpg"],
              "locations": ["Rome, Italy"],
              "name": "Highlights of Rome Bike Tour",
              "questions": [
                {
                  "id": "1",
                  "message": "Enter your date of birth.",
                  "options": [],
                  "required": true,
                  "subTitle": "(e.g. 20 October 1970)",
                  "title": "Date of Birth",
                  "type": "free text"
                },
                {
                  "id": "2",
                  "message": "For safety reasons you must enter the height of all passengers. Please indicate inches or centimetres.",
                  "options": [],
                  "required": true,
                  "subTitle": "(eg. 5'2\", 158cm etc)",
                  "title": "Passenger Heights",
                  "type": "free text"
                }
              ],
              "remarks": {
                "exclusions": "Food and drinks, unless specified, Alcoholic drinks (available to purchase), Gratuities",
                "general": "Confirmation will be received at time of booking<br>\\r\\nChildren must be accompanied by an adult",
                "inclusions": "Use of bike, Local guide",
                "returnDetails": "Returns to original departure point",
                "termsAndConditions": "For a full refund, cancel at least 24 hours in advance of the start date of the experience."
              },
              "reviews": {
                "count": 15,
                "rating": 5
              },
              "thumbnail": "https://example.com/thumbnail.jpg",
              "times": [
                {
                  "id": "23456z",
                  "location": "Central Rome",
                  "time": "9:45 AM",
                  "type": "departure"
                }
              ]
            }
          ],
          "netPrice": {
            "amount": 92.25,
            "currency": "EUR"
          },
          "netPriceInClientCurrency": {
            "amount": 92.25,
            "currency": "EUR"
          },
          "packageRate": false,
          "paymentMethod": "direct",
          "price": {
            "amount": 92.25,
            "currency": "EUR"
          },
          "priceWithoutTax": {
            "amount": 92.25,
            "currency": "EUR"
          },
          "requestCode": "vvv555",
          "surcharges": [],
          "taxAmount": null,
          "token": "BBBCCC123",
          "transactionFee": {
            "amount": 0,
            "currency": "EUR"
          },
          "warnings": [
            {
              "code": 2100,
              "message": "Your item is not available under the originally requested price, please review the selected alternative or go back to select another result."
            }
          ]
        }
      ]
    }
  },
  "status": "done"
}
Element Description
PaymentMethods The acceptable payment methods for this booking
.methodName the name of the payment method. a standard integration will use account_credit or credit_card.
.methodDescription additional description of the method, for example if the method is a saved credit card token on the account, the description can say something like “Credit card ending with 1234”
.status whether this option is enabled for this booking
.paymentSettings specific settings for the payment method
..creditCardForm boolean, specifies if you need to show the credit card form to the user
..requiredFields key/value array of objects, consists of required fields to request from the user. for example the enett agent id in case of enett payment integration
Services The services that are about to be booked
.events an array of events that are about to be booked
..barRate The minimum price (amount/currency) that can be shown on B2C website
..cancellation The cancellation policies, see the search response for details
..code The event code
..commissionable Whether or not you can add commission to the final price
..confirmation immediate or on-request
..items a collection of items
..item.categories name and id of the taxonomy categories
..item.description free text description
..item.dispatchOptions see below
..item.duration The estimated duration of the event
..item.images an array of image URLs
..item.locations an array of location strings where the event is taking place
..item.name The event name
..item.questions see below
..item.remarks an array of remarks with key/value
..item.reviews the quantity (count) and value (rating) of the reviews for the event
..item.thumbnail a URL of a thumbnail image
..item.times see below
..netPrice The net price (amount/currency) of the booking, i.e. the amount that you need to pay the provider
..netPriceInClientCurrency normalized amount to the currency you requested
..packageRate if true, this offer cannot be sold as a stand-alone booking, and the price must never be shown to the user without it being bundled as a package with other products.
..payment pre or post
..price The gross price (amount/currency) of the booking, i.e. the amount you charge your customer
..priceWithoutTax the gross price minus the tax amount
..requestCode the code you sent in the request. this is used in case the result changed due to price or availability. it is for your use only and should not be sent in further requests.
..surcharges if there are any additional surcharges applied to the price
..taxAmount the amount of the tax, if applicable
..token the booking token you will have to send in order to make the actual booking
..transactionFee any additional fee that may apply for the cost of processing the transaction
..warnings optional node, returned only in case of price or availability change

Description of dispatchOptions object. Different methods might have additional costs (like snail-mail or a courier service):

Attribute Description
.description free text description of the dispatch option
.id the id of the option, you’ll need to use it for booking
.price the (additional) price of the dispatch option, can be 0
.type the type of the option. can be print, collect, or post

Description of questions object. It is mandatory to show the questions to the end-user, collect the answers from them, and send them as part of the booking requests.

Attribute Description
.id the id of the question
.message the question text
.options if the answers should be limited to the set described in this element
.required if mandatory
.subTitle description of the question (example, explanation, etc.)
.title the title of the question
.type can be free text, one, or multiple

Description of times object.

Attribute Description
.id the id of the time option
.location the location of the time, free text, usually describes the location of the option
.time the time of the event, timezone is always the local time
.type can be departure or return
"warnings": [
            {
                "code": 2100,
                "message": "Your item is not available under the originally requested price, please review the selected alternative or go back to select another result."
            }
        ]

Book

Request

POST http://example-booking.com/book

Note that this request is being send to a different domain than the one used for searching

{
  "creditCard": {
    "cardNumber": "4111 1111 1111 1111",
    "cvc": "555",
    "expiry": {
      "month": "12",
      "year": "2019"
    },
    "name": {
      "first": "Yogi",
      "last": "Berra"
    }
  },
  "customer": {
    "birthDate": "1975-09-14",
    "contact": {
      "address": "housington 66",
      "city": "cityngton",
      "country": "NL",
      "email": "test@example.com",
      "phone": "555-4433222",
      "state": "N/A",
      "zip": "88776"
    },
    "name": {
      "first": "Yogi",
      "last": "Berra"
    },
    "title": "M"
  },
  "paymentMethod": {
    "methodName": "account_credit"
  },
  "reference": {
    "agency": "my agency reference",
    "voucherEmail": "test@example.com"
  },
  "services": [
    {
      "bookingRequest": [
        {
          "code": "kuegkrug398y3:222$fjfjfj",
          "options": [
            {
              "name": "time",
              "value": "5bfdcf5b"
            },
            {
              "name": "dispatch",
              "value": "5ecf17ca"
            },
            {
              "name": "questions",
              "value": [
                {
                  "id": "1",
                  "value": "20 October 1970"
                },
                {
                  "id": "2",
                  "value": "10 meter"
                }
              ]
            }
          ],
          "pax": [
            {
              "adults": [
                {
                  "contact": {
                    "address": "housington 66",
                    "city": "cityngton",
                    "country": "NL",
                    "email": "test@example.com",
                    "phone": "555-4433222",
                    "state": "N/A",
                    "zip": "88776"
                  },
                  "lead": true,
                  "name": {
                    "first": "Yogi",
                    "last": "Berra"
                  },
                  "title": "M"
                },
                {
                  "name": {
                    "first": "Mona",
                    "last": "Lisa"
                  },
                  "title": "F"
                }
              ]
            }
          ],
          "token": "1515BEE8"
        }
      ],
      "searchRequest": {
        "currencies": ["USD"],
        "customerCountry": "NL",
        "dates": {
          "from": "2018-05-04",
          "to": "2018-05-05"
        },
        "destinations": [
          {
            "id": 5252,
            "type": "location"
          }
        ],
        "filters": [],
        "pax": [
          {
            "adults": 2,
            "children": []
          }
        ],
        "service": "events"
      }
    }
  ]
}
Element Description
creditCard In case you are paying with a credit card, you need to send all relevant details
customer The customer details of the customer that is making the booking. It doesn’t have to be the same details as the travelers
payment how are you going to pay for the booking. this value must be one of the options returned in the pre-book
.method one of: credit_card, account_credit, or enett
.securePaymentUrl in case the payment method is credit_card, you need to supply a URL where to send the user after the payment process.
reference your references
.agency free text of your agency reference, i.e. your internal booking id
.voucherEmail an email address to send the voucher to
services this array of elements consists of the desired items you want to book. Each element contains 2 sub-elements: the original search request, and the booking request.
.searchRequest the original search request
.bookingRequest this element will contain the guest information and the payment details.
..code The result code you wish to book, this code comes from the search/poll response
..token the token from the pre-book call
..pax The pax configuration array for the booked properties. Each element in the array is a booked room
…adults the details of the adults in the room
….name first/last names of the guest
….title M for male, F for female (for children - see below)
….lead boolean, set to true if this is the lead pax. each booking must have one lead. do not set this flag on more than one.
….contact contact details of the lead pax, can be different than the customer on the booking.
..options the relevant options you’d like to book. always include time and dispatch with the relevant values. if there are questions, you need to send the id and values of the answers.

In case you want to send a booking request for children, the child element must include another attribute called “birthDate” with a date value in the format YYYY-MM-DD.
Example of a children node:
“children”: [
{
    ”birthDate”: “2014-04-20”
    ”name”: {
        ”first”: “test”,
        ”last”: “test”
    },
    ”title”: “C”
}
]

Response

Response content

{
  "content": {
    "bookingID": 12345,
    "bookingDate": "2019-07-16",
    "status": "confirmed",
    "customer": {
      "title": "MR",
      "name": {
        "first": "john",
        "last": "smith"
      },
      "birthDate": "1986-01-01",
      "contact": {
        "country": "DE",
        "state": "N/A",
        "address": "123 somestreet",
        "city": "somecity",
        "phone": "123456789",
        "zip": "1234567",
        "email": "you@example.com"
      },
      "create": false
    },
    "price": {
      "amount": 96.86,
      "currency": "EUR"
    },
    "netPrice": {
      "amount": 96.86,
      "currency": "EUR"
    },
    "taxAmount": null,
    "services": [
      {
        "event": {
          "name": "Highlights of Rome Bike Tour",
          "categories": [
            {
              "id": "14",
              "name": "Walking & Biking Tours"
            },
            {
              "id": "11",
              "name": "Tours & Sightseeing"
            }
          ],
          "images": ["https://example.com/media/image.jpg"],
          "thumbnail": "https://example.com/media/thumbnail.jpg",
          "locations": ["Rome, Italy"],
          "duration": "4 hours",
          "reviews": {
            "rating": 5,
            "count": 15
          },
          "description": "Explore Rome on a relaxed bike tour with a guide, discovering sights like Castel Sant'Angelo, Piazza Navona, the Pantheon, Trevi Fountain, the Spanish Steps, and the Colosseum. <br>Biking is a great way to soak up the atmosphere of this historical city."
        },
        "dispatchOption": {
          "id": "5ecf17ca",
          "type": "print",
          "price": {
            "amount": 0,
            "currency": "EUR"
          },
          "description": "You can present either a paper or an electronic voucher for this activity.",
          "details": null,
          "voucherURL": "https://example.com//voucher.ext?1234567890"
        },
        "time": {
          "id": "5bfdcf5b",
          "time": "9:45 AM",
          "type": "departure",
          "location": "Central Rome",
          "remarks": {
            "address": "Via dei Mille 8 ROMA",
            "directions": "Meet your guide at our office: Via dei Mille 8 ROMA"
          }
        },
        "answers": [
          {
            "id": "1",
            "title": "Date of Birth",
            "value": "20 October 1988"
          },
          {
            "id": "2",
            "title": "Passenger Heights",
            "value": "1 meter"
          }
        ],
        "itemId": 1,
        "service": "events",
        "startDate": "2019-09-14",
        "endDate": "2019-09-17",
        "paymentType": "pre",
        "quantity": 1,
        "code": "1234$abcd",
        "status": "confirmed",
        "supplier": {
          "reference": "1234:abcd:t$yy5"
        },
        "price": {
          "amount": 96.86,
          "currency": "EUR"
        },
        "taxAmount": null,
        "netPrice": {
          "amount": 96.86,
          "currency": "EUR"
        },
        "cancellation": {
          "type": "fully-refundable",
          "frames": [
            {
              "from": "2019-07-16 00:00:00",
              "to": "2019-09-09 23:59:59",
              "penalty": {
                "amount": 0,
                "currency": "EUR"
              }
            },
            {
              "from": "2019-09-09 00:00:00",
              "to": "2019-09-12 23:59:59",
              "penalty": {
                "amount": 96.86,
                "currency": "EUR"
              }
            }
          ]
        },
        "pax": [
          {
            "adults": [
              {
                "lead": true,
                "title": "MR",
                "name": {
                  "first": "test",
                  "last": "test"
                },
                "birthDate": "1986-01-01",
                "contact": {
                  "country": "IL",
                  "state": "N/A",
                  "address": "N/A",
                  "city": "",
                  "phone": "N/A",
                  "zip": "N/A",
                  "email": "someone@example.com"
                }
              },
              {
                "lead": false,
                "title": "MR",
                "name": {
                  "first": "john",
                  "last": "smith"
                },
                "birthDate": "1986-01-01",
                "contact": {
                  "country": "IL",
                  "state": "N/A",
                  "address": "N/A",
                  "city": "",
                  "phone": "N/A",
                  "zip": "N/A",
                  "email": "someone@example.com"
                }
              }
            ],
            "children": []
          }
        ],
        "remarks": {
          "returnDetails": "Returns to original departure point",
          "inclusions": "Use of bike, Local guide",
          "exclusions": "Food and drinks, unless specified, Alcoholic drinks (available to purchase), Gratuities",
          "general": "Confirmation will be received at time of booking<br>\\r\\nChildren must be accompanied by an adult",
          "termsAndConditions": "For a full refund, cancel at least 24 hours in advance of the start date of the experience."
        }
      }
    ],
    "payment": {
      "method": "credit_card",
      "clearingState": null,
      "paymentStatus": "paid"
    },
    "options": {
      "emails": ["confirmation_email"]
    },
    "reference": {
      "agency": "",
      "voucherEmail": ""
    },
    "ProfileVersion": "1234"
  },
  "status": "done"
}

Most of the details are a reflection of the data sent by you. the following details are of notice:

Element Description
bookingID The Innstant system booking ID
payment The payment options used in the booking
.method The payment method used
.clearingState In case a credit card was used, the clearing state tells you if the booking was charged or just authorized. possible values are enrollment, authorization, payment and pre-payment
.paymentStatus paid or unpaid
services.supplier.reference the supplier reference that should appear on the voucher
services.dispatchOption details about the voucher

Understanding the different statuses on the bookings response

We return 3 status attributes as part of the book response, each of them has a different purpose.
In order to know if a specific service within the booking was confirmed - you must check the individual statuses on each service in the booking.

Element Description
status message status - tells you if there was a communication error
content.status the booking status
content.services.status status of each service in the booking

Possible status values

Element Description
confirmed The booking/item was confirmed
initialized The booking/item started the booking process
partially_confirmed The booking was only partially confirmed, you must check each item to make sure which one was not confirmed
failed The booking/item failed to confirm
error There was an error during the booking process
cancelled The booking/item was cancelled
pending_cancellation The booking/item was not cancelled yet but is waiting to be cancelled
on_request The booking/item is pending the provider approval or rejection
rejected The booking/item was rejected
unknown ¯_(ツ)_/¯

Cancel

Request content

{
  "BookingID": 1234,
  "CancelReason": "The dog is sick",
  "Force": false,
  "IsManual": false
}

Request

POST https://example.com/booking-cancel

Attribute Description
BookingID The booking ID you would like to cancel
CancelReason The reason for the cancellation, can be left blank
Force Should the booking be cancelled in any case, without calling the provider - USE FALSE UNLESS YOU KNOW WHAT YOU ARE DOING
IsManual Is the booking being cancelled by a human request or by an automated process

Respone

Response content

{
  "content": {
    "Status": "done",
    "Warnings": []
  },
  "status": "done"
}
Attribute Description
content.Status Was the cancellation successful (done) or unsuccessful (error)
content.Warnings This array will be returned only if force cancellation was used

Booking Details

Request

GET https://example.com/booking-details/[booking-id]

Attribute Description
BookingID The booking ID you would like to get details for

Response

The response is the same as booking response

Lookups

Board Codes

Board Code Description
RO Room Only
BB Breakfast
HB Half Board
FB Full Board
AI All Inclusive

FAQ

Q: How many adults and children can accommodate a single room?

A: 1-4 adults, 0-4 children

Q: Which ages are considered as children?

A: Each provider treats it differently, but usually guests are counted as children if their ages are between 0 and 16

Q: What is the min/max length of stay (in nights) allowed in a search request?

A: 1 to 30 nights

Q: Is it possible to send more than one hotel code in the same request?

A: Yes, this feature is supported. You can send max 250 hotel codes per request

Q: Is it possible to send more than one destination code in the same request?

A: No, this feature will be supported in the future

Q: I get an error in the search response: “”Invalid Request! Make sure it’s a valid JSON and has allowed values as described in documentation””

A: Make sure you included the header Content-Type: application/json, and that your search dates are in the future.

Q: I get a status: “working” in search response, but no results

A: You need to send at least one Poll request in order to get results.

Q: How many polls do I have to send in order to get all the results?

A: Depends on your preferred timeout. We work with many providers, some are faster than others and return results in a few seconds, while the slower ones require more time.
The polling mechanism allows you to decide how much time you want to keep polling. The first results will be received in 3 to 5 seconds, and you’ll be able to get new ones by keeping polling every 3 seconds until you decide to stop.

Q: When searching for multiple rooms, can I select which items I want to book from the different results?

A: No. Each of the result objects in the results array has the exact number of rooms to match your search criteria, and should be booked as a whole, using the result code.

Q: For how long are the search results bookable?

A: Every search session is valid for 30 minutes. If more than 30 minutes have passed, the results are no longer bookable, and you’ll have to run a new search.

Q: I get an error message in pre-book/book response

A: Make sure that you try to book the search results within 30 minutes from initial search. In addition, verify that your booking matches your search criteria exactly: same nationality, number of guests, number of rooms, children ages, etc.

Q: Are all the fields in the customer object mandatory?

A: Yes. And without a proper country code that matches the one in search request, the booking will probably fail. As for the other fields, if you don’t have the customer’s phone number or zip, for example, you can send “N/A”, but the fields must be included.

Q: Why do I get an “on_request” booking status even though I’ve excluded on-request in my search filters?

A: Even though the result you got has not been classified as “on request” when you first initiated the search, its status may change on the provider end by the time you make the booking. In such cases, it is mandatory to run the booking-details request to verify it’s status at least once a day until the status is changed to either confirmed or rejected. If the status does not change after 5 working days, it is mandatory to contact customer support and verify the status manually.

Q: I get empty results when the second request with the same parameters is sent

A: To avoid this please make sure that you send the first poll request without a timestamp. The timestamp should be used only in the second poll.

Q: Do you have passenger name restrictions?

A: Yes. First and last name should contain alphabetic characters only and be at least one character. Empty names, no white space or special characters allowed. Please only use the letters a-z, A-Z (Latin alphabet).

Static Data

Introduction

The static data is accessible via a web service or by downloading data in a CSV file. The data is updated constantly, so make sure to update it at least once a week.

In order to access the static data, you will need to send a valid application key in the request header.

Please note: It is not permitted to use static data dynamically. This means you must download the static data and keep it updated on your side.

Methods

Countries

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/countries

Response

[
  {
    "continent": "Europe",
    "id": "AD",
    "name": "Andorra",
    "region": "Southern Europe",
    "regions": [
        {
            "code": "AN",
            "name": "Andorra la Vella"
        },
        {
            "code": "EE",
            "name": "Escaldes-Engordany"
        }
    ]
  },
  {
    "continent": "Europe",
    "id": "AL",
    "name": "Albania",
    "region": "Southern Europe",
    "regions": [
      {
        "code": "TR",
        "name": "Tirane"
      }
    ]
  },
  ...
]

GET https://example.com/countries

Attribute Description
id ISO Alpha-2 country code
name The name of the country
continent Name of the continent
region The region within the continent
regions a collection of provinces or regions within the country

Destinations

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/destinations/AL

Response

[
  {
    "countryid": "AL",
    "id": "6069",
    "lat": "41.3275459",
    "lon": "19.8186982",
    "name": "Tirana",
    "seoname": "tirana",
    "type": "city"
  },
...
]

GET https://example.com/destinations/[country code]

Attribute Description
countryid ISO Alpha-2 country code
id a numeric value, the id of the specific location
name The name of the destination
type the type of the destination, whether it’s a city, a region, etc.
seoname a url-safe slug of the destination name
lat Latitude of the destination
lon Longitude of the destination

Hotels by IDs

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/hotels/1,2,3

Response

[
  {
    "id":"1111",
    "name":"Example Hotel",
    "address":"123 main street",
    "status":"1",
    "zip":"12345",
    "phone":"+66 666 666666",
    "fax":"+66 666 666667",
    "lat":"66.6666",
    "lon":"77.777",
    "seoname":"example-hotel",
    "stars":"4",
    "destinations":[
      {
        "destinationId":"666",
        "type": "city"
      },
      {
        "destinationId":"84533",
        "type": "zone"
      }
    ],
    "mainImageId":"666",
    "images":[
      {
        "id":"666",
        "width":"375",
        "height":"250",
        "title":"External View",
        "url":"0\/0\/666.png"
      },
      ...
    ],
    "description":"The Example is a superbly decorated 4 star place setting new standards. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
  },
  ...
]

GET https://example.com/hotels/[hotels id list]

The hotel ids should be separated by a comma, and the limit is up to 500 hotel ids per request.

Attribute Description
id a numeric value, the id of the specific hotel
name The name of the hotel
seoname a url-safe slug of the destination name
lat Latitude of the destination
lon Longitude of the destination
status The status of the hotel, 0 means disabled, all other positive values means active.
address the physical address of the hotel
zip zip code
phone phone number
fax fax number
stars the number of stars
description free text description. for translations, see translations
destinations a collection of destination ids and types the hotel belongs to. see destinations
images see the images section
mainImageId the main image id of the hotel. the image details will be part of the images collection.

Hotels Diff Since

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/hotels-diff/2018-01-01

Response

[
  "1142",
  "30087",
  ...
]

GET https://example.com/hotels-diff/[timestamp]

This method returns the hotel ids of only hotels that changed since the timestamp in the request.

Currencies

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/currencies

Response

[
  {
    "currencyId": "EUR",
    "name": "Euro",
    "sign": "€",
    "active": "1"
  },
  {
    "currencyId": "USD",
    "name": "United States Dollars",
    "sign": "$",
    "active": "1"
  }
]

GET https://example.com/currencies

Attribute Description
currencyId 3 letter ISO 4217 currency code
name The name of the currency
sign Sign, if any
active boolean, 1 is active, 0 is disabled

Markets

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/markets

Response

[
  {
      "marketId":"26",
      "title":"Western Europe",
      "countries":[
        "AT",
        "BE",
        "CH",
        "DE",
        "FR",
        "LI",
        "LU",
        "MC",
        "NL"
      ]
    },
    ...
]

GET https://example.com/markets

Attribute Description
marketId numeric id
title The name of the market
countries ISO Alpha-2 country code collection of countries participating in this market

Airlines

Request

curl \
  -H "aether-application-key: [app-key]" \
  https://example.com/airlines

Response

[
  {
          "iata": "BD",
          "name": "bmi",
          "alt_name": "bmi British Midland",
          "icao": "BMA",
          "country": "United Kingdom"
      },
    ...
]

GET https://example.com/airlines

Attribute Description
iata iata code (2 letter code)
name The name of the airline
alt_name alternative name, more descriptive
icao icao code of the airline (3 letter code)
country Country of origin

Facilities

24h reception
accessibility
air condition
babysitting
bar
beach
beauty salon
concierge
conference room
gym
hair dryer
internet
kids pool
laundry services
minibar
nightclub
no smoking
outdoor pool
parking lot
pets friendly
radio
refrigerator
restaurant
room service
safe
sauna
solarium
spa
tv
tv channels (satellite)
bikes
bath
free newspaper
coffee/tea
currency exchange
water sports
bidet
free internet
iron
surcharge airport shuttle
surcharge baby friendly
surcharge babysitting
heated pool
indoor pool
pool
baby friendly
ball sport
diving
free street parking
game room
gift shop
golf course
kitchen
library
newspaper
ping pong
pool bar
squash
tennis court
winter sport
airport shuttle
free bikes
kids club
water park
free airport shuttle
hot tub
surcharge bikes
onsite parking lot
surcharge laundry services
surcharge room service
coffee shop
free shuttle to beach
free kids club
video games
iron services
surcharge shuttle to casino
free baby friendly
mini market
pool table
casino
surcharge valet parking
tv channels (cable)
valet parking
atm
surcharge internet
surcharge street parking
surcharge newspaper
free coffee/tea
free long term parking
free truck parking
surcharge shuttle to train
tv channels (digital)
shared bathroom
free near gym
surcharge pets friendly
surcharge parking lot
surcharge shuttle to beach
truck parking
near gym
bbq
surcharge beach
shared lounge
free minibar
fireplace
surcharge kids club
surcharge shuttle to shopping
free gym
free safe
surcharge spa
board games
electric vehicle charge station
surcharge safe
bowling
surcharge truck parking
onsite atm
surcharge coffee/tea
boating
surfing
street parking
surcharge shuttle to ferry
karaoke
free onsite parking lot
free shuttle to train
beach bar
free valet parking
free babysitting
free conference room
free parking lot
surcharge beauty salon
surcharge long term parking
surcharge shuttle to theme park
surcharge shuttle to cruise
scenic view
onsite beach
free beauty salon
free solarium
onsite golf course
free shuttle to theme park
free shuttle to cruise
free shuttle to ferry
onsite spa
free shuttle to casino
adults only
surcharge shuttle to ski
surcharge minibar
free pets friendly
onsite mini market
onsite water sports
free shuttle to shopping
near nightclub
free water park
lockers
free shuttle to ski
onsite tennis court
shared kitchen
shuttle to ski
surcharge conference room
surcharge pool
surcharge gym
free spa
onsite video games
surcharge solarium
surcharge golf course
shared bath
surcharge water park
halal
free laundry services
near golf course
shuttle to beach
kosher
surcharge sauna
free currency exchange
near beach
near spa
free sauna
near tennis court
onsite winter sport
sea view
near water sports
surcharge air condition
free pool
surcharge onsite parking lot
surcharge tennis court
surcharge pool table
free accessibility
long term parking
surcharge tv channels (cable)
free beach
near restaurant
onsite conference room
surcharge iron
free game room
netflix
surcharge winter sport
surcharge hair dryer
surcharge refrigerator
onsite diving
surcharge video games
onsite restaurant
surcharge ping pong
onsite bikes
surcharge tv channels (satellite)
surcharge accessibility
surcharge iron services
onsite bbq
surcharge kitchen
surcharge bath
surcharge tv
near beauty salon
onsite coffee/tea
free air condition
near atm
near outdoor pool
near casino
surcharge radio
near surfing
free heated pool
free refrigerator
near parking lot
free no smoking
near winter sport
near diving
near bbq
surcharge near parking lot
halal food
kosher food
onsite boating
near boating

Static Data Download

There is an option to download a CSV file with the static data instead of using API.

To download static data in CSV file please use the following endpoint:
https://static-data-console.innstant-servers.com/static-files/download

Images

{
  "images":[
  {
    "id":"100511",
    "width":"500",
    "height":"500",
    "title":"Double Bed",
    "url":"0\/100\/100511.png"
  },
  ...
  ]
}
Attribute Description
id a numeric value, the id of the specific image
width width in pixels
height height in pixels
title textual title for the image. Note that it can be empty.
url the url of the image

To create the full URI, use the following structure:

https://cdn-images.innstant-servers.com/[max-width]x[max-height]/[image-url]

For example:

https://cdn-images.innstant-servers.com/500x500/0/100/100511.jpg

Errors

Search Errors

Code Description
m400 Bad Request – Your request sucks
m401 Unauthorized – Your API key is wrong
m404 Required service and/or method not found. Refer to documentation to see available endpoints
m405 Method not allowed! Refer to documentation to see allowed methods
m777 Unexpected infrastructure failure! Please contact us at api@innstant.com
m1001 Invalid Request! Make sure it’s a valid JSON and has allowed values as described in documentation
m1003 Entity id and/or type is wrong! Please contact us at api@innstant.com
m1004 Unexpected internal error occurred. Please contact us at api@innstant.com
m1010 Unexpected internal error occurred. Please contact us at api@innstant.com
m1011 Unexpected internal error occurred. Please contact us at api@innstant.com
m1012 Unexpected internal error occurred. Please contact us at api@innstant.com
m1013 Unexpected internal error occurred. Please contact us at api@innstant.com
m1014 Unexpected internal error occurred. Please contact us at api@innstant.com
m1015 Unexpected internal error occurred. Please contact us at api@innstant.com
m1016 Unexpected internal error occurred. Please contact us at api@innstant.com
m1020 Unexpected internal error occurred. Please contact us at api@innstant.com
m1021 Unexpected internal error occurred. Please contact us at api@innstant.com
m1100 Wrong account setup. Please contact your account manager for more details
m1101 Wrong account setup. Please contact your account manager for more details
m1200 No data found for requested plugin. Please check your spelling
m1201 Account does not exist. Please contact your account manager
m1202 Supplier does not exist. Please contact your account manager
m1203 Agent does not exist. Please contact your account manager
m1210 Unexpected internal error occurred. Please contact us at api@innstant.com
m2000 Unexpected supplier response. Please contact us at api@innstant.com
m2001 Unexpected supplier response. Please contact us at api@innstant.com
m2100 Unexpected supplier response. Please contact us at api@innstant.com
m2101 Unexpected supplier response. Please contact us at api@innstant.com
m2102 Unexpected supplier response. Please contact us at api@innstant.com

Login errors

Code Description
a0 Uncategorized error
a100 Missing login details
a101 Invalid login information
a102 Invalid password
a103 Invalid account status
a104 Invalid agent status
a105 Account disabled
a106 Agent disabled
a107 Invalid login details
a108 Invalid API key
a109 Missing API key
a110 API key disabled
a111 Bad agent configuration
a112 Missing access token

System errors

Code Description
a201 Missing account ID
a202 Missing agent ID
a203 Invalid parameter
a204 Invalid account setup
a205 General error
a206 Missing whitelabel ID
a208 Access storage error

Permission error

Code Description
a300 Permission error

Booking errors

Code Description
a400 Missing booking item
a401 Booking not found
a402 Payment method not supported
a403 Account balance error
a404 Provider failure
a405 Booking expired
a406 Invalid 3D secure token
a407 Invalid markup
a408 Cancellation failed
a409 Broad on request
a410 Missing customer email
a414 Room is unavailable

Processing errors

Code Description
a500 Missing processing credentials
a501 No processing account set

Accounting errors

Code Description
a600 Duplicate document
a601 Document save error

Payment errors

Code Description
a700 Payment authorize is not supported for this interface
a701 Missing amount
a702 Booking already exists (recoverable)

Warnings

Code Description
a2100 Price change (recoverable)
a2101 Board change (recoverable)
a2102 Cancellation policy change (recoverable)
a2103 Result code change (recoverable)