TripIt CRS API Documentation - v1

Index

Overview

The CRS API allows select TripIt partners (from now on referred to as "partner") to programatically load, replace, and delete groups of travel objects and trip remarks in the TripIt platform on behalf of their customers. The kinds of partners interested in this functionality may include travel management companies, global distribution systems, travel suppliers, etc... Travel objects and trip remarks are grouped together by a Record Locator value. Following is a list of object types supported by the CRS API:

CRS Trip Details:

Travel Object Types:

Trip Remark Object Type:

The TripIt CRS API is built on top of the public TripIt API. Since both API's share many of the same fundamentals, it will be helpful for anyone using the CRS API to first familiarize themselves with the public TripIt API documentation available here.

Authentication

2-legged OAuth

The public TripIt API offers two methods of authentication for API calls: Web Authentication and 3-legged OAuth. Neither is particularly useful for a partner interested in loading travel data from their system into the TripIt platform without having to store per-user credentials and per-user information in their own system.

To satisfy the needs of a partner, TripIt's CRS API makes available a modified 2-legged OAuth scheme in which each partner (the "oauth consumer") is supplied with a special key that enables them to authenticate with TripIt's CRS API on behalf of TripIt users (the "oauth user") that have authorized them to do so. By default every TripIt user is configured so that the partner does not have this ability; however, TripIt provides a simple page flow to facilitate users' granting the partner access to load, replace, and delete travel data contained in their TripIt user account.

To implement the 2-legged OAuth scheme, the oauth consumer needs to implement the following:

  1. An oauth consumer needs to have a TripIt account with which the consumer is associated. For a large company this should probably be a general account that is not also used for personal use to avoid issues with account deletion or merge.
  2. Once that account is created, the owner needs to register a 3-legged oauth consumer (see the TripIt application registration page) which will be the consumer used to load, replace, and delete their customers' travel data.
  3. Send an email to api-support@tripit.com requesting 2-legged OAuth for your application. Upon request, TripIt engineering will promote this 3-legged oauth consumer to be a 2-legged consumer and replace the consumer key with well-known public key.
  4. The consumer is now ready to make calls to the TripIt CRS API. In order to make a call on behalf of a TripIt user (assuming the user has authorized the consumer to do so) the consumer will need to form a standard public TripIt API OAuth call with the following modifications:

A successful call via the 2-legged OAuth scheme can only be made on behalf of a TripIt account if that user has authorized the consumer application to do so. Here's what needs to happen in order for the TripIt user to authorize the consumer:

  1. Either at account creation time or later the consumer needs to direct the TripIt user to a secure (ie: SSL) web page, https://www.tripit.com/oauth/authorize, which prompts the user to grant access for the consumer.
  2. The act of granting access to a specific consumer should cause that consumer to appear on the TripIt user's list of authorized applications here: http://www.tripit.com/account/edit/section/applications. The user is also able to de-authorize access at any time.

For information on Web Authentication and standard 3-legged OAuth, please refer to the public TripIt API documentation.

Encoding

Please refer to the public TripIt API documentation.

Resource URLs

Please refer to the public TripIt API documentation for general information, portions of which pertain to partners' use of the CRS API. The following documentation describes CRS-specific resource URLs available only in the TripIt CRS API.

There are currently two requests supported by the CRS API: crsLoadReservations and crsDeleteReservations. Each is explained below in greater detail.

crsLoadReservations

A crsLoadReservations request is used to load or replace a set of travel objects and trip crs remarks. To invoke, send an HTTP POST request to the following URL:

https://api.tripit.com/v1/crsLoadReservations

The XML document containing travel objects and trip remarks must validate against the TripIt CRS API request XSD and must be POSTed as the value of the request parameter xml in the POST body of the request.

An optional company_key parameter may be sent in the request as well. The length of this request parameter's value is limited to 50 characters. See below for a description of how this parameter value is stored and what it's used for.

Note the record_locator XML element in both the ReservationObject (see tripit-api-obj-v1.xsd) as well as in TripCrsRemark (see tripit-api-crs-req-v1.xsd). This field is special for the following reasons:

While the record_locator field is never rendered to TripIt end users, customarily the value in that field is also stored in another field called supplier_conf_num which is rendered and editable by TripIt users much like all other travel objects' fields.

The first and most important difference to understand between the public TripIt API's create method and the CRS API's crsLoadReservations method is that the restriction of being able to present only one travel object per call in the former does not exist in the latter. According to the CRS API XSD, you are allowed to specify multiple travel objects as well as multiple trip remarks in each crsLoadReservations request.

Following is the high level logic executed during crsLoadReservations:

1. group incoming travel objects and trip remarks by their record_locator value
   a. note that this approach makes TripIt compatible with partners who support the
      notion of a "SuperPNR"
   b. any travel objects or trip remarks without a record_locator value will cause
      the entire crsLoadReservations request to fail with an HTTP 400 error
2. for each record_locator value present in the new objects contained in the request
   a. retrieve all travel objects and trip remarks with that record_locator value
      which may already exist in the TripIt platform
   b. determine what TripIt trip(s) the travel objects belong to
      * if no travel objects or trip remarks already exist,
         - create a new TripIt trip for the incoming travel objects and trip remarks
         - note that this trip will be associated with the partner causing it's creation
           for the purposes of displaying that partner's logo along with that trip
         - note also that the trip will be tagged with the value of the optional
           'company_key' request parameter (see below) for the purpose of identifying
           the partner's client to bee associated with this trip
      * if some travel objects and/or trip remarks were found, determine which TripIt
        trip(s) they already belong to
         - if they all belong to exactly one trip: all incoming travel objects and trip
           remarks will be placed in that trip
         - if they belong to multiple trips: choose the trip containing the highest
           number of travel objects associated with the specified record_locator
   c. delete all travel objects and/or trip remarks found in 2a
   d. store all incoming travel objects and trip remarks, placing them in the TripIt
      trip selected in 2b
3. perform all of the following TripIt special sauce logic:
   a. for any trips that were changed during the course of the request, assert correctness
      of auto weather, dates, maps, directions, timezones, etc...
   b. for any air objects that were created during the request, enrich segment data from
      faa flight info, etc...
   c. if TripIt Pro is enabled,
      * activate realtime flight monitoring for all air reservations
      * auto-invite inner circle members to the trip(s)
      * etc...
4. generate and return a response to the client with the newly-stored objects' data

Note that if a brand new TripIt trip is created in step 2b above, the newly-created trip is tagged with the following pieces of information:

  1. If specified in the request, we tag the trip with the company_key, is_private, display_name value passed as a request parameter to crsLoadReservations or passed in the input xml as '<CrsTripDetails>'. The values passed in the xml will have higher precedence than the values passed as a request parameter. This company key is used to identify the partner's client or other entity to be associated with this newly-created itinerary.
  2. We also store the specific oauth consumer (partner) that caused the trip to be created.

Example:

Here is a sample crsLoadReservations request:

Here is what the post data would look like:

company_key=SomeCompanyName&trip_is_private=booleanvalue&trip_display_name=SomeDisplayName&\
xml=<CrsRequest> <!-- this field is optional -->
      <CrsTripDetails>
        <TripPurposes>
         <purpose_type_code> B </purpose_type_code>
         <is_auto_generated> B </is_auto_generated>
        </TripPurposes>
        <display_name> </display_name>
        <company_key> </company_key>
        <is_private> </is_private>
      </CrsTripDetails>
  <AirObject>
    <record_locator>ABC123</record_locator> <!-- this field is used to group objects and remarks -->
    <supplier_conf_num>ABC123</supplier_conf_num> <!-- this field is rendered and editable to the TripIt user -->
    . . . see tripit-api-obj-v1.xsd for a complete list of <AirObject> fields available for you to populate . . .
    <notes>
      (you can store notes on a per-AirObject basis)
    </notes>
    <restrictions>
      (restrictions are typically used to store PNR fare rules, etc...)
    </restrictions>
    <AirSegment>
    . . . see tripit-api-obj-v1.xsd for a complete list of <AirSegment> fields available for you to populate . . .
    </AirSegment>
    <AirSegment>
      ...
      <notes>
        (you can also store notes on a per-AirSegment basis)
      </notes>
    </AirSegment>
    <Traveler>
    . . . see tripit-api-obj-v1.xsd for a complete list of <Traveler> fields available for you to populate . . .
    </Traveler>
  </AirObject>
  <LodgingObject>
    <record_locator>ABC123</record_locator>
    <supplier_conf_num>ABC123</supplier_conf_num>
    . . . see tripit-api-obj-v1.xsd for a complete list of <LodgingObject> fields available for you to populate . . .
    <notes>
      ...
    </notes>
    <restrictions>
      ...
    </restrictions>
  </LodgingObject>
  <CarObject>
    <record_locator>XYZ456</record_locator>
    <supplier_conf_num>XYZ456</supplier_conf_num>
    . . . see tripit-api-obj-v1.xsd for a complete list of <CarObject> fields available for you to populate . . .
    <notes>
      ...
    </notes>
    <restrictions>
      ...
    </restrictions>
  </CarObject>
  <TripCrsRemark>
    <record_locator>ABC123</record_locator>
    <notes>Thanks for booking with us.
In case of emergency, blah blah blah...
Note that remarks can have multiple lines of text.
Think of TripCrsRemark's as providing you the ability to store notes on a per-trip basis.</notes>
  </TripCrsRemark>
  <TripCrsRemark>
    <record_locator>XYZ456</record_locator>
    <notes>Thanks for booking with us.</notes>
  </TripCrsRemark>
  <TripCrsRemark>
    <record_locator>XYZ456</record_locator>
    <notes>In case your car breaks down, blah blah blah...</notes>
  </TripCrsRemark>
</CrsRequest>
      
This example loads a SuperPNR consisting of two PNR's: ABC123, and XYZ456. The first PNR contains an air reservation, a hotel reservation and one remark. The second PNR contains a car reservation and two remarks.

crsDeleteReservations

A crsDeleteReservations request is used to delete all travel objects and trip remarks associated with the specified record locator.

https://api.tripit.com/v1/crsDeleteReservations?record_locator=<PNR>

<PNR> is the Person Name Record, or record locator to be deleted.

Example:

Here is a sample crsDeleteReservations request for PNR "ABC123":

https://api.tripit.com/v1/crsDeleteReservations?record_locator=ABC123
In this example, crsDeleteReservations would delete only one of the two PNR's loaded in the crsLoadReservations example above; specifically, it would delete the AirObject, the LodgingObject, and one of the three TripCrsRemark's.

HTTP Status Codes

Please refer to the public TripIt API documentation as well as the following CRS-specific documentation below.

In addition to the errors and reasons described by the public TripIt API documentation, the CRS API will also return these HTTP Status Codes for the following reasons:

status code meaning description
400 Bad Request xoauth_requestor_id request parameter value is missing or contains an invalid email address.
404 Not Found Email address specified in xoauth_requestor_id does not exist in the TripIt platform.

Request/Response Objects

Please refer to the public TripIt API documentation as well as the following CRS-specific documentation below.

There are two types of XML documents used to communicate with the CRS API. A CrsRequest document is used when the client is asking to load or replace reservations in the TripIt platform. A Response document is what the CRS API returns to the client as an answer to a CrsRequest. The XML Schemas that describe valid CrsRequest and Response documents may be found here:

These schemas completely describe all of the valid XML documents that can be posted to and received from the API.

CrsRequest Object

Used for load or replace operations, a CrsRequest object wraps one or more travel objects (AirObject, LodgingObject, CarObject, etc...) as well as one or more trip remarks (TripCrsRemark) in the xml parameter value of an HTTP POST request.

Response Object

A Response object is used to wrap one or more travel objects as well as one or more Warning and/or Error objects in a response from a crsLoadReservations request.

Viewing the Itinerary

NOTE: only 2-legged oauth consumers will be able to use the mechanisms described in this section.

Once a set of travel objects and trip remarks are successfully loaded into the TripIt platform by a partner, they will be available for on-line viewing according to all the trip privacy and access rules defined by the TripIt platform. For convenience, people invited to the trip will be able to view it at the following terse URL:

Note that "ABC123" is the record locator value and this URL can easily be constructed by the partner and included either in the invoice sent to the customer at the time of booking and/or on the purchase confirmation page. For people who either don't already have a TripIt account and/or have not yet granted access to the partner's consumer, the URL would need to contain a few more parameters in order to facilitate new user account creation and setup:

Here's an example:

This URL will guide the user through the steps necessary to create and establish the communication channel the partner will need in order to load, replace, and delete travel objects and trip remarks in their TripIt account moving forward. Once that communication channel is established it will remain open until/unless the user revokes access to that partner oauth application. The request parameters in the url above are:

In addition to facilitating the ability for partners to link directly to a user's itinerary, this /pnr url serves a few more useful purposes. Consider the following two use cases in which the partner's initial invocation of crsLoadReservations fails:

  1. user had not already registered with TripIt using the email address associated with the PNR
  2. user had an account with that email address but hadn't already granted access to the partner's consumer

Even if the initial crsLoadReservations fails, partners can still direct users to the /pnr url described above as TripIt can still successfully get the user to their itinerary. To do so, partners will need to implement a crsLoadReservations callback listener. Here's an example of how this flow works:

  1. user books travel with partner
  2. partner attempts a crsLoadReservations which fails either with a 404 (email address not found in TripIt) or 401 (not authorized)
  3. partner still conveys the TripIt /pnr url to the user either on their purchase confirmation page and/or in their invoice email
  4. user clicks on the TripIt /pnr url
  5. TripIt facilitates creation of a new account and/or granting access to the partner's consumer
  6. once account exists in TripIt and has granted access to the consumer, TripIt calls the partner's crsLoadReservations callback listener
  7. partner receives https request, verifies oauth signature and once again invokes crsLoadReservation for the specified PNR
  8. this time, the crsLoadReservations call will succeed
  9. TripIt redirects user's browser to the TripIt itinerary page and they can view their trip!

Some notes:

In order for TripIt to initiate a request to the partner so that the partner once again tries to load the user's PNR into the TripIt platform, the partner will need to:

  1. set up an https server with valid CA-signed certs
  2. validate oauth signatures using the HMAC-SHA1 signature method
  3. be able to invoke their crsLoadReservations logic from this crsLoadReservations callback listener

The protocol used for this callback will be an oauth-signed https (SSL) GET request. Partners will be able to configure the hostname and path to which TripIt calls back, and the url will look like this:

The record locator is included in this GET url under the request parameter key 'pnr'. In order to support multi-passenger PNR's, TripIt will also make an effort to send the email address specified in the "/pnr" URL (described above) as well. If the user clicks on a "/pnr" URL that either doesn't contain the 'email_address' request parameter or the value associated with that parameter is not a valid email address, then no email_address parameter will be sent in the listener callback GET request.

TripIt will expect two things in the response from this listener callback https request:

  1. A valid http response code. "2xx" will be interpretted as success and anything else will be considered failure.
  2. The email address associated with the PNR that the partner attempted to load. This email address will be passed back in the response content as a URL-encoded, GET-style query string with the value present under the GET parameter 'email_address'. While passing of this email address back to TripIt is optional, it behooves the partner to send it back in the https response in order to facilitate TripIt's ability to get the user to their itinerary. For example: in the event that the crsLoadReservation call fails when TripIt is asking the partner to try loading again, TripIt can use this email address to help the user determine that (1) the address simply needs to be added to their already-existing account, (2) that they already have an account with that email address but it needs to be merged into their main account, or (3) that they already have that email address in their account but ownership of the address needs to be confirmed.

Here's a rough illustration of the data involved in this crsLoadReservations callback listener exchange:

# --------
# 1) TripIt initiates an oauth-signed HTTPS Request to the partner's SSL server.
#       NOTES:
#          - partner configures the "https://tmc.hostname.com/path/to/whatever"
#          - TripIt includes a 'pnr' GET parameter and signs request: "?...&pnr=ABC123&oauth_signature=xxxxxxxxxxxxxxxx&..."
# --------
https://partner.hostname.com/path/to/whatever?...&pnr=ABC123&email_address=user%40@some-company.com&oauth_signature=xxxxxxxxxxxxxxxx&...
# --------
# 2) TripIt's https request client waits while the partner immediately calls crsLoadReservations
# 3) partner calls crsLoadReserations for the specified PNR
# 4) partner determines whether or not that crsLoadReservations call succeeded
# 5) partner renders an https response indicating to TripIt if the load call succeeded and the email address associated with the PNR
# --------
200 OK
...
Content-Length: 39


email_address%3Duser%40@some-company.com
# --------

If all goes well TripIt will redirect the user's browser directly to view their trip. If a failure occurs, TripIt will use the email address sent back in the response to remedy the specific authentication problem that is still preventing crsLoadReservations from succeeding and then attempt the on-boarding process once again.

TripIt Pro Data

Please refer to the public TripIt API documentation.

Deprecation Policy

Please refer to the public TripIt API documentation.

Release Notes

Please refer to the public TripIt API documentation.

Examples

Please refer to the public TripIt API documentation.