Travelfusion Direct Connect XML API > Guidelines >
Connection Guide
Registering to use the service
To obtain an login and password, please register here.
Connecting to the service
Xml requests are submitted to api.travelfusion.com/Xml as the body of an HTTP 1.1 POST request. You must connect using https (secure). Please see the general guidelines for information about our secondary system and correct handling of IPs, URLs and DNS.
In general, UTF-8 encoding should be used. The 'Content-Type' and 'Host' header must be submitted in the HTTP headers. GZip compression must be requested in all HTTP requests. (But please note that Travelfusion's servers may not always return gzip compressed results)
Example java and PHP code is supplied below which can be used to submit the login request to the Travelfusion service and obtain a response. You should insert your login and password into the appropriate place (highlighted in red) before executing this code. This code is supplied as guidance only and it is not necessarily functional or correct and is not recommended for use in any application. It is recommended that you consider connection problems very carefully. There are many reasons that a connection to our system may timeout or fail completely. You should detect these cases and implement retries wherever applicable/ safe to do so.
Java Code Example
import java.io.*;
import java.net.*;
import java.util.zip.*;
import javax.net.ssl.*;
public class TravelfusionXmlClient {
private final static URL TARGET_URL;
static {
try {
TARGET_URL = new URL("https://api.travelfusion.com");
} catch (Exception ex) {
throw new RuntimeException("Unable to initialise target url", ex);
}
}
public static void closeSafely(Closeable closable) {
if (closable == null) return;
try {
closable.close();
} catch (Exception ex) {
// Ignored
}
}
public static String sendCommand(String command) throws Exception {
HttpsURLConnection huc = (HttpsURLConnection) TARGET_URL.openConnection();
byte[] payload = command.getBytes("UTF-8");
huc.setRequestMethod("POST");
huc.setDoInput(true);
huc.setDoOutput(true);
huc.setUseCaches(false);
huc.setAllowUserInteraction(false);
huc.setConnectTimeout(15000);
huc.setReadTimeout(120000);
huc.setRequestProperty("Accept", "text/xml");
huc.setRequestProperty("Accept-Encoding", "gzip, deflate");
huc.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
huc.setRequestProperty("Content-Length", String.valueOf(payload.length));
OutputStream os = null;
try {
os = huc.getOutputStream();
os.write(payload);
} finally {
closeSafely(os);
}
InputStream is = null;
try {
is = new BufferedInputStream(huc.getResponseCode() >= 400 ? huc.getErrorStream() : huc.getInputStream());
String hContentEncodingValue = String.valueOf(huc.getContentEncoding()).toLowerCase();
if (hContentEncodingValue.contains("gzip")) {
is = new GZIPInputStream(is);
} else if (hContentEncodingValue.contains("deflate")) {
is = new InflaterInputStream(is, new Inflater(true));
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[4096];
while (true) {
int read = is.read(b, 0, b.length);
if (read == -1) {
break;
}
baos.write(b, 0, read);
}
return baos.toString("UTF-8");
} finally {
closeSafely(is);
}
}
public static void main(String[] args) throws Exception {
String response = sendCommand("<CommandList><Login><Username>user</Username><Password>pwd</Password></Login></CommandList>");
System.out.println("RESPONSE:" + response);
}
}
Php Code Example
/**
* Creates a Login command in XML format with the given username and password.
*
* @param string $username The username for the login.
* @param string $password The password for the login.
* @return string The Login command in XML format.
*/
function createLoginCommand(string $username, string $password): string
{
$xml = new SimpleXMLElement('<CommandList></CommandList>');
$login = $xml->addChild('Login');
$login->addChild('Username', $username);
$login->addChild('Password', $password);
return $xml->asXML();
}
/**
* Sends a POST request to the TravelFusion API and returns the response body.
*
* @param string $payload The request payload in XML format.
* @return string The response body as a string.
*/
function sendPostRequest(string $payload): string
{
$client = new Client();
$res = $client->request(
method: 'POST',
uri: 'https://api.travelfusion.com',
options: [
'headers' => [
'Accept' => 'text/xml',
'Accept-Encoding' => 'gzip, deflate',
'Content-Type' => 'text/xml; charset=utf-8'
],
'body' => $payload,
'timeout' => 120000,
]);
return $res->getBody()->getContents();
}
/**
* Retrieves the login ID from the API based on the provided username and password.
*
* @param string $username The username to log in.
* @param string $password The password associated with the username.
* @return string The login ID obtained from the API.
*/
function getLoginID(string $username, string $password): string
{
$login = createLoginCommand($username, $password);
$response = sendPostRequest($login);
$xml = simplexml_load_string($response);
if (!isset($xml->Login->LoginId)) {
throw new Exception('Unauthorised');
}
return (string)$xml->Login->LoginId;
}
$username = getenv('API_USERNAME');
$password = getenv('API_PASSWORD');
$loginID = getLoginID($username, $password);
Recommended Timeouts
The timeouts below are examples / guidelines and are subject to the actual typical response times seen at customer's end.
Each connection to our service involves 2 steps: connection and read. These two steps have separate timeouts.
It is vital that you monitor timeouts and detect/ report any cases where a significant number of timeouts are occurring ( e.g. > 0.2%)
Connection timeouts: (connect means establishing the initial socket connection)
In normal circumstances, it should be very fast to establish an initial connection. So we recommend starting with a timeout of 0.5s. However it is vital to retry at least once, with a longer timeout in case there are random/ networking/ system delays or hangs during the first connection. We would suggest 1s. If that also times out, it is suggested to retry again with a longer timeout of 2s. You should consider other possible cases where even longer timeouts may be needed - for example if there is a major temporary networking problem that could cause connections to be delayed by a few seconds. Also, if your system is running in a location where connectivity is known to be slow to the UK, there may be no point starting with a low timeout like 500ms. If you cannot implement any retries at all, then you will need to choose an appropriate 'catchall' connection timeout such as 2s. However retries are highly recommended (not more than 3 ideally)
Data read timeouts: ('Data read' means the time from the successful socket opening, to the last byte of the response being read)
StartRouting: 4s read timeout, retry once with a 15 seconds timeout
CheckRouting: 7s read timeout (and continue with the standard polling process in case of a time out)
ProcessDetails: 150s read timeout, no retry
ProcessTerms: 150s read timeout, no retry
StartBooking: 20s read timeout, do NOT retry, instead proceed to CheckBooking
CheckBooking: 10s read timeout (and continue with the standard polling process in case of a time out)
It is important that you monitor timeouts and detect/ report any cases where a significant number of timeouts are occurring ( e.g. > 0.2%)
We recommend careful logging of the number and type of timeouts in all cases and a regular check of this data to ensure that timeout rates are low. Each retry should be logged separately so that you can see how many timeouts occur on the first attempt and how many on each of the subsequent retries.