Event Subscription Management
1. Access Control (JWT)
The Event Subscription Service (ESS) APIs uses the standard Concur OAuth2 Framework for Authentication and Authorization via JSON Web Token (JWT).
The authentication is done by using a JWT which represents the event subscriber. This can be obtained by calling the Client Credentials grant type using your OAuth2 credentials. The JWT generated by this grant will have a JWT Type
of App
where your Application ID
is the Subject
of the Token.
For authorization, the Application needs to contain the scope events.topic.read
in order to access the ESS APIs. This scope will be inherited by the JWT during the Client Credentials Grant which is then checked by the ESS API.
Pass the JWT in the Post Header when making calls to the ESS API:
Authorization: Bearer <JWT>
The Client Credentials JWT has a lifetime of 60 minutes and can only be obtained again via the Client Credentials Grant.
2. Browse available topics
Before you create any subscription you need to verify that you have sufficient access to the topic. If that request returns empty you need to get in touch with your assigned contact from SAP Concur to set proper scopes to your Concur Oauth2 Application.
Request
GET /events/v4/topics
Response
["public.test"]
3. Create a subscription
To create a subscription you need to
- know and have sufficient access to the topic
- get your receiving endpoint running, endpoint requirements
- come up with unique name (id) of your subscription. Subscription names are globally unique, and you will get an error if name is already occupied.
- set filter to
.*
(regexp syntax), you can use it later to filter out unwanted types of events
Request
PUT /events/v4/subscriptions/webhook
{
"id": "my-unique-subscription-id",
"filter": ".*",
"topic": "public.test",
"webHookConfig": {
"endpoint": "https://www.concuress.com/sub/my-valid-endpoint"
}
}
Response
{"message":"Subscription 'my-unique-subscription-id' saved successfully"}
4. Verify your subscription
You can always request a configuration of your subscription. You might notice that your subscription contains some more parameters that you can not modify for security reasons, but can use them for troubleshooting purposes.
- applicationId - identifies your Concur Application as an owner of that subscription
- companyIds - a list of UUIDs of companies that allowed your Applicaion to access their data, the process of connecting Concur company to your application is described here (link)
- groups and scope - are used for complex access control scenarios
Request
GET /events/v4/subscriptions/my-unique-subscription-id
Response
[
{
"id": "my-unique-subscription-id",
"topic": "public.test",
"filter": ".*",
"webHookConfig": {
"endpoint": "https://www.concuress.com/sub/my-valid-endpoint"
},
"applicationId": "dabd27f0-23e7-415d-b5e5-19a7dbe4fb4d",
"scope": "",
"groups": [],
"companyIds": []
}
]
5. Browse existing subscriptions
If you happen to forget your subscription name/id, you can always retrieve all of your subscriptions by calling next endpoint:
Request
GET /events/v4/subscriptions
Response
[
{
"id": "my-second-unique-subscription-id",
"topic": "public.test",
"filter": ".*",
"webHookConfig": {
"endpoint": "https://www.concuress.com/sub/my-second-valid-endpoint"
},
"applicationId": "dabd27f0-23e7-415d-b5e5-19a7dbe4fb4d",
"scope": "",
"groups": [],
"companyIds": []
},
{
"id": "my-unique-subscription-id",
"topic": "public.test",
"filter": ".*",
"webHookConfig": {
"endpoint": "https://www.concuress.com/sub/my-valid-endpoint"
},
"applicationId": "dabd27f0-23e7-415d-b5e5-19a7dbe4fb4d",
"scope": "",
"groups": [],
"companyIds": []
}
]
6. Delete your subscription
Request
DELETE /events/v4/subscriptions/my-unique-subscription-id
Response
{
"message": "Subscription 'my-unique-subscription-id' marked for deletion"
}
6. Request Example
HEADERS
PUT /events/v4/subscriptions/webhook HTTP/1.1
Content-Type: application/json
Concur-Correlationid: something-unique-and-trackable
Authorization: Bearer eyJ0e*****MY-SECRET-JWT-HERE********
Accept: */*
Cache-Control: no-cache
Host: www-us.api.concursolutions.com
Accept-Encoding: gzip, deflate
Connection: keep-alive
BODY
{
"id": "my-unique-subscription-example",
"filter": ".*",
"topic": "public.test",
"webHookConfig": {"endpoint": "https://www.concuress.com/sub/my-unique-endpoint" }
}
CURL Code
curl -X PUT \
https://www-us.api.concursolutions.com/events/v4/subscriptions/webhook \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Authorization: Bearer eyJ0e*****MY-SECRET-JWT-HERE********' \
-H 'Cache-Control: no-cache' \
-H 'Concur-Correlationid: something-unique-and-trackable' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'Host: www-us.api.concursolutions.com' \
-H 'cache-control: no-cache' \
-d '{
"id": "my-unique-subscription-example-2",
"filter": ".*",
"topic": "public.test",
"webHookConfig": {
"endpoint": "https://www.concuress.com/sub/my-unique-endpoint"
}
}'