Access Control (JWT)

The Event Subscription Service (ESS) API uses the standard SAP Concur OAuth2 Framework for Authentication and Authorization via a 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 API. 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.

Browse Available Topics

Before you create any subscriptions you need to verify that you have sufficient access to the topic. If that request returns an empty response you need to get in touch with your SAP Concur contact to set proper scopes to your OAuth2 application.

Request

GET /events/v4/topics

Response

["public.test"]

Create a Subscription

To create a subscription you need to:

  • Know and have the sufficient access to the topic by having the correct scopes.
  • Get your receiving endpoint running, see the endpoint requirements.
  • Come up with unique name (id) of your subscription. Subscription names are globally unique, and you will get an error if the name is already in use.
  • 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"
  }
}

Request Parameters

Name Type Format Description
Id String Lowercase letters, numbers, “.” and “-“ Your unique subscription name. It is suggested that you use something self explanatory. For example: my-company.my-scenario.env.version
Filter String regular expression Allows you to reduce the number of delivered events to a certain type. Example, setting to eventCreated will only get this event type delivered, other event types will be skipped. Set to “.*” to receive ALL events in the topic.
Topic String - Topic, stream of events you are subscribing to.
Endpoint String URL Your endpoint where events will be delivered.

Response

{"message":"Subscription 'my-unique-subscription-id' saved successfully"}

Verify Your Subscription

You can always request a configuration of your subscription. You might notice that your subscription contains some parameters that you can not modify for security reasons, but you can use them for troubleshooting purposes.

  • applicationId - identifies your application as an owner of that subscription.
  • companyIds - a list of UUIDs of companies that allowed your application to access their data, the process of connecting a company to your application is described here.
  • 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": []
    }
]

Response Parameters

Name Type Format Description
Id String Lowercase and . - \d YYour unique subscription name. It is suggested that you use something self explanatory. For example: my-company.my-scenario.env.version
Filter String regular expression Allows you to reduce the number of delivered events to a certain type. Example, setting to eventCreated will only get this event type delivered, other event types will be skipped. Set to “.*” to receive ALL events in the topic.
Topic String - Topic, stream of events you are subscribing to.
Endpoint String URL Your endpoint where events will be delivered.
applicationId String UUID The partner application that was used to generate the JWT. Application is used to establish subscription owner.
companyIds List list of UUIDs List of Company UUIDs who have connected to a partner application allowing events to be delivered.
groups List - Reserved for future support scenarios.
scope String - Reserved for future support scenarios.

Browse Existing Subscriptions

If you happen to forget your subscription name/id, you can always retrieve all of your subscriptions by calling the following 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": []
    }
]

Delete Your Subscription

Request

DELETE /events/v4/subscriptions/my-unique-subscription-id

Response

{
    "message": "Subscription 'my-unique-subscription-id' marked for deletion"
}

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

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"
  }
}'