View on GitHub

Concur @ #APIConSF

Download this project as a .zip file Download this project as a tar.gz file

  Concur @ #APIConSF  


This page contains information and links to all the resources you need for the Concur Contest in #APIConSF Hackathon:

Best use of Concur API:

What is Concur?

Concur started out as a company that helped business travelers manage their receipts and reimbursements. If you've ever filled out an Excel sheet to itemize all your expense items, or carried a separate envelope to make sure you don't lose all your receipts for reimbursement, then you understand the pain that Concur solves for business travelers. Using software, Concur set out to remove these unnecessary troubles.

Fast forward to today, through Concur you can take a picture of your receipts (and rid yourself of the paper receipt mayhem), itemize expense (using OCR and E-Receipts), submit your expense reports, and even book a company policy-compliant travel ("Will my boss approve this?"). This saves companies time and money, and ensures that their business travelers are productive.

Over 25 million people in 190 countries and over 65 percent of the Fortune 500 trust Concur to process $50 billion in travel and expense data per year. We help these 25M business travelers manage their travel bookings and expense reports through the Concur Travel and Expense web/mobile app.

With this global reach, we have opened up the Concur Platform so that partners can provide value to Concur users by having access to their itinerary and expense information.

That's where you come in.

What information can I get from the Concur APIs?

Example apps

Let's first look at 2 examples of apps that our partners have built using Concur APIs. They're all listed in our App Center:

Information returned by the APIs

You can find more examples of apps that use our APIs in the App Center link above. Now let's get to business - what information can you get from the Concur APIs?

These are just two of many APIs you can use to get information from Concur.

I'm sold, how do I get started?

Quickest Way (5 mins) - a GET API call

To save you time, we have created developer test accounts pre-populated with expense and itinerary information. The idea is to quickly familiarize you with the structure of expense and itinerary information that you can get from Concur. We still expect you to understand the normal flow from a Concur user's perspective, which is why we will explain that bit later. For now, all you need is an access token, and call an API, the Expense Report Digest API in this case, like this:

    curl https://www.concursolutions.com/api/v3.0/expense/reportdigests
    -H "Authorization: OAuth <insert your access token here>"

A similar call to get an Itinerary List of a Concur user would be:

    curl https://www.concursolutions.com/api/travel/trip/v1.1
    -H "Authorization: OAuth <insert your access token here>"

To get a JSON response, you can do a GET call like below:

    curl https://www.concursolutions.com/api/v3.0/expense/reportdigests
    -H "Authorization: OAuth <insert your access token here>"   
    -H "Accept: application/json"

To POST JSON content, add the following header:

    -H "Content-Type:application/json"

To get an access token, send an email to chris.ismael@concur.com (our Developer Evangelist) or approach him at the Concur booth and say "Gimme!"

You can also give our Swagger API documentation a spin. We'll cover Swagger in a bit more detail below.

Normal Way - Generate an access token and use the Concur mobile app

The section explains how to properly authenticate against the Concur APIs by generating your own access token, and using the Concur app to create an Expense Report. The last step would be to call the Entries API to pull the individual line items inside the Expense Report we created. To get started, first we need to get a developer sandbox account, and install the Concur app.

Get a Developer sandbox account

A developer sandbox account allows you to test both the app and APIs, free of charge. For the purposes of this hackathon, we have set up developer accounts (using non-existent email addresses and pre-populated with Expense and Itinerary information) so that you can start using them right away. To get one of these accounts, please email chris.ismael@concur.com with the Subject: Concur Sandbox Request.

If you prefer to set up your own free sandbox, you can do so by registering here. Note that the setup steps right after you login requires you to keep clicking 'Next' (for the most part) until you get to the end. If you get stuck, reach out to chris.ismael@concur.com or send him a tweet @chrispogeek

Install the app

After you've set up your sandbox account, start familiarizing yourself with the app, so that you can map the APIs to features inside the product. You can access the web version of Concur at http://concursolutions.com/ or get the mobile app from App Store or Google Play.

It helps to watch these 2-min videos (snapshot image below) to understand how the Concur app works, as well as get context on how your app will add value to the Concur business traveler (e.g. Our app helps Concur users predict weather conditions for their future travel).

Generate Access Token -> Create Expense Report in App -> Call API

The steps below show how we can generate an access token for the API call, use the Concur app to create an Expense report, and getting back individual items inside that expense report through an API call. Without getting into too much detail, we'll authenticate using Concur's OAuth Native Flow. The goal is to get an Access Token that we will use for all our subsequent API calls. (Note: You can also use the OAuth Web Flow that shows a Concur login page to collect the user's credentials)

  1. Get your Consumer Key

    After logging in to http://concursolutions.com, go to Administration -> Register Partner Application -> Concur Partner Application (Modify). We need the consumer key so we can call the endpoint that would return the access token.

  2. Call the endpoint to request an access token

    Here's what the HTTP call looks like to request for an access token:

      GET https://www.concursolutions.com/net2/oauth2/accesstoken.ashx HTTP 1.1
      Authorization: Basic am9obl9kZXZlbG90bWFpbC5jb206VHJhdmVsJkV4cGVuc2UkMjAxMg==
      X-ConsumerKey: eZByXv2X41cJlC21pSVvRi    
    

    Note that we already have X-ConsumerKey from number 1. To generate the Authorization: Basic value, you need to Base64-encode the login ID, colon and password such that john_developer@hotmail.com:Travel&Expense$2012 becomes am9obl9kZXZlbG90bWFpbC5jb206VHJhdmVsJkV4cGVuc2UkMjAxMg==. If you're not doing this programmatically yet, you can use this nifty web tool to generate that value (remember to choose Encode).

    If you're using a Terminal, an equivalent curl statement of the above would be:

      curl https://www.concursolutions.com/net2/oauth2/accesstoken.ashx
      -H "Authorization: Basic am9obl9kZXZlbG90bWFpbC5jb206VHJhdmVsJkV4cGVuc2UkMjAxMg=="
      -H "X-ConsumerKey: eZByXv2X41cJlC21pSVvRi"
    

    If the call is successful, you should get an XML response with a <Token> node. That's your access token. We would also recommend that you use Postman, a Chrome extension, to help you manage your API calls (not just Concur ones). Here's what it looks like in action:

    Chris has already built a couple of Concur Postman "Collections", email him at chris.ismael@concur.com if you want to get it.

  3. Create items to expense and associate them with an expense report

    We will do this bit using the Concur mobile app. This would give us data that we can pull using the APIs. Note that aside from Expense, we can do the same thing for Travel too. Here's a sequence of screenshots on how to add an expense using the app, then associating them with an expense report.

    You can keep adding new expenses (and even add a receipt image!) to have a variety of data to pull for your API calls. After adding expenses, create a report to associate it with by tapping the "Add to Report" button (in the last screenshot above).

  4. Call the APIs to pull expense report items

    Since we now have an access token, we can pull an Expense Report Digest, like so (in Terminal):

      curl https://www.concursolutions.com/api/v3.0/expense/reportdigests
      -H "Authorization: OAuth <insert your access token here>"
    

    This would return an Expense Report response, with a field called ID. We need this ID to extract the expense line items we created in the app earlier. To liven things up a bit, let's use the Swagger documentation of the "Entries" API to get the individual expense line items:

    We highlighted two things here, the (oval) field where you put in your access token, and the (rectangle) field where you put in the ID we got from the previous API call. Note that we can do this same call in curl, or in any fashion you want. Swagger just provides us a consolidated way to make the API calls.

    To execute the call, click the "Try it out!" button. You should get a response like this below:

Back to Top

Often-used API calls/samples:

How to make a POST call to create an itinerary:

Here are details of an HTTP POST call push itinerary to a Concur user's trip list:

 Request Type = POST
 Authorization = <your access token>
 URI = https://www.concursolutions.com/api/travel/trip/v1.1/
 ContentType = Application/XML
 Body = 
  <?xml version="1.0"?>
  <Itinerary xmlns="http://www.concursolutions.com/api/travel/trip/2010/06">
  <TripName>TechCrunch Disrupt Concur</TripName>
  <StartDateLocal>2014-05-30T03:47:14</StartDateLocal>
  <EndDateLocal>2014-06-06T03:47:14</EndDateLocal>
  <Bookings>
   <Booking>
    <Segments>
        <Hotel>
            <Status>HK</Status>
            <StartCityCode>SFO</StartCityCode>
            <StartDateLocal>2014-05-30T07:47:14</StartDateLocal>
            <EndDateLocal>2014-06-06T03:47:14</EndDateLocal>
            <Name>Times Square Hilton New York</Name>
            <RecordLocator>Hotel Locator</RecordLocator>
            <RoomDescription>1 KING BED ACCESSIBLE ROOM - K1RRC</RoomDescription>
            <Currency>USD</Currency>
            <CancellationPolicy>Cxl 1 day prior to Arrival</CancellationPolicy>
            <DailyRate>240.3500</DailyRate>
            <NumRooms>1</NumRooms>
            <NumPersons>1</NumPersons>
            <RateCode>LV4</RateCode>
            <Charges>
                <Rate>
                    <Currency>USD</Currency>
                    <Amount>10.00</Amount>
                    <StartDatelocal>2014-05-30T07:47:14</StartDatelocal>
                    <IsPrimary>false</IsPrimary>
                    <SemanticsCode>ROOMRATE</SemanticsCode>
                    <PerUnit>DAY</PerUnit>
                    <NumUnits>3.00</NumUnits>
                </Rate>
            </Charges>
        </Hotel>
    </Segments>
    <RecordLocator>Disrupt123</RecordLocator>
    <BookingSource>Sample Itin for Disrupt</BookingSource>
    <DateBookedLocal>2014-04-30T03:47:14</DateBookedLocal>
  </Booking>
  <Booking>
    <Segments>
        <Air>
            <Vendor>AA</Vendor>
            <FlightNumber>425</FlightNumber>
            <StartCityCode>SFO</StartCityCode>
            <StartDateLocal>2014-05-30T03:47:14</StartDateLocal>
            <EndCityCode>NYC</EndCityCode>
            <EndDateLocal>2014-05-30T07:47:14</EndDateLocal>
            <Cabin>O</Cabin>
            <ClassOfService>O</ClassOfService>
        </Air>
    </Segments>
    <RecordLocator>Air Locator</RecordLocator>
    <BookingSource>Sample Itin for Disrupt</BookingSource>
    <DateBookedLocal>2014-04-30T03:47:14</DateBookedLocal>
  </Booking>
</Bookings>
</Itinerary>

How to submit an image receipt to Concur (PHP/curl):

<?php
    // Please refer to 
    // https://www.concursolutions.com/api/docs/index.html..
    // #!/ReceiptImages/Post_loginID_post_2
    // For instructions to generate access token, please refer to 
    // https://developer.concur.com/api-documentation/oauth-20-0#nativeexample

    $url = "https://www.concursolutions.com/api/v3.0/expense/receiptimages";

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents('./tmp/image.jpg'));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: OAuth <YOUR ACCESS TOKEN HERE>',
            'Content-Type: image/jpeg'
    ));

    $response = curl_exec($ch);
    curl_close($ch);

    echo $response;

?>

Posting Report Header:

Request Type = POST
Authorization = <your access token>
URI = https://www.concursolutions.com/api/expense/expensereport/v1.1/report
ContentType = Application/XML
Body = 
<Report xmlns="http://www.concursolutions.com/api/expense/expensereport/2011/03">
    <Name>Disrupt Hackathon NYC Trip</Name>
    <Purpose>All Hackathon Expenses</Purpose>
    <Comment>Includes hotel and meals.</Comment>
    <OrgUnit1>US</OrgUnit1>
    <OrgUnit3>Bellevue</OrgUnit3>
    <Custom1>Client</Custom1>
    <Custom2>Local</Custom2>
    <UserDefinedDate>2014-05-01 15:15:07.0</UserDefinedDate>
</Report>

Getting Report Details:

Request Type = GET
Authorization = <your access token>
URI = https://www.concursolutions.com/api/expense/expensereport/v2.0/Reports/?reportcountry=US
ContentType = Application/JSON

Posting Report Entry:

Request Type = POST
Authorization = <your access token>
URI = https://www.concursolutions.com/api/expense/expensereport/v1.1/report/B6F4FD62FB424911A3B8/entry
ContentType = Application/XML
Body = 
<ReportEntries xmlns="http://www.concursolutions.com/api/expense/expensereport/2011/03">
<Expense>
    <CrnCode>USD</CrnCode>
    <ExpKey>BRKFT</ExpKey>
    <Description>Starbucks for Breakfast</Description>
    <TransactionDate>2014-05-01</TransactionDate>
    <TransactionAmount>15.54</TransactionAmount>
    <Comment>Breakfast meeting</Comment>
    <VendorDescription>Starbucks</VendorDescription>
    <IsPersonal>N</IsPersonal>
</Expense>
</ReportEntries>

Back to Top

Sample code

Back to Top

Help! I'm stuck!

Back to Top

#APIConSF Sponsor Mashup ideas

Hit multiple birds with 1 stone with these Concur integration ideas.

Mashup Idea
Concur + Evernote Auto-upload receipt images dropped in an Evernote folder
Concur + Getty Images Create a Getty photo/video collage of a traveler's itinerary (search images for "Hotel Fairmont San Francisco") to familiarize him/her with the location prior to arrival
Concur + Nexmo Auto-share your Nexmo number to colleagues based on destination country (from Concur). At the end of your business trip, automatically send your boss an email on how much money you saved the company by accepting SMS/calls through your Nexmo number.
Concur + Twitter No time for leisure travel on a business trip? Tweet random images of places you will never go to, based on your Concur travel destination. Personalize your tweets by pulling Concur expense history (e.g. "Machiatto! [Pic] You all know I heart coffee!"). This idea was inspired by "Wisconsin" in TechCrunch Disrupt NY Hackathon 2014
Concur + Pubnub Build a Swarm clone for business travelers! Biz Swarm! tagish!
Concur + Eagle Eye Networks Take selfies at various locations in a hotel (Need help here?)
Concur + Mojio Compute and submit car mileage expense
Concur + Orchestrate Add rich Orchestrate meta-data to a Concur user's travel and expense for interesting data analysis (e.g. Add restaurant POIs to a Concur user's T&E data to identify opportunities and trends - he could have saved $35 on coffee if he just walked around the block)
Concur + Wit.ai Hold up a receipt to your phone camera and say the total so that it gets sent directly to your Concur expense
Concur + SecureKey Tighten your own Concur Expense/Travel app with Securekey

Back to Top

#APIConSF Sponsor API Links and Prizes

Sponsor Prizes
Concur Technologies $500 Amazon gift card to winning team
Evernote (1) iPad per team member
Getty Images $1,000 to one team
Nexmo (1) Mini Jambox per team member
Twitter To be announced
PubNub To be announced
Eagle Eye Networks $1,000 cash to one team
Mojio To be announced
Orchestrate 1 year subscription to Orchestrate database per team member
Wit.ai To be announced
SecureKey 1st place: $1000 AMEX Gift Card, 2nd place: $600 AMEX Gift Card, 3rd place: $400 AMEX Gift Card + all winning teams receive 1 year license of briidge.net CONNECT ID Digital Service

Back to Top

Concur Contest Official Rules and Sandbox Signup Form

By participating in this hackathon, each entrant (“Entrant”) agrees to be bound by the Official Rules and represents that they satisfy all of the eligibility requirements specified therein

Back to Top

You're set. Go win this!