Bring Your Own Datasource
This guide explains how to facilitate data exchange with the Webex Suite and Webex Contact Center (Webex CC) using the Bring Your Own Data Source (BYODS) framework via the dataSources REST endpoint. For Contact Center use cases, BYODS serves as the baseline for configuring the complimentary Bring Your Own Virtual Agent (BYOVA) framework.
This guide is tailored for data providers seeking to integrate with the Webex Suite and Webex Contact Center (Webex CC). It aims to streamline the development process for Cisco partners (Data Access Providers) who want to manage Webex interaction data and can deliver actions or insights back to customers.
These integrations can enhance real-time interactions within the Webex ecosystem, such as enabling type-ahead suggestions for Webex Adaptive Cards or supporting media exchanges in Webex CC for AI-driven services like Bring Your Own Virtual Agent (BYOVA). The data exchanges are conducted over high-bandwidth, high-fidelity gRPC connections, allowing direct interaction between Webex and data providers. This guide details the steps required to establish and secure these connections, ensuring efficient and effective data integration.
anchorWhat is "Bring Your Own Data Source"?
anchorThe Bring Your Own Data Source service is managed through the /dataSources
REST endpoint. Data access providers use this endpoint to register a URL where they intend to receive data. Additionally, providers select a schema that represents the type of data they wish to exchange with Webex Suite or Webex CC. Depending on the selected Data Exchange Schema, the data exchange can be either unidirectional or bidirectional.
The BYODS mechanism offers a standardized, secure framework for establishing and securing data exchanges between Webex Suite or Webex Contact Center, and third-party providers. Services like Bring Your Own Virtual Agent leverage this framework and expand upon it for their specific requirements.
anchorAdvantages of the BYODS Framework
anchorSecurity and Transparency: No data can be exchanged without the third-party provider registering their services and a customer admin approving the data exchange, visible to all admins in Control Hub. Data exchanges are secured via rotating and signed short-lived tokens, and data can only be exchanged with registered domains.
Flexibility: The partner data provider determines the data they wish to exchange with Webex and selects the appropriate schema from a dozen available schemas. If no suitable schema exists, the partner can submit a new schema for Cisco's approval and inclusion in the schema repository. Additionally, the BYODS setup is entirely under the control of the partner and customer, with no need for Cisco's involvement in provisioning the exchange.
Multitenancy and Extensibility: Each data source is registered and maintained separately for each customer organization under one umbrella service application. This setup allows for easy onboarding and offboarding of customers individually without disrupting services for other customers. Customers could be in separate deployment clusters yet rely on the same data source for their critical business processes.
anchorBefore You Start
anchorPlease review the following sections before starting your BYODS flow.
Sandboxes
The quickest and simplest way to get started is by using a sandbox environment. If you are working on Contact Center (CC) use cases, such as "Bring Your Own AI," you can utilize a CC sandbox. For other data exchange ideas within the Webex Suite, such as bot-supported type-ahead in the adaptive cards framework, a regular sandbox will suffice.
Data Exchange Schema Selection
Additionally, browse the available schemas on developer.webex.com to identify an appropriate schema for your data exchange needs. Each schema represents the structure and content of data that can be exchanged between the Data Provider and Webex. For example, the AudioVirtualAgent
schema specifies the format for audio call data being sent to the data provider and receiving audio prompts in return, in order to drive the caller's interaction with the bot.
Data Exchange Domains
You should also determine your domains with which data will be exchanged. These domains will be locked to the Service App and must be approved by the admin. You can specify several domains prior to admin approval. Once authorized in Control Hub by an admin, the system will allow data exchange with any URL within the specified domain. For instance, if you specify the domain cisco.com, data can be exchanged with https://www.cisco.com/{placeholder} as well as https://{placeholder}.cisco.com/. However selecting a wildcard domain (e.g. *.com, . is not possible). Avoid registering a port for the Service App Data Exchange Domains. All ports will be accepted later in the datasource registration.
When exploring the API through the "Try-It" mode on the developer portal, it's important to note that the dataSources
REST endpoint requires a different type of access token than other endpoints. The prefilled personal access token typically used in Try-It
mode will not work for this specific API. Instead, you must use a Service App access token with the appropriate scopes. These are:
spark-admin:datasource_read
- Allows read access to the data source.spark-admin:datasource_write
- Allows write access to the data source.
anchorSet Up a Data Provider
anchorTo become a data provider, start by creating a Service App on developer.webex.com. This app serves as the foundation for data exchanges, independent of any specific customer. During setup, you'll define your app's publicly visible name, choose the data exchange schema, and specify the approved domain(s) for the data exchange. After a Full Admin in Control Hub authorizes the Service App, you'll receive access tokens for the authorizing customer. These tokens are essential for registering a data source for that customer. If you need a refresher in Service Apps, please consult this guide.
To configure a data provider:
- Navigate to the Webex Developer Portal:
- Log in with your credentials.
- Create a New Service App:
- Go to the My Apps section and select Create a New App.
- Choose Service App as the application type.
- Configure the Service App:
- Name: Enter a publicly visible name for your app.
- Data Exchange Schema: Select the schema that defines the data to be exchanged.
- Domains: Specify the domain(s) for data exchange.
- Scopes: Ensure you select the required scopes, such as
spark-admin:datasource_read
andspark-admin:datasource_write
. - Complete any other required information.
- Submit the Service App for Admin Approval:
- In your sandbox, test the Service App by selecting
Request Admin Approval,
making it visible in Control Hub. - For production, submit your app to AppHub for approval. Once approved, it will appear in Control Hub for admin authorization.
- In your sandbox, test the Service App by selecting
Here's a typical configuration for a dataSource Service App created in the Webex Developer Portal:
{
"isNative": false,
"id": "Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL0NjMjE3MTU5NGFjNjMzZWJlYzBhMjJkMmFmNWZmMWU0NGEzOTUzOWMyODgzODUwN2MzZDBkZTk2MjFkMTgzYWZl",
"friendlyId": "testthedatasource-take-4",
"type": "serviceApp",
"name": "TestTheDataSource Take 4",
"logo": "https://avatar-prod-us-east-2.webexcontent.com/Avtr~V1~ce861fba-6e2f-49f9-9a84-b354008fac9e/V1~48351afbb2d28d5c512dd2f63dff43a553cf0c50df1c0bbe1f101d9ecd592f2e~72855c8ae5594e13855778ebf179d0d2",
"description": "Test the Data Source Take 4",
"categories": [],
"tags": [],
"orgId": "Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi9jZTg2MWZiYS02ZTJmLTQ5ZjktOWE4NC1iMzU0MDA4ZmFjOWU",
"contactEmail": "adminaudit@schiffert.me",
"companyName": "Schiffert AG",
"scopes": [
"spark:kms",
"spark-admin:datasource_write",
"spark-admin:datasource_read"
],
"clientId": "Cc2171594ac633ebec0a22d2af5ff1e44a39539c28838507c3d0de9621d183afe",
"isFeatured": false,
"submissionStatus": "none",
"orgSubmissionStatus": "none",
"createdBy": "Y2lzY29zcGFyazovL3VzL1BFT1BMRS8xMTM4NWI3OS1hMDVmLTRkZWMtYWQyYy01YjAyZDc3YTQyZWU",
"created": "2024-10-16T16:54:41.201Z",
"validDomains": [
"schiffert.me",
"cisco.com",
"google.com"
],
"modified": "2024-10-16T16:54:41.201Z",
"entitlements": [
"spark-admin",
"spark",
"webex-squared"
],
"reserved": false,
"dataSourceSchemaIds": [
"78efc775-dccb-45ca-9acf-989a4a59f788"
]
}
anchorAuthorization Process and Token Retrieval
anchorHere's the auth and token retrieval process:
- Authorize the Service App:
- A Full Admin in Control Hub must authorize your Service App. This authorization grants access tokens specific to the customer, data exchange domains, and schema. To change scopes, domains, or schemas, the admin must deauthorize and reauthorize the app.
- Retrieve Customer-Specific Tokens:
- Retrieve access and refresh tokens specific to your customer's organization. These are essential for setting up a data source. Tokens can be obtained via the GUI in the developer portal or through an API call using the spark:applications_token scope.
Subscribe to the Service App's Authorization Webhook
- Quickly respond to authorizations and deauthorizations by subscribing to the Service App's authorization webhook.
- Retrieve access and refresh tokens specific to your customer's organization. These are essential for setting up a data source. Tokens can be obtained via the GUI in the developer portal or through an API call using the spark:applications_token scope.
An authorized Service App includes an authorizationsList,
which details domains and schemas at the time of authorization.
An authorized SA looks like this:
{
"isNative": false,
"id": "Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OL0NjMjE3MTU5NGFjNjMzZWJlYzBhMjJkMmFmNWZmMWU0NGEzOTUzOWMyODgzODUwN2MzZDBkZTk2MjFkMTgzYWZl",
"friendlyId": "testthedatasource-take-4",
"type": "serviceApp",
"name": "TestTheDataSource Take 4",
"logo": "https://avatar-prod-us-east-2.webexcontent.com/Avtr~V1~ce861fba-6e2f-49f9-9a84-b354008fac9e/V1~48351afbb2d28d5c512dd2f63dff43a553cf0c50df1c0bbe1f101d9ecd592f2e~72855c8ae5594e13855778ebf179d0d2",
"description": "Test the Data Source Take 4",
"categories": [],
"tags": [],
"orgId": "Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi9jZTg2MWZiYS02ZTJmLTQ5ZjktOWE4NC1iMzU0MDA4ZmFjOWU",
"contactEmail": "adminaudit@schiffert.me",
"companyName": "Schiffert AG",
"scopes": [
"spark:kms",
"spark-admin:datasource_write",
"spark-admin:datasource_read"
],
"clientId": "Cc2171594ac633ebec0a22d2af5ff1e44a39539c28838507c3d0de9621d183afe",
"isFeatured": false,
"submissionStatus": "none",
"orgSubmissionStatus": "none",
"createdBy": "Y2lzY29zcGFyazovL3VzL1BFT1BMRS8xMTM4NWI3OS1hMDVmLTRkZWMtYWQyYy01YjAyZDc3YTQyZWU",
"created": "2024-10-16T16:54:41.201Z",
"validDomains": [
"schiffert.me",
"cisco.com",
"google.com"
],
"modified": "2024-10-16T16:54:41.201Z",
"entitlements": [
"spark-admin",
"spark",
"webex-squared"
],
"authorizationsList": [
{
"authorizerId": "Y2lzY29zcGFyazovL3VzL1BFT1BMRS8xMTM4NWI3OS1hMDVmLTRkZWMtYWQyYy01YjAyZDc3YTQyZWU",
"orgId": "Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi9jZTg2MWZiYS02ZTJmLTQ5ZjktOWE4NC1iMzU0MDA4ZmFjOWU",
"authorizationDate": "2024-10-16T21:48:54.056Z",
"orgName": "JP's Org",
"validDomains": [
"schiffert.me",
"cisco.com",
"google.com"
],
"dataSourceSchemaIds": [
"78efc775-dccb-45ca-9acf-989a4a59f788"
]
}
],
"authorizationsCount": 1,
"reserved": false,
"dataSourceSchemaIds": [
"78efc775-dccb-45ca-9acf-989a4a59f788"
]
}
At this stage you should have two tokens in hand; an access token and a refresh token. These are org-specific and will work only for registering a Data Source for the org where the admin authorized your Service App. If you want to work with several customers, you will have to store their tokens individually and each org admin must go through the authorization process in Control Hub. This means that each admin takes responsibility for the data exchange.
anchorRegister Your Data Source
anchorNow you can register the data source for your customer's organization using your Service App's access token. The data source entry includes:
- Schema: Details about the data to be exchanged. The schema must match one of the schemas that were preregistered during the Service App setup. The available schemas and their schema ids can be inspected during the Service App creation in the developer portal or retrieved from the REST API (
/v1/datasources/schemas
): - URL: Specifies where the data will be sent. The URL must belong to a domain registered with the Service App and is typically customer-specific, such as http://dataprovider.com/customers/customerA.
Additionally, the data source entry contains information for composing a JSON Web Signature (JWS) token used to authenticate requests when Webex invokes the URL. The token lifetime, set during registration, can range from 1 to 24 hours and must be refreshed before expiration to prevent system disruption. Webex will not attempt an outbound request with an expired token. To prevent replay attacks, regularly update the nonce.
Below is a sample payload for a data source registration.
{
"schemaId": [
"78efc775-dccb-45ca-9acf-989a4a59f788"
],
"url": "https://www.byods.com/service1",
"audience": "MedDocVirtualAgent",
"subject": "callAudioData",
"nonce": "123456",
"tokenLifeMinutes": "60"
}
A sample API response looks like the following:
{
"id": "7791dc84-989c-4903-a3b5-8c48c039dfb3",
"schemaId": "78efc775-dccb-45ca-9acf-989a4a59f788",
"orgId": "ce861fba-6e2f-49f9-9a84-b354008fac9e",
"applicationId": "Cc2171594ac633ebec0a22d2af5ff1e44a39539c28838507c3d0de9621d183afe",
"status": "active",
"jwsToken": "eyJraWQiOiIxOWFmMzYxYS0zYWI0LTU0NzEtYTViMC03MmQxODQyOTRjMmYiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJNeUFwcDMiLCJzdWIiOiJNeUFwcHNQdXJwb3NlMyIsImlzcyI6Imh0dHBzOlwvXC9pZGJyb2tlci53ZWJleC5jb21cL2lkYiIsImV4cCI6MTczMDM0MDgwNSwiY29tLmNpc2NvLmRhdGFzb3VyY2UudXJsIjoiaHR0cHM6XC9cL3NjaGlmZmVydC5tZVwvZHMzIiwiY29tLmNpc2NvLmRhdGFzb3VyY2Uuc2NoZW1hLnV1aWQiOiI3OGVmYzc3NS1kY2NiLTQ1Y2EtOWFjZi05ODlhNGE1OWY3ODgiLCJpYXQiOjE3MzAzMzcyMDUsImNvbS5jaXNjby5vcmcudXVpZCI6ImNlODYxZmJhLTZlMmYtNDlmOS05YTg0LWIzNTQwMDhmYWM5ZSIsImp0aSI6IjEyMzQ1NiJ9.k-gCBXS4yRiEmXWXhhO99MQNC_ZX1m6oK2mFSqloqf2mw1Ot2eRhSArElbQMEbudsj4vAvMj-fKuZUx78tjU4pKz6RzE8YkJJXzWNFA0OxCxLiiHwA0J6ayLH4JNPgcr71brNIt5ADuyXrZbrnXOETaJUQfFSU--MytYiAw-NnOXi9zWUDTNgzxOgNvXATnB1BW1cdYwgtQc1Hwlm__vPV7hPMUat1TjA2fqrZlsDAHWP5uExTIFDATFH211NeX5ItbmBd2GAjFg8T0YT0NTNpexMIiRlFe0_dObpn37YynKfbZOlJKADpQAbif4SlcNj5IT3sQNlienFYqr7UCaAQ",
"tokenExpiryTime": "2024-10-31T02:13:25.776Z",
"nonce": "123456",
"createdBy": "1a034299-8e07-49a9-b147-a4b86999b96c",
"createdAt": "2024-10-31T01:13:25.780Z",
"url": "https://www.byods.com/service1"
}
To temporarily disable a data source for a customer, update the data source with status
="disabled" and include an errorMessage
. Our API framework generally requires supplying the full payload for any update request, including the status
field, even for active
statuses.
The applicationId
field is the Service Apps identifier, also shown in the developer portal. The jwsToken
is the same that will be sent when the URL connection is established. We will see later how to verify its signature.
anchorVerify the JWS Token
anchorThe jwsToken
in the dataSources response is the JSON Web Signature (JWS) token that Webex sends when making a connection request. To inspect this token, you can use a tool like the JWT Debugger. When decoded, the token appears as follows:
Header
{
"kid": "19af361a-3ab4-5471-a5b0-72d184294c2f",
"typ": "JWT",
"alg": "RS256"
}
Payload
{
"aud": "MyApp3",
"sub": "MyAppsPurpose3",
"iss": "https://idbroker.webex.com/idb",
"exp": 1730340805,
"com.cisco.datasource.url": "https://schiffert.me/ds3",
"com.cisco.datasource.schema.uuid": "78efc775-dccb-45ca-9acf-989a4a59f788",
"iat": 1730337205,
"com.cisco.org.uuid": "ce861fba-6e2f-49f9-9a84-b354008fac9e",
"jti": "123456"
}
The key ID (kid
) is used to query the Cisco public key from the Cisco REST endpoint. This public key corresponds to the private key used to sign the JWS.
To validate the JWS token, you can refer to a Java example available here. This example uses the JOSE library, which supports multiple programming languages.
The unique Webex org id com.cisco.org.uuid
allows you to correlate the request to one of your customers.
anchorUpdate Your Data Source
anchorTo ensure uninterrupted data exchange, update your data source at regular intervals before the token expires. The maximum tokenLifetime is 1440 minutes (24 hours). Before the current token expires, update the data source with a new nonce
to maintain a valid token.
anchorConclusion and Next Steps
anchorIn conclusion, the "Bring Your Own Data Source" developer guide equips developers with the essential tools and knowledge to integrate third-party data sources with the Webex Suite and Webex Contact Center. By following the outlined steps, developers can effectively set up and configure a Service App, ensuring secure data exchange through the use of JSON Web Signature (JWS) tokens. Regular updates of the data source are crucial to maintaining seamless integration, preventing token expiration, and ensuring data integrity.
This guide also mentioned the complementary Bring Your Own Virtual Agent (BYOVA) framework for Contact Center use cases, expanding the possibilities for personalized customer interactions. By adhering to best practices and leveraging the provided examples, developers can enhance their applications' capabilities, offering robust and secure data interactions within the Webex ecosystem. The BYOVA builds on top of the BYODS concept with additional configuration. A complementary guide will walk you throug the steps.