This guide prescribes how to associate external attendees to expense entries in Concur Expense. It assumes you are familiar with Concur Expense and the system of record for the external attendees. It also assumes that you have registered your application, and that you know how to make API calls to the SAP Concur Platform.
Base URL: https://www.concursolutions.com/api/v3.0
For certain types of expenses such as entertainment, business meals, and events, the person filing the expense report must identify all the people who participated in the event. In Concur Expense, the participants are called attendees. Often, attendees are tracked and managed in a business system outside of SAP Concur such as a customer-relationship management (CRM) application. Concur Expense refers to these attendees as external attendees.
To successfully associate attendees to an expense entry, the attendees and the expense entry must already exist in SAP Concur. Associating external attendees to an expense entry consists of these steps:
This section provides details of the SAP Concur API calls you need to make to associate external attendees to expense entries.
The following is the sequence of API calls a fictitious partner application makes to the SAP Concur Platform. This app has a collection of external attendees it wants to associate to a specified expense entry. Each external attendee has a unique identifier assigned by the system of record for the attendees called the External ID.
The app has a collection of external attendees it wants to associate to a specified expense entry. Each external attendee has a unique identifier assigned by the system of record for the attendees called the External ID.
The sequence of events is as follows:
The following sections provide the details for each API call.
The method for identifying an expense entry depends on whether the expense entry needs to be created or it already exists. Regardless of whether you create a new expense entry or you search for an existing one, you can use the GET Reports API followed by the GET Report Details API to obtain the unique identifier for the expense entry.
When creating a new expense entry, the SAP Concur Platform returns to the developer the unique identifier for the expense entry. In some cases a developer needs to create an expense entry. For example, in a CRM application there is an object called Sales Call that allows sales professionals to record expenses and contacts involved in a sales call they make for a prospective opportunity. In this case the developer creates an expense entry in Concur Expense to record the expense in the sales call. For details on how to create a new expense entry in Concur Expense, see these APIs:
There are cases when the expense entry already exists. For example, in a CRM application there is an object called an Event that includes contacts, but not expenses. In this case, the expenses related to events come into Concur Expense as imported credit card charges. In this situation, you can use the search capabilities in the Expense Report web service to find the relevant expense entry associated to the event. When searching for an existing expense entry the SAP Concur Platform returns to the developer the unique identifier for the expense entry.
To determine if SAP Concur has a record of external attendees, make a GET HTTPS request to the Attendees resource using the External ID search term for external attendees stored in SAP Concur:
GET https://www.concursolutions.com/api/v3.0/expense/attendees?externalid={unique_identifier_for_external_attendee} HTTP/1.1
Authorization: OAuth {valid OAuth Access Token goes here}
Content-Type: {application/json or application/xml goes here}
Where:
externalID is the unique identifier record for the external attendee assigned by the system of record. If the attendee with this external ID exists, the response includes the details about the attendee including its ID.
Here’s an example for how to look for the SAP Concur record for an external attendee with an ID of 5575592349 in a business system outside of SAP Concur.
Make a GET HTTP request to the attendees endpoint:
GET https://www.concursolutions.com/api/v3.0/expense/attendees?externalid=5575592349 HTTP/1.1
Authorization: OAuth pBA8nW1qGJcd4AZp9sGxti374Cc=
Content-Type: application/json
If SAP Concur has a record of the external attendee, its unique identifier in SAP Concur is returned in the ID element and you can skip to Step 4. If SAP Concur does not have a record, the Items element will be empty and you need to add the external attendee in SAP Concur as prescribed in Step 3.
A successful response when SAP Concur has a record of the external attendee looks like this:
{
"Items": [
{
"AttendeeTypeCode": "HCP",
"AttendeeTypeID": "niJ6GaAD60bAetp3vtK6$sGRgCi1s",
"FirstName": "Emilie",
"LastName": "Cass",
"MiddleInitial": null,
"Suffix": null,
"Company": "Life Care Center of Action",
"Title": "Gynecology and Obstetrics",
"ExternalID": "5575592349",
"HasExceptionsPrevYear": false,
"HasExceptionsYTD": false,
"TotalAmountPrevYear": 0.00000000,
"TotalAmountYTD": 0.00000000,
"VersionNumber": 1,
"OwnerName": "System, Concur",
"OwnerLoginID": "ConcurSystem",
"CurrencyCode": "USD",
"Cust om1": null,
"Custom2": null,
"Custom3": null,
"Custom4": null,
"Custom5": null,
"Custom6": null,
"Custom7": null,
"Custom8": null,
"Custom9": null,
"Custom10": null,
"Custom11": null,
"Custom12": null,
"Custom13": null,
"Custom14": null,
"Custom15": null,
"Custom16": null,
"Custom17": null,
"Custom18": null,
"Custom19": null,
"Custom20": null,
"Custom21": null,
"Custom22": null,
"Custom23": null,
"Custom24": null,
"Custom25": null,
"ID": "nmBwIaoDagUkD8kXZGIl7B170uK9tE6pk",
"URI": "https://rqa3-cb.concurtech.net/api/v3.0/expense/attendees/nmBwIaoDagUkD8kXZGIl7B170uK9tE6pk"
}
],
"NextPage": null
}
If the attendee doesn’t exist in SAP Concur, make a POST request to the Attendees resource to create a new attendee in SAP Concur:
POST https://www.concursolutions.com/api/v3.0/expense/attendees HTTP/1.1
Authorization: OAuth {valid OAuth Access Token goes here}
Content-Type: {application/json or application/xml goes here}
The request content body includes the details about the attendee. For example:
{
"AttendeeTypeID": "ID for the attendee type",
"FirstName": "Taylor",
"LastName": "Hernandez",
"MiddleInitial": "E",
"Company": "Life Care Center of Action",
"Title": "Anaesthetics",
"ExternalID": "6164704601"
}
To determine the value you need to enter for the AttendeeTypeID element in the content body of the POST request, make a GET request to the AttendeeTypes resource. For example:
GET https://www.concursolutions.com/api/v3.0/expense/attendeetypes HTTP/1.1
Authorization: OAuth pBA8nW1qGJcd4AZp9sGxti374Cc=
Content-Type: application/json
In this example, we’re looking for the attendee type ID for Business Guest attendee types. A successful response looks like this:
{
"Items": [
{
"Name": "Business Guest",
"Code": "BUSGUEST",
"AttendeeFormID": "gWgSQwsOy6EcM7sy3esMk25cqEZM9yf9gPg",
"DuplicateSearchFields": [
"Title",
"Company",
"OwnerEmpName",
"FirstName",
"LastName"
],
"ConnectorID": "",
"AllowManuallyEnteredAttendees": true,
"AllowAttendeeCountEditing": false,
"ID": "gWjUHBxUY4iQLA9KTkbtUD6pc",
"URI": "https://www.concursolutions.com /api/v3.0/expense/attendeetypes/gWjUHBxUY4iQLA9KTkbtUD6pc"
},
{
"Name": "Employee",
"Code": "EMPLOYEE",
"AttendeeFormID": "gWgSQwsOy6EcM7sy3esMk25cqEZM9yf9gPg",
"DuplicateSearchFields": [
"Title",
"Company",
"OwnerEmpName",
"FirstName",
"LastName"
],
"ConnectorID": "",
"AllowManuallyEnteredAttendees": true,
"AllowAttendeeCountEditing": false,
"ID": "gWjYs6nUm$ptrgvkjvwYt2B3SN",
"URI": " https://www.concursolutions.com/api/v3.0/expense/attendeetypes/gWjYs6nUm$ptrgvkjvwYt2B3SN"
}
],
"NextPage": null
}
Now we can make our POST request to the /api/v3.0/expense/attendees endpoint:
POST https://www.concursolutions.com/api/v3.0/expense/attendees HTTP/1.1
Authorization: OAuth pBA8nW1qGJcd4AZp9sGxti374Cc=
Content-Type: application/json
With this request body:
{
"AttendeeTypeID": "gWjUHBxUY4iQLA9KTkbtUD6pc",
"FirstName": "Taylor",
"LastName": "Hernandez",
"MiddleInitial": "E",
"Company": "Life Care Center of Action",
"Title": "Anaesthetics",
"ExternalID": "6164704601"
}
A successful response looks like this:
{
"ID":"nmBwIaoDagUvXYaxgYZp$pWlPZOvpzUfsM",
"URI": "https://www.concursolutions.com/api/v3.0/expense/attendees/nmBwIaoDagUvXYaxgYZp$pWlPZOvpzUfsM"
}
Once you obtain the ID for the attendee, make a POST request to the Entry Attendee Associations resource. To make this call, the user account associated with the OAuth 2.0 access token must have an SAP Concur account with one of these roles: Web Services Administrator for Professional or Can Administer for Standard.
Here’s what the call looks like:
POST https://www.concursolutions.com/api/v3.0/expense/entryattendeeassociations?user={URL_Encoded_Login_ID_for_the_Login_ID_for_the_owner_of_the_expense_entry} HTTP/1.1
Authorization: OAuth {valid OAuth Access Token goes here}
Content-Type: application/json
Accept: application/json
...
{
"EntryID": "n4MrUpcqIH3ot4bFvFCNXCpk7TJOphLTH",
"AttendeeID": "nmBwIaoDagUkD8kXZGIl7B170uK9tE6pk"
}
In this example, the content body for POST request has an expense entry with the unique identifier n4MrUpcqIH3ot4bFvFCNXCpk7TJOphLTH
and the attendee with the unique identifier nmBwIaoDagUkD8kXZGI l7B170uK9tE6pk
.