Use OAuth2 Authentication with Event Notification Service

Access to the Event Notification Service (ENS) is secured using message signing and IP allowlisting. In some cases, it’s preferable to have ENS authenticate with your system before pushing event notifications. To meet this requirement, ENS supports OAuth2 authentication.

These instructions assume that you’re familiar with the Event Notification Service API.

Supported Grant Types 

Marketing Cloud Engagement supports authentication using the OAuth2 client_credentials and password grant types.

To use the client_credentials grant type, your system must support clientId, clientSecret, authUrl.

The password grant type uses resource owner password credential (ROPC). To use this grant type, your system must support clientId, clientSecret, username, password, authUrl.

The password grant type is considered a legacy authentication scheme. However, many customers find the level of risk for this use case to be acceptable.

Note

OAuth2 Authorization Server Requirements 

Your authorization server must be publicly accessible and must serve requests over HTTPS. It must be able to return authorization tokens within 2 seconds of the request being issued, and must support the concurrent provisioning of multiple tokens. The server must support client requests with parameters in application/x-www-form-urlencoded format with UTF-8 character encoding. Successful responses must include the access_token property.

If you use the password grant type, your server must support the HTTP Basic authentication scheme for authenticating clients that were issued a client password.

Optionally, responses can use the access_token scope. See IETF: RFC 6749.

Create an ENS Callback Authentication Scheme 

Before you configure ENS callbacks for authentication, create an authentication scheme. When you create or update calls for OAuth2 requests, verify that the authentication URL successfully returns a token.

When there is a delete request, ENS confirms that all callback associations with the authentication scheme have been removed. If this verification step isn’t successful, the request fails.

Client Credential Authentication Example 

This code sample shows an example of a REST request using the client_credential grant type.

1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2POST /platform/v1/ens-authentications
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6[
7  {
8    "authType": "oauth2",
9    "grantType": "client_credentials",
10    "clientId": "YOUR_CLIENT_ID",
11    "clientSecret": "YOUR_CLIENT_SECRET",
12    "authUrl": "https://example.com/oauth/token",
13    "scope": "write"
14  }
15]

The response includes an authID parameter. Fields that contain sensitive data, such as the clientId and clientSecret fields, aren’t included in the response.

1[
2  {
3    "authId": "22z825az-c2b5-46fe-81d0-d6abcbe8111c",
4    "authType": "oauth2",
5    "grantType": "client_credentials",
6    "authUrl": "https://example.com/oauth/token",
7    "scope": "write"
8  }
9]

Password Authentication Example 

This code sample shows an example of a REST request using the password grant type.

1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2POST /platform/v1/ens-authentications
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6[
7  {
8    "authType": "oauth2",
9    "grantType": "password",
10    "clientId": "YOUR_CLIENT_ID",
11    "clientSecret": "YOUR_CLIENT_SECRET",
12    "username": "YOUR_USERNAME",
13    "password": "YOUR_PASSWORD",
14    "authUrl": "https://example.com/oauth/token",
15    "scope": "write"
16  }
17]

The response includes an authID parameter. Fields that contain sensitive data, such as the clientId, clientSecret, username, and password fields, aren’t included in the response.

1[
2  {
3    "authId": "22z825az-c2b5-46fe-81d0-d6abcbe8111c",
4    "authType": "oauth2",
5    "grantType": "password",
6    "authUrl": "https://example.com/oauth/token",
7    "scope": "write"
8  }
9]

Create the ENS Callback 

Register a new callback to receive event notifications by sending a POST request to the /platform/v1/ens-callbacks API endpoint.

1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2POST /platform/v1/ens-callbacks
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6[
7  {
8    "callbackName": "cb1",
9    "url": "https://example.com/sfmc-events",
10    "maxBatchSize": 1000,
11    "authId": "22z825az-c2b5-46fe-81d0-d6abcbe8111c"
12  }
13]

The response includes the callback ID and a signature key.

1HTTP/1.1 201 Created
2
3[
4  {
5    "callbackName": "cb1",
6    "callbackId": "65b885ab-c2b4-46fe-85d0-d6cb8be8057d",
7    "url": "https://example.com/sfmc-events",
8    "signatureKey":"V27FXfqI3DnhfQW1bhFDeJixpt8eDAY5R24UJI3cK6M=",
9    "maxBatchSize": 1000,
10    "authUrl": "22z825az-c2b5-46fe-81d0-d6abcbe8111c"
11  }
12]

To verify events via message signature, capture the value of the signatureKey property in the response.

For more information about the ens-callbacks endpoint, see Create Callback.

Verify ENS Callback 

Verify that the callback can receive notifications by sending a POST request to the /platform/v1/ens-verify endpoint. The request includes the callback ID and the verification key from the creation request.

1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2POST /platform/v1/ens-verify
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6{
7  "callbackId": "65b885ab-c2b4-46fe-85d0-d6cb8be8057d",
8  "verificationKey": "CZwJw4XATH6LK1fPWFeMDkIyVbro6T3ijXK8CrzQe2s="
9}

If the callback is operating as expected, the API returns a 200 OK response.

For more information about the ens-verify endpoint, see Verify Callback.

Create an ENS Subscription 

After you verify the callback, create a subscription. A subscription indicates the event types that you want to receive notifications for and which callback to receive them on. A new subscription takes up to 2 minutes to become active. Each callback can have up to 200 subscribers.

Ensure that the callback you specify is ready to receive events before creating a subscription for it. This code provides an example of a request to create a subscription. It includes these properties:

PropertyTypeDescription
subscriptionNameStringA unique name for the subscription.
callbackIdStringThe unique identifier of the callback that receives the notification events. This callback must exist and must be verified.
eventCategoryTypesArray of stringsThe comma-separated list of fully qualified event types for which you’re requesting notifications. This list is expressed as NotificationEventCategory.NotificationEventType. See Supported Notification Events.
filtersArray of stringsEach string in the array is a key-value pair to filter on. Filter values must use the syntax key=value. See Subscription Filters.
1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2POST /platform/v1/ens-subscriptions
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6[
7  {
8    "callbackId": "65b885ab-c2b4-46fe-85d0-d6cb8be8057d",
9    "subscriptionName": "sub1",
10    "eventCategoryTypes": [
11      "TransactionalSendEvents.EmailNotSent",
12      "TransactionalSendEvents.EmailSent"
13    ],
14    "filters": ["definitionKey=12345"]
15  }
16]

The response includes a subscription ID and the status of the subscription.

1HTTP/1.1 201 Created
2
3[
4  {
5    "callbackId": "65b885ab-c2b4-46fe-85d0-d6cb8be8057d",
6    "callbackName": "cb1",
7    "subscriptionName": "sub1",
8    "eventCategoryTypes": [
9      "TransactionalSendEvents.EmailNotSent",
10      "TransactionalSendEvents.EmailSent"
11    ],
12    "subscriptionId": "d89c87c4-70f8-43d6-be1e-f01dce97fe4c",
13    "filters": ["definitionKey=12345"],
14    "status": "active"
15  }
16]

For more information about the ens-subscription endpoint, see Create Subscription.

ENS Stream Processing 

When the callback is configured and subscribed to, you can begin to send events to the authentication server. This code sample shows an example of a request to log an event.

The Authorization header in the request includes the bearer token only if the authentication token was retrieved successfully. If the token retrieval fails, the Authorization header contains a value of Bearer null, and the request fails.

Important

1Host: https://example.com
2POST /sfmc-events
3Content-Type: application/json
4Authorization: Bearer b2f67f94-2956-42c0-88b3-c246f5da8ba0
5x-sfmc-ens-signature: 0lpCnt5QNGcLbFJxw3H15wjtWI+T0ZaLUHlrCS6LWUQ=
6
7[
8  {
9    "eventCategoryType":"TransactionalSendEvents.EmailSent",
10    "timestampUTC":1596137717051,
11    "compositeId":"6b1a9f18-2de9-e911-a2d6-1402ec938821.14598719.2262900.400.935980107",
12    "definitionKey":"eventbus_definition_key",
13    "mid":10991090,
14    "eid":10991090,
15    "info": {
16      "to":"eventbus@bh.exacttarget.com",
17      "subscriberKey":"eventbus_sub_key",
18      "messageKey":"072b0950-1f41-4ed4-9920-b65b033b2f47",
19      "status":"Sent",
20      "renderedSubject":"Test email"
21    },
22    "definitionId":"6b1a9f18-2de9-e911-a2d6-1402ec938821"
23  }
24]

Update ENS Callback Authentication 

To modify the authentication configuration for a callback, send a PUT request to the /platform/v1/ens-authentications endpoint. There can be a delay of a few minutes before the changes to the callback become active. This code example shows how to update a callback.

1Host: https://YOUR_SUBDOMAIN.rest.marketingcloudapis.com
2PUT /platform/v1/ens-authentications
3Content-Type: application/json
4Authorization: Bearer YOUR_ACCESS_TOKEN
5
6[
7  {
8    "authId": "22z825az-c2b5-46fe-81d0-d6abcbe8111c",
9    "authType": "oauth2",
10    "grantType": "password",
11    "clientId": "myClientId",
12    "clientSecret": "myClientSecret",
13    "username": "exampleUsername",
14    "password": "examplePassword",
15    "authUrl": "https://example.com/oauth/token"
16  }
17]

The response includes an updated authId property.

1HTTP/1.1 200 OK
2
3[
4  {
5    "authId": "22z825az-c2b5-46fe-81d0-d6abcbe8111c",
6    "authType": "oauth2",
7    "grantType": "password",
8    "authUrl": "https://example.com/oauth/token"
9  }
10]