Subscriptions

This page talks about how to manage subscriptions for events and notifications with v1 API.

The primary duty of the Notification Service is to handle client subscriptions. It allows clients to:

  1. Create a subscription to the Avaya Experience Platform™ real-time interface.
  2. Retrieve the list of subscriptions.
  3. Retrieve a particular subscription.
  4. Renew a subscription.
  5. Delete a subscription.

To create a subscription the client has to specify the family.
The family - an entity that represents a set of events. Only one family could be specified per subscription.
The following event families are currently supported:

familydescription
AGENT_ENGAGEMENTContact Center Agent and Engagement events are available for the streaming needs of client applications. This family focuses on CTI eventing as an engagement progresses through the Contact Center.
ANALYTICSProvides a mechanism for third-party clients to subscribe to Analytics Realtime Data. Measures for an Event Source and Measure Producer will be produced as Realtime Data onto an outgoing websocket.

AGENT_ENGAGEMENT

Event Types

Notification Agent and Engagement support the next events:

eventstopic
ALL
AgentLoggedInagent
AgentReadyagent
AgentNotReadyagent
AgentLoggedOutagent
InboundEngagementCreatedengagement
OutboundEngagementCreatedengagement
EngagementPreroutedengagement
AutomationParticipantAddedengagement
AutomationParticipantRemovedengagement
AgentParticipantInvitedengagement
AgentParticipantAddedengagement
AgentParticipantRemovedengagement
AgentParticipantHeldengagement
AgentParticipantUnheldengagement
AgentParticipantMovedengagement
AgentParticipantObservingengagement
AgentParticipantCoachingengagement
AgentParticipantBargedInengagement
ExternalParticipantInvitedengagement
ExternalParticipantAddedengagement
ExternalParticipantRemovedengagement
SingleStepTransferInitiatedengagement
SingleStepTransferCancelledengagement
SingleStepTransferFailedengagement
SingleStepTransferToUserInitiatedengagement
SingleStepTransferToUserCancelledengagement
SingleStepTransferToUserFailedengagement
SingleStepTransferToExternalInitiatedengagement
SingleStepTransferToExternalCancelledengagement
SingleStepTransferToExternalFailedengagement
SingleStepTransferToAutomationInitiatedengagement
SingleStepTransferToAutomationCancelledengagement
SingleStepTransferToAutomationFailedengagement
MatchOfferedmatch

If the client wants to receive all the events mentioned above it has to specify ALL in the request body on subscription creation:

{
  "events": [
    "ALL"
  ]
}

If the client wants to receive only specific events, it has to specify them in the format topic:eventName :

{
  "events": [
    "agent:AgentLoggedIn",
    "engagement:InboundEngagementCreated"
  ]
}

Or the client can specify just the topic name if it wants to receive all events from a specific topic.

{
  "events": [
    "agent"
  ]
}

Transport

Currently, Notification Agent and Engagement supports only websocket transport type for v1 API.

Authentication

The authentication is done by How to Authenticate with Avaya Experience Platform™ APIs ).

In order to create an AGENT_ENGAGEMENT subscription the client has to use Client Credentials Grant with role trusted_client.

In order to create an ANALYTICS subscription the client has to use Resource Owner Password Credentials Grant with role Reporting_Supervisor or Reporting_Administrator.

Making an API Call.

Possible A&A Failure Codes:

  • Unauthorized (401) - Missing or Invalid token.
  • Access Denied (403) - Token validation successful, but insufficient privileges.

Example

Create a Subscription request

The following is an example of the payload returned when a client sends an AgentEngagement Subscription.

POST /subscriptions

/v1/accounts/ABCDEF/subscriptions

Subscription request body:

{
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "ALL"
  ],
  "transport": {
    "type": "WEBSOCKET"
  }
}

Subscription response:

HTTP 200 OK

{
  "subscriptionId": "2fd147d5-3a25-4834-90f7-f9f417c4894f",
  "createdAt": "2022-11-18T12:00:56.277061Z",
  "expiresAt": "2022-11-18T12:15:28.277061Z",
  "expiresIn": 872,
  "status": "ACTIVE",
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "ALL"
  ],
  "transport": {
    "type": "WEBSOCKET",
    "endpoint": "wss://dev-1.ixcc-sandbox.avayacloud.com:443/ix-notification-dispatchers/notification-websocket/notifications/ESPSEO/2fd147d5-3a25-4834-90f7-f9f417c4894f",
    "authTokenHeader": "auth-token",
    "pingInterval": 300
  }
}

Important fields to consider:

  • status: The status of the subscription can be either: ACTIVE or INACTIVE. A created subscription has an ACTIVE state and remains in that state until it expires and becomes INACTIVE. Then the subscription is deleted after some time. The default inactive subscription lifetime is 24h.
  • endpoint: This is the URL of the WebSocket endpoint for the client.
  • pingInterval: The expected time between ping messages. Ping messages keep the WebSocket session alive when a client is connected to the notification dispatchers. The default value is 300s.

Error cases:

Invalid realm or the client doesn't have access to the realm response:

HTTP 403 Forbidden

{
  "timestamp": "2022-12-01T11:45:55.773+00:00",
  "status": 403,
  "error": "Forbidden",
  "message": "",
  "path": "/v1/accounts/ABCDED/subscriptions"
}

Invalid Family response:

HTTP 400 Bad Request

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#constraint-violation",
  "status": 400,
  "violations": [
    {
      "field": "unknown",
      "message": "Unexpected value 'AGENT'"
    }
  ],
  "title": "Constraint Violation"
}

Invalid topic in subscription request body "events" field:

{
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "invalidTopic:AgentReady"
  ],
  "transport": {
    "type": "WEBSOCKET"
  }
}

Response:

HTTP 400 Bad Request

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#constraint-violation",
  "status": 400,
  "violations": [
    {
      "field": "events",
      "message": "Topic \"invalidTopic\" is not allowed for streaming"
    }
  ],
  "title": "Constraint Violation"
}

Invalid event in subscription request body "events" field:

{
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "engagement:invalidEvent"
  ],
  "transport": {
    "type": "WEBSOCKET"
  }
}

Response:

HTTP 400 Bad Request

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#constraint-violation",
  "status": 400,
  "violations": [
    {
      "field": "events",
      "message": "Event \"invalidEvent\" is not allowed for streaming"
    }
  ],
  "title": "Constraint Violation"
}

Internal Server Error response:

HTTP 500 Internal Server Error

{
  "title": "Internal Server Error",
  "status": 500,
  "detail": "<Details why the error happened>",
  "instance": "/v1/accounts/cKPQGK/subscriptions"
}

This error applies to any API requests described in this guide and means that an internal server error was encountered, and it usually can't be resolved on the client side.

Get the list of created Subscriptions

The following is an example of the payload returned when a client requests the list of AgentEngagement Subscriptions.

GET /subscriptions

/v1/accounts/ABCDEF/subscriptions

HTTP 200 OK

{
  "pagination": {
    "pageNumber": 1,
    "pageSize": 10,
    "total": 1
  },
  "subscriptions": [
    {
      "subscriptionId": "2fd147d5-3a25-4834-90f7-f9f417c4894f",
      "createdAt": "2022-11-18T12:00:56.277061Z",
      "expiresAt": "2022-11-18T12:15:28.277061Z",
      "expiresIn": 872,
      "status": "ACTIVE",
      "family": "AGENT_ENGAGEMENT",
      "events": [
        "ALL"
      ],
      "transport": {
        "type": "WEBSOCKET",
        "endpoint": "wss://dev-1.ixcc-sandbox.avayacloud.com:443/ix-notification-dispatchers/notification-websocket/notifications/ESPSEO/2fd147d5-3a25-4834-90f7-f9f417c4894f",
        "authTokenHeader": "auth-token",
        "pingInterval": 300
      }
    }
  ],
  "links": {
    "prev": "",
    "next": ""
  }
}

The response body contains pagination information.

  • pageNumber - The current page number.
  • pageSize - The max number of records that can be retrieved on this page.
  • total - The total number of records.

In order to request a specific page the client has to specify it:

GET /subscriptions?pageSize=10&pageNumber=4

If the specified pageNumber doesn't exist the 1st page will be shown.

The response body contains links to the previous and the next page if they exist:

  • prev - URL of the previous page. Blank if currently on the first page.
  • next - URL of the next page. Blank if currently on the last page.

Error cases:

Invalid realm response:

HTTP 403 Forbidden

{
  "timestamp": "2022-12-01T11:45:55.773+00:00",
  "status": 403,
  "error": "Forbidden",
  "message": "",
  "path": "/v1/accounts/ABCDED/subscriptions"
}

Get a single Subscription

The following is an example of the payload returned when a client requests a Subscription for a given subscriptionId.

GET /subscriptions/{subscriptionId}

/v1/accounts/ABCDEF/subscriptions/2fd147d5-3a25-4834-90f7-f9f417c4894f

HTTP 200 OK

{
  "subscriptionId": "2fd147d5-3a25-4834-90f7-f9f417c4894f",
  "createdAt": "2022-11-18T12:00:56.277061Z",
  "expiresAt": "2022-11-18T12:15:28.277061Z",
  "expiresIn": 872,
  "status": "ACTIVE",
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "ALL"
  ],
  "transport": {
    "type": "WEBSOCKET",
    "endpoint": "wss://dev-1.ixcc-sandbox.avayacloud.com:443/ix-notification-dispatchers/notification-websocket/notifications/ESPSEO/2fd147d5-3a25-4834-90f7-f9f417c4894f",
    "authTokenHeader": "auth-token",
    "pingInterval": 300
  }
}

Error cases:

Invalid realm response:

HTTP 403 Forbidden

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling",
  "title": "Forbidden",
  "status": 403,
  "detail": "Access is denied"
}

Invalid subscriptionId response:

HTTP 404 Not Found

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#resource-not-found",
  "title": "Resource Not Found",
  "status": 404,
  "detail": "Subscription not found for account:ABCDEF and id:2fd147d5-3a25-4834-90f7-f9f417c4894f"
}

Renew a Subscription request

POST /subscriptions/{subscriptionId}:renew

The Client needs to call the :renew API before the token expires to keep the subscription in an ACTIVE state.

/v1/accounts/ABCDEF/subscriptions/2fd147d5-3a25-4834-90f7-f9f417c4894f:renew

HTTP 200 OK

{
  "subscriptionId": "2fd147d5-3a25-4834-90f7-f9f417c4894f",
  "createdAt": "2022-11-18T12:00:56.277061Z",
  "expiresAt": "2022-11-18T12:26:32.651953Z",
  "expiresIn": 837,
  "status": "ACTIVE",
  "family": "AGENT_ENGAGEMENT",
  "events": [
    "ALL"
  ],
  "transport": {
    "type": "WEBSOCKET",
    "endpoint": "wss://dev-1.ixcc-sandbox.avayacloud.com:443/ix-notification-dispatchers/notification-websocket/notifications/ESPSEO/2fd147d5-3a25-4834-90f7-f9f417c4894f",
    "authTokenHeader": "auth-token",
    "pingInterval": 300
  }
}

Error cases:

Invalid realm response:

HTTP 403 Forbidden

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling",
  "title": "Forbidden",
  "status": 403,
  "detail": "Access is denied"
}

Invalid subscriptionId response:

HTTP 404 Not Found

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#resource-not-found",
  "title": "Resource Not Found",
  "status": 404,
  "detail": "Subscription not found for account:ABCDEF and id:e82cfb04-8d34-48dd-924f-0eded1e9c688"
}

Delete a Subscription

The following is an example of the payload returned when a client requests the deletion of an Agent and Engagement Subscription.

DELETE /subscriptions/{subscriptionId}

/v1/accounts/ABCDEF/subscriptions/2fd147d5-3a25-4834-90f7-f9f417c4894f

HTTP 200 OK

Error cases:

Invalid realm response:

HTTP 403 Forbidden

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling",
  "title": "Forbidden",
  "status": 403,
  "detail": "Access is denied"
}

Invalid subscriptionId response:

HTTP 404 Not Found

{
  "type": "https://developers.avayacloud.com/onecloud-ccaas/docs/error-handling#resource-not-found",
  "title": "Resource Not Found",
  "status": 404,
  "detail": "Subscription not found for account:ABCDEF and id:18c76aba-cf54-4f9a-b0e7-6d26fcf8a776"
}

Notification Agent and Engagement Async API

The Notification Async API uses a WebSocket interface to publish real-time events.

Establishing a WebSocket connection

The client opens a websocket connection using the endpoint value from the subscription response:

{
  "transport": {
    "endpoint": "wss://dev-1.ixcc-sandbox.avayacloud.com:443/ix-notification-dispatchers/notification-websocket/notifications/ESPSEO/6fc966e9-ae5a-4629-a61e-6069262197b4"
  }
}

Once the connection is established, the Client sends an Authentication object containing the token.

{
  "event": "authentication",
  "token": "JWT_TOKEN"
}

The Notification Async API responds with an AuthenticationResponse object.

{
  "event": "authenticationResponse",
  "status": "CONNECTION_CONFIRMED",
  "subscriptionId": "b4581220-9a2e-4a34-9a6d-90db36aa56ef",
  "pingInterval": "300",
  "expiresInterval": "300"
}

The WebSocket connection status can take the following values:

StatusDescription
CONNECTION_CONFIRMEDConnection was confirmed.
CONNECTION_FAILED_INVALID_TOKENAuthentication token is invalid.
CONNECTION_FAILED_UNKNOWN_SUBSCRIPTIONUnknown Subscription, can be for a subscription that never existed or one that is no longer active.
CONNECTION_FAILED_INTERNAL_SERVER_ERRORServer Error, client can retry later.
CONNECTION_FAILED_CONSTRAINT_VIOLATIONClient issue, malformed client request, client must update payload and retry.

Check the status of the subscription in the Notification Service if the client does not receive a CONNECTION_CONFIRMED.

Consuming real-time data

The Notification real-time interface sends data once the connection is established and the Authentication object is processed.

Avaya Experience Platform™ Notification sends the supported produced events to the client if the client subscribed for them.

An example of a real-time "EngagementPrerouted" event:

{
  "correlationId": "1661864b-f6fc-491a-b16a-d0f14765023d",
  "subscriptionId": "6fc966e9-ae5a-4629-a61e-6069262197b4",
  "family": "AGENT_ENGAGEMENT",
  "sentAt": "2022-11-18T14:28:36Z",
  "accountId": "ESPSEO",
  "body": {
    "engagementId": "240a2179-3a87-45ca-893a-51ef6f49723c",
    "dialogId": "dac38258-cfb4-41d4-8b73-f8cacfc83fe1",
    "orchestrationFlow": "TestFlow",
    "attributes": [
      {
        "category": "Category1",
        "values": [
          "Value1",
          "Value2)"
        ]
      }
    ],
    "attributeList": [
      "Value1",
      "Value2)"
    ],
    "engagementParameters": {
      "param1": "value1",
      "param2": "value2"
    },
    "agentRoutingStrategy": {
      "type": "LAR",
      "waitTime": 1
    },
    "adhocEmail": false,
    "autoResponse": "AutoResponse",
    "channelProviderId": "78b9fb89-1704-4685-9f9c-e591b69ef58f",
    "channelId": "Voice",
    "channelIdentifier": "ChannelIdentifier",
    "queue": {
      "queueId": "01455566-5d83-44aa-abe0-8e2e93ef9dc3",
      "queueName": "Queue",
      "priority": 1,
      "proficiencyRangeMin": 1,
      "proficiencyRangeMax": 10
    },
    "customerIdentifiers": {
      "phoneNumbers": [
        "123",
        "1234"
      ],
      "accountIds": [
        "test1",
        "test2"
      ]
    },
    "externalParticipantId": "93826dbc-cd4d-4037-bfa1-8a0051a8a76c",
    "sourceAddress": "123123",
    "destinationAddress": "12341234",
    "subject": "Subject",
    "id": "dec422f5-9cbd-42a3-98a4-899ead6bfc07",
    "timestamp": 1668781716489,
    "event": "EngagementPrerouted"
  }
}

Ping pong

The Client MUST send periodic ping messages to the Notification Async API to keep the WebSocket connection alive.
Failure to send a ping message in time will result in the WebSocket session being closed and ultimately the Subscription going inactive.
The ping interval default value is 300s and can be changed via notification-service configuration.
The ping pong mechanism could be disabled via notification-dispatcher configuration.

To do a ping the Client sends a Ping object.

{
  "event": "ping"
}

The Notification server responds with a Pong object.

{
  "event": "pong"
}

Closing the connection

The Client MUST close the WebSocket connection when it no longer wishes to receive data. More information about WebSocket close opcode can be found here.

The Client also MUST call the Delete Subscription API on the Notification Service to clean up its subscription.

Building a client

Please use the OpenAPI and AsyncAPI code generators to build client SDKs to interface with the Avaya Experience Platform™ Notification Agent and Engagement APIs:

There API reference is here -- Notification Service API
More details on the websocket connect and events can be found here -- Agent and Engagement Events