Integrations & Authorization
Add features from third-party services to Webex or perform actions on behalf of another user with Integrations.
anchorWhat Are Integrations?
anchorIntegrations are how you request permission to invoke the Webex REST API on behalf of another Webex user. To do this in a secure way the API supports the OAuth 2 standard which allows third-party integrations to get a temporary access token for authenticating API calls instead of asking users for their password.
If you're sure that your integrations require authenticating on behalf of another Webex user, read on, we'll get you there in a few easy steps:
- Register your integration with Webex
- Request permission using an OAuth Grant Flow
- Exchange the resulting authorization code for an access token
- Use the access token to make your API calls
anchorRegistering Your Integration
anchorRegistering an integration with Webex is super easy. If you're logged in, select My Webex Apps from the menu under your avatar at the top of this page, click "Create a New App" then "Create an Integration" to start the wizard. You'll need to provide some basic information like your integration's name, description, and logo. This information should be user-facing since that's what they'll see in the permission dialog.
After successful registration you'll be taken to a different screen containing your integration's newly created clientID
and clientSecret
. The Client Secret will only be shown once so please copy and keep it safe!
Each Webex user account is limited to 20 integrations.
anchorRequesting Authorization
anchorThis step requires that your integration have a user interface capable of temporarily sending users to a Webex login page. For web apps this is typically done as a popup or redirect. For mobile apps consider using a "WebView" or equivalent on your mobile platform of choice. Webex currently supports the following OAuth flows for integrations:
- Authorization Code Flow and Authorization Code Flow with PKCE for devices with a web browser and keyboard. Authorization Code Flow with PKCE is the recommended flow as it provides the best security.
- Device Grant Flow is designed for smart TVs and other devices without a web browser or with limited input abilities.
Authorization Code Flow
In the Authorization Code Flow your app (the OAuth client) first obtains an authorization code from the authorization server endpoint, which it then exchanges for an access token from the access token endpoint.
The following steps illustrate the authorization code flow sequence. Also see Getting an Access Token with Authorization Code Flow for example requests and responses.
- User starts authorization flow (by clicking 'Login', for example).
- Your app directs the user to the authorization server endpoint with a set of URL query parameters, including
response_type=code
,clientID
,scope
,state
, and theredirect_uri
to which the authorization server will send the user-agent back once access is granted (or denied). - The OAuth server redirects the user's browser to the Webex authentication page where the user signs into their Webex account and accepts the requested scopes.
- In response, the OAuth server directs the user to the the specified
redirect_uri
. The server appends acode
property to the URI fragment whose value is the authorization code. - The client extracts the authorization code from the URI and sends it in a request to the acccess token endpoint, along with the integration's configured
clientID
andclientSecret
. - The server responds with a JSON object containing the ID token (and an access token and refresh token, depending on requested scopes).
Authorization Code Flow with PKCE
Proof Key for Code Exchange (PKCE) is an extension to the Authorization Code flow to prevent Cross-Site Request Forgery (CSRF) and authorization code injection attacks. PKCE adds the following parameters to the standard Authorization Code flow:
- code_verifier — A cryptographically random string used to correlate the authorization request to the token request. The code verifier must be between 43 and 128 characters in length and consist only of numbers (0-9), uppercase and lowercase letters (A-Z, a-z), hyphens (
-
), dots (.
), underscores (_
), and tildes (~
). - code_challenge — A base64-encoded SHA-256 hash of
code_verifier
value (or the same value as thecode_verifier
, depending on thecode_challenge_method
used. The Webex OAuth server decrypts this value and uses it to verify that the authorization and access token requests are coming from the same client. - code_challenge_method — The transformation method used to derive the code challenge. Supported values are S256 (for SHA-256 transforms) and plain (if no transform has been applied).
Apps are encouraged to prefer the SHA-256 code challenge method over plain.
For example, if code_challenge_method
is S256
the following pseudo-code shows how code_challenge
is computed from code_verifier
:
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
If code_challenge_method
is plain
then code_challenge
is equal to code_verifier
:
code_challenge = code_verifier
For example, below is an example request to initiate the Authorization Code flow with PKCE. Before making the call to /v1/authorize
your app first needs to generate a code verifier from which the code challenge is derived. In this example, the code_challenge
value (h5REeLdS914fH3VaOKytjx5VNzHOCKHKYSRbzE0k6BM
) was generated using the SHA256 hashing algorithm indicated by S256
as the value for code_challenge_method
:
GET /v1/authorize?redirect_uri=https%3A%2F%2Fwww.example.com%2Fauth
&scope=meeting%3Aschedules_read
&client_id=C7480d953df4816dfe7e1b50fbac7f3b8da6b58efec1846ba47ab357b8ace6cc4
&response_type=code
&code_challenge=h5REeLdS914fH3VaOKytjx5VNzHOCKHKYSRbzE0k6BM
&code_challenge_method=S256 HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: webexapis.com
Device Grant Flow
The Device Flow enables OAuth clients devices without a web browser or with limited input ability (smart TVs or media consoles, for example) to obtain user authorization to access protected resources. Instead of interacting directly with the end user's user agent (web browser), the device client instructs the end user to use another computer or device and connect to the authorization server to approve the access request. Clients poll the authorization server repeatedly until the end user completes the approval process.
For a complete sample that illustrates the Device Grant Flow from end to end, see the following GitHub repo, webex-device-oauth-sample.
The following outlines the process for using Device Grant Flow. For details see Getting an Access Token with Device Grant Flow.
- The app running on the device initiates a request to the Device Authorization Endpoint, passing
clientID
and scopes for the associated Webex integration. - The server responds with device code, user code, and two verification URLs, one of which includes a hashed version of the user code.
- Device presents the verification URI and user code to the user, or equivalent QR code. User starts authorization process on a mobile device or laptop.
- Device begins polling the Device Token Endpoint. The endpoint returns
428 Precondition Required
until the user has finished the authorization process. - Once the user successfully completes the authorization process on another device the next request to the device token endpoint returns a
200 OK
and a JSON object with the access and refresh tokens.
anchorWebex OAuth Authorization and Token Endpoints
anchorThe following outlines how to make a request to the following endpoints for an Authorization Code, and Access Tokens:
Authorization Endpoint
Your app initiates an OAuth 2.0 flow to obtain an access token. The value of the request's response_type
query parameter determines which OAuth grant flow is used:
GET https://webexapis.com/v1/authorize
To obtain an ID token:
- The
response_type
parameter must includecode
- The request's
scope
request parameter must containopenid
Authorization
This endpoint requires no authorization.
Authorization Request
Requests to the authorization endpoint have the following query parameters:
Parameter Name | Type | Required | Description |
---|---|---|---|
response_type | string | yes | Type of grant, which determines the authorization flow. Set to code to use the Authorization Code flow flow. Set to id_token , token or id_token token to use the Implicit Flow. |
client_id | string | yes | Client ID of your Webex integration. |
redirect_uri | string | no | URI where the user's browser is redirected after they complete the authentication process. If the integration has multiple registered redirect URIs, this parameter is required and the redirect_uri in the request must match one of the registered redirect URIs. May be omitted from the request if the integration has a single registered redirect URI. |
scope | string | yes | URL-encoded list of requested data access scopes and/or OpenID Connect scopes separated by spaces. Specified data access scopes must be registered with your Webex integration. (OpenID Connect scopes do not need to be registered.) If scope is missing from the request the server will return an "invalid scope" error. |
state | string | no | Any arbitrary string. Its purpose is to prevent Cross-Site Request Forgery attacks by providing a way for your app maintain state between your app's authorization request and the server's response. The server returns the same value you specify as a name=value pair in the URL fragment (#) of the redirect URI. |
code_challenge | string | no | Proof Key for Code Exchange (PKCE) code challenge used with Authorization Code flows to prevent Cross-Site Request Forgery attacks. See Implementing PKCE with Authorization Code Flow. |
code_challenge_method | string | no | Proof Key for Code Exchange (PKCE) code challenge method used with Authorization Code flows to prevent Cross-Site Request Forgery attacks. See Implementing PKCE with Authorization Code Flow. |
Below is a sample request for an authorization code:
GET /v1/authorize?response_type=code
&client_id=<CLIENT_ID>
&redirect_uri=https%3A%2F%2Fapp.example.com%3A9443%2Fauth
&scope=openid%20profile%20email
&state=random-string HTTP/1.1
Host: webexapis.com
Authorization Response
The response to the authorization endpoint depends on the response_type
specified in the request.
If the
response_type
wascode
then the Authorization Code flow is inititated and the response contains acode
URL query parameter that can be exchanged for an ID token, access token, or both at the Access Token endpoint:https://www.example.com/auth?code=<AUTHORIZATION_CODE>&state=<STATE_FROM_REQUEST>
If the
response_type
was one ofid_token
,token
, orid token token
, thenid_token
and/oraccess_token
properties are appended to the redirect URI's hash fragment. For example, the following shows a response for a request withresponse_type=id_token
:https://www.example.com/redirect/#id_token=<ID_TOKEN>&state=<STATE_FROM_REQUEST>
The following table lists the possible parameters included in the response to a request to /v1/authorize
:
Parameter Name | Description |
---|---|
access_token | Access token for making API calls. Included if the response_type request parameter included token . |
code | Authorization code used to obtain an access token from the access token endpoint. Included if response_type was set to code in the request. |
expires_in | Number of seconds for which the token is valid. Included if the response_type request parameter included token . |
id_token | Base64-encoded and signed JSON Web Token (JWT). Included if the response_type request parameter included id_token and the scope request parameter included openid . |
token_type | Included if the response_type request parameter included token . Value is always "Bearer". |
state | Included if the state parameter was in the request. The same value sent in the request should be in the response. Apps should verify that the the values are the same. |
The following response is for a request with response_type=id_token token
, so the URL contains both id_token
and access_token
fields (line breaks added for readability):
http://127.0.0.1:8080/#id_token=<ID_TOKEN>
&access_token=<ACCESS_TOKEN>
&token_type=Bearer
&expires_in=<SECONDS_TO_EXPIRE>
&state=<STATE_FROM_REQUEST>
Device Authorization Endpoint
The device token authorization endpoint is used to initiate an authorization request on input-constrained client devices such as smart TVs or set-top boxes. It returns a URL where the user can authenticate with Webex and approve the authorization request a user code returned in the response:
POST https://webexapis.com/v1/device/authorize
The following redirect URIs must be added to the Webex integration associated with the clientID
used in the request.
- https://oauth-helper-a.wbx2.com/helperservice/v1/actions/device/callback
- https://oauth-helper-r.wbx2.com/helperservice/v1/actions/device/callback
- https://oauth-helper-k.wbx2.com/helperservice/v1/actions/device/callback
Authorization
This endpoint requires no authorization.
Device Authorization Request
The request body is a URL-encoded string with the following parameters:
Parameter Name | Type | Required | Description |
---|---|---|---|
client_id | string | yes | Webex integration clientID . The integration must have the OAuth helper services URLs added as redirect URLs. |
scope | string | yes | List of requested scopes separated by spaces. |
POST /v1/device/authorize HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: webexapis.com
Content-Length: 106
client_id=C65cbd0361e76a1c07a4f01bf67fffb8b863103dffaa809d3bf752b0d15144ff1&scope=meeting%3Aschedules_read
Device Authorization Response
The following are possible response codes for the device authorization response:
Response Code | Description |
---|---|
200 OK | The request was successfully processed, see the response body for results. |
400 Bad Request | An invalid client_id or invalid scope parameter was provided in the request. |
429 Too many requests | The client has made too many requests. The Retry-After header is included, indicating how long the client should wait before making another request. |
A successful response contains a JSON object that has the following properties:
Parameter Name | |
---|---|
device_code | An unique device code assigned to this device authorization request. |
expires_in | Lifetime in seconds for device_code and user_code response fields. |
user_code | End user's unique, six digit verification code. |
verification_uri | A verification URL (https://oauth-helper-r.wbx2.com/verify , for example) that the user navigates to on a separate device and enters the user_code from the response. |
verification_uri_complete | A verification URL that has a hashed version of the user_code response variable embedded (https://oauth-helper-r.wbx2.com/verify?userCode=0d3955d418be1de30ef281aaf37939515c8d697b7393d6eda16423c7002497b1 , for example). Apps can use this URL to generate a QR code to present to the user for an easier sign in experience. |
interval | Minimum amount of time in seconds that your device should wait between polling requests to Device Token Endpoint. |
Examples
Successful response
HTTP/1.1 200 OK
Content-Type: application/json
{
"device_code": "5d5cf602-f0dd-49d5-bfd3-915267e4fbe0",
"expires_in": 300,
"user_code": "729703",
"verification_uri": "https://oauth-helper-r.wbx2.com/verify",
"verification_uri_complete": "https://oauth-helper-r.wbx2.com/verify?userCode=6587b053970a656c29500e6bced0c1c59290a743ad7e34af474a65085860de57",
"interval": 2
}
Error Response due to Invalid Client ID
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"message": "The request could not be understood by the server due to malformed syntax.",
"errors": [{ "description": "Client Id is invalid" }],
"trackingId": "ROUTER_62E068B0-FA5E-01BB-1501-0AFE2B641501"
}
Access Token Endpoint
The token endpoint is used to exchange an authorization code obtained from a previous call to the Authorization endpoint for an ID token, access token and refresh token.
ID tokens returned by this endpoint only contain claims for the openid scope, regardless of what other OpenID Connect scopes were in the original Device Authorization request. To get user claims for all requested OpenID Connect scopes (the "email" or "profile" scopes) you call the UserInfo Endpoint with the returned access token.
POST https://webexapis.com/v1/access_token
Authorization
Requests to the access token endpoint must be authorized either with Basic authentication, or by passing clientID
and clientSecret
in the request body. To use Basic authentication, add an Authorization
HTTP header whose value is Basic <credentials>
, where <credentials>
are a Base64-encoding of clientID
and clientSecret
separated by a colon (e.g. Base64("<client-id>:<client-secret>")
), for example:
Authorization: Basic ABC1Y2JkMDM2MWU3NmExYzA3YTRmMDFiZjY3ZmZmYjhiODYzMTAzZGZmYWE4MDlkM2JmNzUyYjBkMTUxNDRmZjE6YTcwZjQ0N2UyMzg1Mzg1ZTdkOWExN2Y1ZDE0ZTc3NTAyOTRiOWZhZTE0YzA1NDlkMjNhYmZmY2MxMDEzMjdiYg==
See example requests below.
Access Token Request
The body sent in the POST request is a URL-encoded string that contains the following parameters:
Parameter Name | Type | Required | |
---|---|---|---|
client_id | string | yes | Webex integration client ID. |
client_secret | string | yes | Webex integration client Secret. |
code | string | yes | Authorization code obtained by a previous call to the authorization endpoint. |
code_verifier | string | no | PKCE code verifier, required if the request to the authorization endpoint included code_challenge and code_challenge_method parameters. Must be between 43-128 characters and consist only of unreserved characters. See Authorization Code Flow with Proof Key for Code Exchange for more information. |
grant_type | string | yes | Must be set to "authorization_code". |
redirect_uri | string | yes | Valid URI. Must be the same as the redirect_uri specified in the authorization code request. |
user_info | string | no | JSON object with additional requested information about the user or resource (for example {'device_id': 'xxxxxxxx', 'device_name': 'Home-DX80'} ). |
The following is an example request for an access token that contains the client ID and secret in the request body:
POST /v1/access_token HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: webexapis.com
grant_type=authorization_code&code=M2ZmNjdlM2MtNzQzNS00MjY1LTlhMzUtZDcxNWQxNDEyNWRhMTAzZGY1NmMtMjM0_PF84_1eb65fdf-9643-417f-9974-ad72cae0e10f&client_id=C65cbd0361e76a1c07a4f01bf67fffb8b863103dffaa809d3bf752b0d15144ff1&redirect_uri=https%3A%2F%2Fwww.example.com%2Fauth&client_secret=a70f447e2385385e7d9a17f5d14e7750294b9fae14c0549d23abffcc101327bb
The following is an equivalent request that uses Basic authentication instead:
POST /v1/access_token HTTP/1.1
Authorization: Basic QzY1Y2JkMDM2MWU3NmExYzA3YTRmMDFiZjY3ZmZmYjhiODYzMTAzZGZmYWE4MDlkM2JmNzUyYjBkMTUxNDRmZjE6YTcwZjQ0N2UyMzg1Mzg1ZTdkOWExN2Y1ZDE0ZTc3NTAyOTRiOWZhZTE0YzA1NDlkMjNhYmZmY2MxMDEzMjdiYg==
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: webexapis.com
grant_type=authorization_code&code=ZDYxYWZiYmMtYTU0NC00NTQ2LTgwMGEtZjZhNWJjOWQxNGViYzRmMDExNDMtMzE0_PF84_1eb65fdf-9643-417f-9974-ad72cae0e10f&redirect_uri=https%3A%2F%2Fwww.example.com%2Fauth
Access Token Response
Successful responses will be accompanied with a body in JSON format with the following properties:
Property Name | Type | Description |
---|---|---|
expires_in | long | The lifetime in seconds of the access token. For example, the value '5999' denotes that the access token will expire in 5999 seconds from the time the response was generated. |
token_type | string | The type of access token, currently only "Bearer" is supported. |
refresh_token | string | Refresh token for obtaining a new access token. |
refresh_token_expires_in | long | The lifetime in seconds of the refresh token. |
access_token | string | API access token with scopes specified in initial request to authorization server. |
id_token | string | OpenID Connect ID token, only present if the original request to the authorization server contained the openid scope. |
Below is an example JSON response body for a successful request for an access token:
{
"access_token": "NjlhN...",
"expires_in": 1209599,
"refresh_token": "Nzc0N...",
"refresh_token_expires_in": 7775999,
"token_type": "Bearer"
}
Device Token Endpoint
Device clients use this endpoint to poll for access and refresh tokens after presenting the verification URL and user code (or equivalent QR code) to the user. The user opens the verification URL and enters the user code (or uses the provided QR code) to authorize the request. Until the user has finished the authorization process the request will return Once the user has completed the authentication using the provided Once the user has authenticated with Webex and granted authorization on another device, the next polling request will be successful and the endpoint will return access and refresh tokens with the requested scopes:
POST https://webexapis.com/v1/device/token
Authorization
This endpoint requires Basic authentication to authenticate the request. The request must contain an Authorization <credentials>
, where <credentials>
is a Base64-encoding of your integration's clientID
and clientSecret
separated by a colon:
Authorization: Basic <credentials>
Device Token Request
The body sent in the POST request is a URL-encoded string that contains the following parameters:
Parameter Name | Type | Required | Description |
---|---|---|---|
grant_type | string | yes | Value must be set to urn:ietf:params:oauth:grant-type:device_code. |
device_code | string | yes | Valid device code received from the Device Authorization Endpoint. |
client_id | string | yes | Must match clientID used in previous call to the Device Authorization Endpoint. |
self_contained_token | string | no | Set to true to get a self-contained access token. Self-contained access tokens may be significantly quicker and more efficient as the API server doesn't need to look up authorization information for each request. |
user_info | string | no | Additional information about the user or resource in JSON-formatted string, for example: {"device_id": "xxxxxxxx", "device_name": "Home-DX80"} . |
Example request:
POST /v1/device/token HTTP/1.1
Authorization: Basic QzY1Y2JkMDM2MWU3NmExYzA3YTRmMDFiZjY3ZmZmYjhiODYzMTAzZGZmYWE4MDlkM2JmNzUyYjBkMTUxNDRmZjE6OTMzNDc0ZWQ2NjkxN2QxZWUxMThhMjE4NzBkZDg3ZWMzYzQ5YTkwMmY2MDFiOTYwZDViZDE4MGNjMGY5NDI4Ng==
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: webexapis.com
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=9c697e89-552c-4b27-bbfc-57a831cdf5fe&client_id=C65cbd0361e76a1c07a4f01bf67fffb8b863103dffaa809d3bf752b0d15144ff1
Device Token Response
The following are possible response codes for the device token response:
Response Code | Description |
---|---|
200 OK | The request was successfully processed, see the response body for results. |
400 Bad Request | An invalid clientID or invalid scope parameter was provided in the request. Possible error messages:
|
428 Precondition Required | The authorization request is still pending as the end user hasn't yet completed the authenticating with Webex and approving the request. The device client should poll again after |
The response is JSON object with the following properties:
Property Name | Type | Description |
---|---|---|
scope | string | The scopes associated with the token. |
expires_in | long | The lifetime in seconds of the access token. For example, the value '5999' denotes that the access token will expire in 5999 seconds from the time the response was generated. |
token_type | string | The type of access token, currently only "Bearer" is supported Bearer. |
refresh_token | string | Refresh token for obtaining a new access token. |
refresh_token_expires_in | long | The lifetime in seconds of the refresh token. |
access_token | string | API access token. |
The following is an example successful response:
{
"scope": "meeting:schedules_read",
"expires_in": 64799,
"token_type": "Bearer",
"refresh_token": "MjZmMzcyZWUtMzI2MS00MmE4LTgyZWMtYTVlMWIxYzBjZjhiODJmYzViOTItMGFi_PF84_1eb65fdf-9643-417f-9974-ad72cae0e10f",
"access_token": "eyJhbGciOiJSUzI1NiJ9.eyJjbHVzdGVyIjoiUEY4NCIsInByaXZhdGUiOiJleUpqZEhraU9pSktWMVFpTENKbGJtTWlPaUpCTVRJNFEwSkRMVWhUTWpVMklpd2lZV3huSWpvaVpHbHlJbjAuLll3eWhjUmZ2LTRQU3NlVHdvMkdfQ0EuNmUtcndTYzVqLXBaZ1V1bjgyQUozeVVYY1VhWmxXNm93Nnh4QTZhZWpIY2lxR0lTZEFCUURraS10RDNsWEtSMlZDMENkc1ZQQWx<rest truncated>",
"refresh_token_expires_in": 7697037
}
anchorScopes
anchorScopes define the level of access that your integration requires. The following is a complete list of scopes and their user-facing descriptions as shown in the permission dialog.
meeting:schedules_read
meeting:schedules_write
meeting:recordings_read
meeting:recordings_write
meeting:preferences_read
meeting:preferences_write
meeting:controls_read
meeting:controls_write
meeting:participants_read
meeting:participants_write
meeting:admin_participants_read
spark-admin:telephony_config_read
spark-admin:telephony_config_write
meeting:admin_schedule_read
meeting:admin_schedule_write
meeting:admin_recordings_read
meeting:admin_recordings_write
meeting:admin_transcripts_read
meeting:admin_preferences_write
meeting:admin_preferences_read
spark-compliance:meetings_read
meeting:transcripts_read
spark-compliance:meetings_write
spark-admin:workspace_locations_read
spark-admin:workspace_locations_write
spark-admin:workspace_metrics_read
identity:contacts_rw
identity:contacts_read
spark:all
spark:webrtc_calling
spark:calls_read
spark:devices_read
spark:devices_write
spark:memberships_read
spark:memberships_write
spark:messages_read
spark:messages_write
spark:organizations_read
spark:people_read
spark:places_read
spark:places_write
spark:rooms_read
spark:rooms_write
spark:team_memberships_read
spark:team_memberships_write
spark:teams_read
spark:teams_write
spark-compliance:recordings_read
spark-compliance:recordings_write
spark:xapi_statuses
spark:xapi_commands
spark:xsi
spark-admin:devices_read
spark-admin:devices_write
spark-admin:licenses_read
spark-admin:organizations_read
spark-admin:people_read
spark-admin:people_write
spark-admin:places_read
spark-admin:places_write
spark-admin:resource_group_memberships_read
spark-admin:resource_group_memberships_write
spark-admin:resource_groups_read
spark-admin:roles_read
spark-admin:call_qualities_read
spark-admin:workspaces_read
spark-admin:wholesale_sub_partners_read
spark-admin:wholesale_sub_partners_write
spark-compliance:events_read
spark-compliance:memberships_read
spark-compliance:memberships_write
spark-compliance:messages_read
spark-compliance:messages_write
spark-compliance:rooms_read
spark-compliance:rooms_write
spark-compliance:team_memberships_read
spark-compliance:team_memberships_write
spark-compliance:teams_read
spark-admin:broadworks_enterprises_read
identity:placeonetimepassword_create
Identity:one_time_password
spark-compliance:webhooks_write
spark-compliance:webhooks_read
spark:calls_write
spark-admin:hybrid_clusters_read
spark-admin:hybrid_connectors_read
spark-admin:broadworks_subscribers_read
spark-admin:broadworks_subscribers_write
audit:events_read
spark-admin:wholesale_customers_write
spark-admin:wholesale_customers_read
spark-admin:wholesale_subscribers_write
spark-admin:wholesale_subscribers_read
cjp:user
cjp:config_read
cjp:config_write
cjp:config
identity:groups_rw
identity:groups_read
guest-issuer:read
guest-issuer:write
spark:telephony_config_read
spark:telephony_config_write
spark-admin:locations_write
identity:tokens_read
identity:tokens_write
meeting:admin_config_read
meeting:admin_config_write
spark-admin:locations_read
spark-admin:datasource_write
spark-admin:datasource_read
spark:applications_token
application:webhooks_write
application:webhooks_read
spark-admin:metrics_read
guest-meeting:rw
webexsquare:get_conversation
dedicated-instance-uc:admin_perfmon_read
spark-admin:recordings_read
spark-admin:recordings_write
spark:recordings_read
spark:recordings_write
identity:organizations_read
identity:organizations_rw
spark-admin:telephony_pstn_write
spark-admin:telephony_pstn_read
spark-admin:broadworks_enterprises_write
Scopes that begin with spark-admin
can only be used by users with administrative access to an organization. Requesting these scopes during a grant flow will not give non-admin users access to administrative functions.
The spark-compliance
scopes can only be used by an organization's compliance officers. See the Compliance Guide for more information.
The spark:all
scope grants access to certain Webex account features that are not granted via the other user-level scopes. Applications which use the Webex SDKs for calling features may require this scope. Most other applications will not need to use this scope. Consult the SDK documentation for information about whether your application will need to use this scope.
As a general best practice, your integration should request only the scope, or scopes, it needs. For example, if you are creating an integration that notifies users of updates in a third-party service, and never responds to any commands, we recommend using only the spark:messages_write
scope.
KMS Scope
After registering an integration, it will include the scopes you selected along with an additional scope: spark:kms
. This scope is required to give your integration permission to interact with encrypted content (such as messages). For convenience, the scope is included in the integrations's scope list in the example OAuth Authorization URL on the integration's application detail page. If you don't use the example URL, be sure to include the scope when creating authorization URLs for your integration.
State
The state
parameter is used to verify that the response from grant flow has not been tampered with along the way. It is recommended that your integration set this to a value that is verifiable once the user gives permission and the web browser is sent to your redirect_uri
. A second use for this parameter is to encode basic state information like an internal user ID or the URL of the last page they were on before entering the grant flow.
anchorGetting an Access Token
anchorIf the user granted permission to your integration, the Webex REST API will redirect the user's web browser to the redirect_uri
you specified when entering the grant flow. The request to the redirect URL will contain a code parameter in the query string like so:
http://your-server.com/auth?code=YjAzYzgyNDYtZTE3YS00OWZkLTg2YTgtNDc3Zjg4YzFiZDlkNTRlN2FhMjMtYzUz
Your integration will then need to exchange this authorization code for an access token that can be used to invoke the APIs. To do this your app will need to perform an HTTP POST to the following URL with a standard set of OAuth parameters in the body of the POST request. This endpoint will only accept a message body encoded with the application/x-www-form-urlencoded
content type.
https://webexapis.com/v1/access_token
The required parameters are:
Parameter | Value |
---|---|
grant_type | This should be set to "authorization_code". |
client_id | Issued when creating your integration. |
client_secret | Remember this guy? You kept it safe somewhere when creating your integration. |
code | The authorization code from the previous step. |
redirect_uri | Must match the one used in the previous step. |
An example curl request for sending form data would look like below.
curl -X POST https://webexapis.com/v1/access_token -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=authorization_code&client_id=Cda0958&client_secret=11db688edb1fafb0a13e&code=OTQ5NzA0ZmUtZzU2Zi00NGJkLTliNWYtZmU0NDlhN2Y0Y2I4ZWRhNDQ3NmItMWIx_PF84_ce861fba-6e2f-49f9-9a84-b354008fac9e&state=set_state_here&redirect_uri=http://localhost:8081/authorization-code'
The Webex REST API will then respond with JSON containing an access token and a refresh token, as shown in the example below. Expiration times are provided in seconds:
{
"access_token":"YmVmODgxPF84_ce861fba-6e2f-49f9-9a84-b354008fac9e",
"expires_in":1209599,
"refresh_token":"YjJhMWQiOGI1MGMw_PF84_ce861fba-6e2f-49f9-9a84-b354008fac9e",
"refresh_token_expires_in":7775999,
"token_type":"Bearer",
"scope":"spark:all spark:kms"
}
After the access token expires, using it to make a request from the API will result in an HTTP 401 "Invalid Token Error" response, such as:
{
"message": "The request requires a valid access token set in the Authorization request header.",
"errors": [
{
"description": "The request requires a valid access token set in the Authorization request header."
}
],
"trackingId": "API_12345678-90AB-CDEF-1234-567890ABCDEF"
}
At this point, you should use the refresh token to generate a new access token from the authorization server.
anchorUsing the Refresh Token
anchorUsing access tokens that are short-lived and requiring that they periodically be refreshed helps to keep data secure. If the access token is ever compromised, the attacker will have a limited time in which to use it. If a refresh token is compromised, it is useless to the attacker because the client ID and secret are also required to obtain a new access token.
To refresh the access token, issue a POST to https://webexapis.com/v1/access_token
in form of a application/x-www-form-urlencoded request with the following fields in the POST body:
Field | Value |
---|---|
grant_type | This should be set to "refresh_token". |
client_id | Issued when creating your integration. |
client_secret | Remember this guy? You kept it safe somewhere when creating your integration. |
refresh_token | The refresh token you received from the previous step. |
curl -X POST https://webexapis.com/v1/access_token -H "Content-type: application/x-www-form-urlencoded" -d 'grant_type=refresh_token&refresh_token=ZWQzZWI0ZDEtNTcwNi00OTNkLzEtZTIz_PF84_ce861fba-6e2f-49f9-9a84-b354008fac9e&client_id=Cda095afad5c12380bb&client_secret=2af32e36cc892ef3f9ec71d849cb29eb5ab3c21'
The Webex REST API will then respond with JSON containing a new access token. Generating a new access token automatically renews the lifetime of your refresh token. Expiration times are indicated in seconds:
{
"access_token":"OGQ1MGQ2OTUtNW008fac9e",
"expires_in":1209599,
"refresh_token":"ZWQzZWI0ZDEtNTcwNi00OT49f9-9a84-b354008fac9e",
"refresh_token_expires_in":7773103,
"token_type":"Bearer",
"scope":"spark:all spark:kms"
}
Refreshing an access token before its expiration date will not cause the original access token to expire.
After the refresh token expires, using it to request a new access token from the API will result in an HTTP 400 "Invalid Request" response, such as:
{
"message": "The refresh token provided is expired, revoked, malformed, or invalid.",
"errors": [
{
"description": "The refresh token provided is expired, revoked, malformed, or invalid."
}
],
"trackingId": "API_12345678-90AB-CDEF-1234-567890ABCDEF"
}
anchorAccess Token Invalidation
anchorAn access token that's been issued to your app may be invalidated as a result of changes to a user's account. This includes, but is not limited to, the following scenarios:
- A user's account access changes as a result of updates to their email address or password.
- A user's Webex organization administrator deactivates and reactivates their account.
anchorInvoking the Webex REST API
anchorAuthenticating with another user's access token works just like your developer token; supply the token in an Authorization
header like so:
GET /rooms
Authorization: Bearer THE_ACCESS_TOKEN
Accept: application/json
or in cURL it would be
curl https://webexapis.com/v1/rooms \
-H "Authorization: Bearer THE_ACCESS_TOKEN" \
-H "Accept: application/json"
The Bearer
part is important as it instructs the API that this is an OAuth token instead of HTTP Basic Auth.
With the API, you can perform actions as the user such as sending a message with an interactive card to someone. To respond to events, you'll need to configure webhooks. Webhooks will let your app know when an activity has occurred so you can take action. Check out the Webhooks Guide for more information about configuring webhooks.
With cards, you can give your users even more ways to interact with your integration or service, right in the Webex clients. See the Buttons and Cards Guide for more information.