Cisco Webex Integration Setup

Prerequisites

  • A Webex organization and a full administrator account in Control Hub to authorize the connection — the scopes ZLH requests are admin scopes, and every sync runs with that administrator's access
  • A sign-in at developer.webex.com (any Webex account) to create the integration
  • ZLH running with a reachable callback URL

Step 1: Create an Integration on the Webex Developer Portal

  1. Sign in at developer.webex.com, open your avatar menu and choose My Webex Apps
  2. Click Create a New App, then Create an Integration
  3. Fill in:
    • Integration name: ZombieLicenseHunter
    • Contact email, icon and description as you prefer
    • Redirect URI(s): {YOUR_ZLH_BASE_URL}/integrations/webex/callback
    • Scopes: tick spark-admin:people_read and spark-admin:licenses_read
  4. Click Add Integration
  5. Copy the Client ID and the Client Secret — the secret is shown only once; regenerate it from the integration's page if you lose it

Step 2: ZLH-Side Values

  • The Redirect URI must be exactly {YOUR_ZLH_BASE_URL}/integrations/webex/callback — protocol, host, port and path
  • Scopes requested: spark-admin:people_read spark-admin:licenses_read. Self-hosted deployments can override them with WEBEX_SCOPES; the integration on the developer portal must have every requested scope ticked
  • The Client ID and Client Secret are entered per integration in the UI, not in environment variables

Step 3: Connect via the ZLH UI

  1. In ZLH, navigate to Integrations > Add Integration
  2. Select Cisco Webex — there are no Webex-specific fields; the organization is the one the signing-in administrator belongs to
  3. Enter the Client ID and Client Secret from Step 1
  4. Click Connect — you are redirected to Webex to sign in
  5. Sign in as a full administrator of the organization and click Accept
  6. You are redirected back to ZLH with the integration active and a first sync queued

ZLH reads the signed-in administrator's profile after consent; their email domain must match the domain of your ZLH login.

What Gets Synced

ZLH lists every person in the organization through the People API, 100 per page, and resolves each license ID to its name through the Licenses API. For each person it captures:

  • Primary email and the Webex person ID (used as the stable identifier)
  • Status — active is imported as active; inactive and pending as inactive
  • Assigned licenses by name, stored as license types; an ID that the Licenses API does not return is kept as the raw ID
  • Last activity (stored as last login) and creation date

People without an email address, such as workspace or machine accounts, are skipped.

Troubleshooting

Issue Fix
Webex shows an error instead of the sign-in page The Redirect URI on the integration does not match {YOUR_ZLH_BASE_URL}/integrations/webex/callback exactly
"Authorization failed: ..." after Webex redirects back The sign-in was cancelled, or the integration is missing a scope ZLH requested. Tick both spark-admin scopes on the developer portal and retry
"Failed to complete OAuth handshake. Please check your credentials and try again." The Client ID or Client Secret does not match the integration. Regenerate the secret on the developer portal and re-enter it
"Failed to connect integration" immediately after consent ZLH could not read the signed-in user's profile. Reconnect as a full administrator with both scopes granted
"Access denied: you can only connect accounts from your organization's domain" The Webex administrator's email is on a different domain from your ZLH login. Reconnect with an administrator on your domain
Sync fails with webex: unexpected status 403 fetching licenses (or fetching people) The account that authorized is not a full administrator, or a scope was removed after consent. Click Reconnect on the integration's card on the ZLH home page and sign in as a full administrator
Sync fails with webex: unexpected status 401 The refresh token expired or was revoked. Click Reconnect on the integration's card on the ZLH home page
People are missing People without a primary email are skipped. Check the person's email in Control Hub
A license shows as a long ID rather than a name The Licenses API did not return that license; ZLH stores the ID as reported