Webex Admin
Authentication
In Getting Started we showed you just how easy it is to send messages using your own access token. But what if your app needs to send messages on behalf of someone else? That's where Integrations and OAuth come in.
Keep in mind that you don't need to register an integration to explore the APIs. The best way to learn the APIs is to use your own personal access token to create rooms, play with messages, etc. If you're sure that your integrations require authenticating on behalf of another Webex user, read on.
anchorWhat are Integrations?
anchorIntegrations are how you request permission to invoke Webex APIs on behalf of another user. To do this in a secure way Webex supports the OAuth 2 standard which allows 3rd party integrations to get a temporary access token for authenticating API calls instead of asking users for their password.
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 Client ID and Client Secret. The Client Secret will only be shown once so please copy and keep it safe!
anchorRequesting Permission
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.
To kick off the flow send your user to the following URL along with a standard set of OAuth query parameters:
https://webexapis.com/v1/authorize
The required query parameters are:
response_type | Must be set to "code" |
client_id | Issued when creating your app |
redirect_uri | Must match one of the URIs provided during integration registration |
scope | A space-separated list of scopes being requested by your integration (see below) |
state | A unique string that will be passed back to your integration upon completion (see below) |
After logging in users will see a grant dialog like this one:

Scopes
Scopes 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.
spark-admin:events_readspark-compliance:events_readspark-admin:messages_writespark-compliance:messages_writespark-admin:messages_readspark-compliance:messages_readspark-compliance:recordings_writespark-compliance:recordings_readspark-compliance:memberships_writespark-compliance:memberships_readspark-compliance:meetings_writespark-compliance:meetings_readspark-compliance:rooms_writespark-compliance:rooms_readspark-compliance:teams_readspark-compliance:team_memberships_writespark-compliance:team_memberships_readspark-compliance:webhooks_writespark-compliance:webhooks_readaudit:events_readspark-admin:recordings_writespark-admin:recordings_readspark-admin:reports_writespark-admin:reports_readspark-admin:broadworks_subscribers_writespark-admin:broadworks_subscribers_readspark-admin:broadworks_enterprises_writespark-admin:broadworks_enterprises_readspark-admin:wholesale_billing_reports_writespark-admin:wholesale_billing_reports_readspark-admin:wholesale_sub_partners_writespark-admin:wholesale_sub_partners_readspark-admin:wholesale_customers_writespark-admin:wholesale_customers_readspark-admin:wholesale_subscribers_writespark-admin:wholesale_subscribers_readspark-admin:people_writespark-admin:people_readspark-admin:licenses_readspark-admin:roles_readspark-admin:telephony_config_writespark-admin:telephony_config_readspark-admin:telephony_pstn_writespark-admin:telephony_pstn_readspark-admin:workspaces_readspark-admin:workspace_locations_writespark-admin:workspace_locations_readspark-admin:workspace_metrics_readspark-admin:places_writespark-admin:places_readspark-admin:locations_writespark-admin:locations_readspark-admin:devices_writespark-admin:devices_readspark-admin:organizations_readspark-admin:resource_groups_readidentity:contacts_readspark-admin:resource_group_memberships_writespark-admin:resource_group_memberships_readspark-admin:call_qualities_readspark-admin:hybrid_clusters_readspark-admin:hybrid_connectors_readidentity:tokens_writeidentity:tokens_readidentity:groups_rwidentity:groups_readidentity:organizations_rwidentity:organizations_readidentity:contacts_rwIdentity:one_time_passwordidentity:placeonetimepassword_createcjp:configcjp:config_writecjp:config_readcjp:usermeeting:admin_recordings_writemeeting:admin_recordings_readmeeting:admin_transcripts_readmeeting:admin_participants_readmeeting:admin_schedule_writemeeting:admin_schedule_readmeeting:admin_preferences_writemeeting:admin_preferences_readmeeting:admin_config_writemeeting:admin_config_readmeeting:recordings_writemeeting:recordings_readmeeting:transcripts_readmeeting:controls_writemeeting:controls_readmeeting:participants_writemeeting:participants_readmeeting:schedules_writemeeting:schedules_readmeeting:preferences_writemeeting:preferences_readspark:recordings_writespark:recordings_readspark:allspark:applications_tokenspark:messages_writespark:messages_readspark:memberships_writespark:memberships_readspark:xsispark:xapi_statusesspark:xapi_commandsspark:calls_writespark:calls_readspark:webrtc_callingspark:people_readspark:rooms_writespark:rooms_readspark:teams_writespark:teams_readspark:team_memberships_writespark:team_memberships_readspark:devices_writespark:devices_readspark:telephony_config_writespark:telephony_config_readspark:places_writespark:places_readspark:organizations_readapplication:webhooks_writeapplication:webhooks_readwxc-dedicateduc:admin_perfmon_readguest-issuer:readguest-issuer:writecjds:admin_org_readcjds:admin_org_writecloud-contact-center:pod_convspark-admin:datasource_readspark-admin:datasource_writespark-admin:metrics_readguest-meeting:rwanchorGetting an Access Token
anchorIf the user granted permission to your integration, Webex 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. This endpoint will only accept an x-www-form-urlencoded body.
https://webexapis.com/v1/access_token
The required parameters are:
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 |
Webex will then respond with JSON containing an Access Token that's good for 14 days and a Refresh Token that expires in 90 days, as shown in the example below:
{
"access_token":"ZDI3MGEyYzQtNmFlNS00NDNhLWFlNzAtZGVjNjE0MGU1OGZmZWNmZDEwN2ItYTU3",
"expires_in":1209600, //seconds
"refresh_token":"MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTEyMzQ1Njc4",
"refresh_token_expires_in":7776000 //seconds
}
After the access token expires, using it to make a request from the API will result in an “Invalid Token Error.” At this point, you should use the refresh token to generate a new access token from the authorization server.
Using the Refresh Token
Using 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 tohttps://webexapis.com/v1/access_tokenwith the following fields:
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 |
Webex will then respond with JSON containing a new Access Token. Generating a new Access Token automatically renews the lifetime of your Refresh Token.
Note: Refreshing an access token before its expiration date will not cause the original access token to expire.
anchorInvoking the Webex APIs
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 Webex that this is an OAuth token instead of HTTP Basic Auth.