Concur @ #APIConSF
This page contains information and links to all the resources you need for the Concur Contest in #APIConSF Hackathon:
- Prize for Best use of Concur API
- What is Concur?
- What information can I get from the Concur APIs?
- I'm sold.. How do I get started?
- Often-used APIs e.g. POST itinerary information
- Sample code/libraries
- Help! I'm stuck!
- #APIConSF Sponsor Mashup ideas
- #APIConSF Sponsor API Links and Prizes
- Concur Contest Official Rules and Sandbox Signup Form
Best use of Concur API:
- $500 Amazon gift card: Best Use of Concur APIs - the winning team gets a $500 Amazon gift card.
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:
TravelText - TravelText allows you to text your expenses right into Concur. No more paper receipts and Excel sheet mayhem! Don't believe us? Check out their video demo here.
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 traveler. (just like Trover).
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)
-
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-ConsumerKey
from number 1. To generate theAuthorization: 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.
-
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
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:
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>
Sample code
- Windows 8 C#/XAML
- Objective-C/iOS
- C#
- C# (Get OAuth token via native flow)
- PHP/curl (in Runnable.com)
- Python (Generate access token)
- node.js
Help! I'm stuck!
-
How do I GET/POST JSON?
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"
-
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
111
for theBreakfast
type). 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 chris.ismael@concur.com or tweet @chrispogeek and he'll come to your rescue
#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 |
#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 |
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 |
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
You're set. Go win this!