View on GitHub

Concur Disrupt

Concur's Contest Page for the TechCrunch Disrupt Hackathon New York 2014

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

    Concur Disrupt    


This page contains information and links to all the resources you need for the Concur Contest in TechCrunch Disrupt 2014 New York:

Prizes to win:

Who starts their contest page with prizes? We do! Here's what you can win:

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)

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 50 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: Disrupt Sandbox.

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

Other API calls/samples to check out:

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

TC Disrupt Hackathon Sponsor API Links and Prizes

Sponsor Prizes
Concur Technologies $2500 worth of Amazon gift cards ($500 each team member) for best use of Concur APIs + $100 per team (10) that use Concur APIs (excluding $500 gift card winners)
Yodlee Interactive $2500 in value of VISA gift cards as well as Dr Dre Beats Pill speakers (1 speaker for each member of the winning team up to 4).
Mailjet 1st place: 1 year silver membership, $1500, $350 Fancy gift card, 20 GB karma hotspot; 2nd place: 6 months silver membership, $1000, $150 Fancy gift card, 5 GB Karma hotspot; 3rd place: 6 months bronze membership, $250, 2 GB Karma hotspot
Yammer Xbox One, Nokia Lumia Icon
Microsoft Best in Azure Award: This Award is for the best use of Cloud Services with Microsoft Windows Azure. Points will be awarded based on overall User Experience, and usage of Azure Web Sites (1 point), Virtual Machines (2 points), Azure Storage (Blobs, Tables, Queues) (3 points), Azure Mobile Services (4 points) and/or Additional Azure usage (ie, SQL Databases, Service Bus, Active Directory, etc) (5 points). Whether you are creating an iOS, Android or Windows app, the more Azure you use, the more points you earn. The Winning team will be awarded a $400 Gift Card for each team member, up to 5 team members total. (total prize value $2,000)
Weather Underground We’re giving away a $1,000 gift card to the best use of the Weather Underground weather API
Pearson Amazon Gift Cards
Esri
Evernote Grand Evernote Prize Awarded to the best overall app that connects with the Evernote API. All members (4 max) win: Apple iPad Minis and 1 year of Evernote Premium (each)
Crunchbase Best Use of CrunchBase API – $500

Back to Top

Mash-up with our fellow sponsors' APIs

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

Mashup Idea
Concur + Yodlee Take a list of transactions pulled from the Yodlee API and select/insert them into Concur for expenses. Build an app that takes Concur travel expenses and checks against the user's bank and credit card activity so that the user can have status that they've been reimbursed.
Concur + Mailjet Type expenses line by line in email and send them to Concur through Mailjet SMTP
Concur + Yammer Find out if your travel overlaps with a co-worker in Yammer) and meet up! Or save on travel expense by sharing a taxi ride (if you're arriving on the same airport at the same time)
Concur + Microsoft Azure Use Azure Mobile Services as scaffolding for your Concur app
Concur + Weather (Wunderground) Determine weather on a Concur users travel date and destination
Concur + Pearson Use Pearson's Eyewitness Guide API to augment a Concur user's destination with interesting travel information
Concur + Esri Use Esri's different mapping layers/functionalities to add visual context to a Concur user's destination
Concur + Evernote Auto-upload receipt images dropped in an Evernote folder
Concur + Crunchbase Check startups to visit in area of a Concur user's travel destination

Back to Top

Contest Terms and Conditions

You're set. Go win this!