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
- What is Concur?
- What information can I get from the Concur APIs?
- I'm sold.. How do I get started?
- Other API calls/samples to check out
- Sample code
- Help! I'm stuck!
- TC Disrupt Hackathon Sponsor API Links and Prizes #hackdisrupt
- Mashup with our fellow sponsors' APIs
- Contest Terms and Conditions
Who starts their contest page with prizes? We do! Here's what you can win:
Maximum $2,500 worth of Amazon gift cards: Best Use of Concur API - App that demonstrates the best use of Concur APIs. Prize distribution is $500 to each winning team member.
$100 Amazon gift card: Use of Concur APIs - first 10 teams that registers/uses/demos the use of Concur APIs, outside of the above category, gets a $100 Amazon gift card (per team).
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.
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:
Trover - it's travel photography + business travel integration in one great app. Because we understand that the business traveler is a person too. Quoting from this article, what they get for integrating with Concur is "being able to tap into Concur’s experience, knowledge and “great visibility into travel patterns”".
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?
Expense data history of a Concur user - users of Concur expense their purchases using the Concur Travel and Expense web/mobile app, so that they can get reimbursed by their company at the end of the trip. This gives Concur insight into a user's expense pattern (e.g. does Joe always get a Starbucks coffee right after landing in SFO?). This API returns a collection of expense reports that you can use to make the same deduction. It's also worth noting that there are also APIs to submit expense entries (e.g. Starbucks coffee, printer ink, etc) and reports (collection of expense entries), as well as submit images of receipts (similar to TravelText above).
Itinerary Details of a Concur user - there's a ton of information you can get from a Concur user's trip, such as the booking segments the trip, whether it's Air, Car, Hotel, Dining, Ride, Rail, or Parking. The most common information you'll probably use is a user's travel destination. From that single piece of info, you can make recommendations to the travele (just like Trover).
These are just two of many APIs you can use to get information from Concur.
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:
To get an access token, send an email to email@example.com (our Developer Evangelist)
You can also give our Swagger API documentation a spin. We'll cover Swagger in a bit more detail below.
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 firstname.lastname@example.org 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 email@example.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)
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.
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-ConsumerKeyfrom number 1. To generate the
Authorization: Basicvalue, you need to Base64-encode the login ID, colon and password such that firstname.lastname@example.org: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 email@example.com if you want to get it.
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).
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
IDwe 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:
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>
- Windows 8 C#/XAML
- PHP/curl (in Runnable.com)
- Python (Generate access token)
If you're getting an error when submitting an expense report, it's likely because you have not set up an Account Code for an expense item type (i.e. Account Code
Breakfasttype). To fix this, go to Setup -> Expense -> 4)Expense -> Expense Types -> 2) Account Code (as in the screenshot below), and fill out account codes for expense types you're using. Remember to hit the Save button (right beside the drop-down with the value DEFAULT).
Still stuck? Send Chris an email at firstname.lastname@example.org or tweet @chrispogeek and he'll come to your rescue
|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|
|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|
Hit more birds with 1 stone with these Concur integration ideas.
|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|
You're set. Go win this!