wxcli 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
# Admin: Identity & SCIM
|
|
2
|
+
|
|
3
|
+
SCIM 2.0 user/group provisioning, Webex People/Groups APIs, identity org settings, and directory management.
|
|
4
|
+
|
|
5
|
+
## Sources
|
|
6
|
+
|
|
7
|
+
- [SCIM 2.0 Protocol (RFC 7644)](https://datatracker.ietf.org/doc/html/rfc7644) -- Standard protocol for cross-domain identity management
|
|
8
|
+
- [Webex SCIM 2.0 Users API](https://developer.webex.com/docs/api/v1/scim2-user) -- Official API docs
|
|
9
|
+
- [Webex People API](https://developer.webex.com/docs/api/v1/people) -- Official API docs
|
|
10
|
+
- [Webex Groups API](https://developer.webex.com/docs/api/v1/groups) -- Official API docs
|
|
11
|
+
- OpenAPI spec: `specs/webex-admin.json` -- Tags: SCIM 2 Users, SCIM 2 Groups, SCIM 2 Schemas, Bulk Manage SCIM 2 Users and Groups, Identity Organization, Groups, People
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Key Concepts
|
|
16
|
+
|
|
17
|
+
### SCIM 2.0 Protocol
|
|
18
|
+
|
|
19
|
+
SCIM (System for Cross-domain Identity Management) is a standardized REST protocol for provisioning and managing user identities across systems. Webex implements SCIM 2.0 at `/identity/scim/{orgId}/v2/` endpoints. Key SCIM concepts:
|
|
20
|
+
|
|
21
|
+
- **Resources** are Users and Groups, represented as JSON objects with standard schemas.
|
|
22
|
+
- **Schemas** define the attributes available on each resource type. Webex extends the core SCIM schemas with `urn:scim:schemas:extension:cisco:webexidentity:2.0:User` and `urn:scim:schemas:extension:cisco:webexidentity:2.0:Group`.
|
|
23
|
+
- **Filters** use SCIM filter syntax for search: `filter=userName eq "user@example.com"` or `filter=displayName co "Engineering"`. Operators: `eq`, `ne`, `co` (contains), `sw` (starts with), `pr` (present), `gt`, `ge`, `lt`, `le`.
|
|
24
|
+
- **Bulk operations** allow multiple create/update/delete operations in a single HTTP request via the `/Bulk` endpoint.
|
|
25
|
+
|
|
26
|
+
### PUT vs PATCH
|
|
27
|
+
|
|
28
|
+
Both SCIM user and group endpoints support two update methods:
|
|
29
|
+
|
|
30
|
+
- **PUT** (`update` commands) -- Replaces the entire resource. Any attribute not included in the PUT body is removed. Always GET the resource first, modify the JSON, then PUT the full object back.
|
|
31
|
+
- **PATCH** (`update-users` / `update-groups` commands) -- Partial update. Only the specified attributes are changed; all other attributes are left intact. Uses SCIM patch operations: `add`, `replace`, `remove`.
|
|
32
|
+
|
|
33
|
+
### scim-users vs people
|
|
34
|
+
|
|
35
|
+
Both manage user accounts, but serve different purposes:
|
|
36
|
+
|
|
37
|
+
| Aspect | `scim-users` | `people` |
|
|
38
|
+
|--------|-------------|----------|
|
|
39
|
+
| Protocol | SCIM 2.0 (RFC 7644) | Webex REST API |
|
|
40
|
+
| Base path | `/identity/scim/{orgId}/v2/Users` | `/v1/people` |
|
|
41
|
+
| Primary use | IdP sync, automated provisioning, directory integration | Webex-native user management, manual CRUD |
|
|
42
|
+
| Requires `orgId` arg | Yes | No (uses token's org) |
|
|
43
|
+
| Update methods | PUT (full replace) + PATCH (partial) | PUT only |
|
|
44
|
+
| Scopes | `identity:people_rw` / `identity:people_read` | `spark-admin:people_write` / `spark-admin:people_read` |
|
|
45
|
+
| Calling data | Not returned | Optional via `--calling-data true` |
|
|
46
|
+
|
|
47
|
+
Use `scim-users` when integrating with an external IdP (Okta, Azure AD, etc.) or doing bulk provisioning. Use `people` for Webex-native user management and when you need calling-specific data.
|
|
48
|
+
|
|
49
|
+
### scim-groups vs groups
|
|
50
|
+
|
|
51
|
+
| Aspect | `scim-groups` | `groups` |
|
|
52
|
+
|--------|--------------|----------|
|
|
53
|
+
| Protocol | SCIM 2.0 | Webex REST API |
|
|
54
|
+
| Base path | `/identity/scim/{orgId}/v2/Groups` | `/v1/groups` |
|
|
55
|
+
| Primary use | IdP group sync, directory groups | Webex-native group management |
|
|
56
|
+
| Requires `orgId` arg | Yes | No (uses token's org) |
|
|
57
|
+
| Update methods | PUT + PATCH | PATCH only |
|
|
58
|
+
| Member listing | Via `--include-members` on list/show, or dedicated `GET /Groups/{groupId}/Members` sub-endpoint (paginated, up to 500/page) | Separate `list-members` command |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Required Scopes
|
|
63
|
+
|
|
64
|
+
| Scope | Purpose |
|
|
65
|
+
|-------|---------|
|
|
66
|
+
| `identity:people_rw` | Read and write SCIM users, SCIM groups, and SCIM bulk operations. |
|
|
67
|
+
| `identity:people_read` | Read-only access to SCIM users and SCIM groups. |
|
|
68
|
+
| `identity:organizations_rw` | Read and write identity organization settings. |
|
|
69
|
+
| `identity:organizations_read` | Read-only access to identity organization settings. |
|
|
70
|
+
| `Identity:one_time_password` | Generate OTP for a user. |
|
|
71
|
+
| `spark-admin:people_write` | Create, update, and delete people (Webex REST API). |
|
|
72
|
+
| `spark-admin:people_read` | List and get people (Webex REST API). |
|
|
73
|
+
|
|
74
|
+
**Note:** SCIM endpoints (`scim-users`, `scim-groups`, `scim-bulk`) use `identity:*` scopes. Webex REST endpoints (`people`, `groups`) use `spark-admin:*` scopes. Mixing them up produces 403 errors.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Table of Contents
|
|
79
|
+
|
|
80
|
+
1. [SCIM Users (`scim-users`)](#1-scim-users-scim-users)
|
|
81
|
+
2. [SCIM Groups (`scim-groups`)](#2-scim-groups-scim-groups)
|
|
82
|
+
3. [SCIM Schemas (`scim-schemas`)](#3-scim-schemas-scim-schemas)
|
|
83
|
+
4. [SCIM Bulk Operations (`scim-bulk`)](#4-scim-bulk-operations-scim-bulk)
|
|
84
|
+
5. [Identity Organization (`identity-org`)](#5-identity-organization-identity-org)
|
|
85
|
+
6. [Groups (Webex REST API) (`groups`)](#6-groups-webex-rest-api-groups)
|
|
86
|
+
7. [People (Webex REST API) (`people`)](#7-people-webex-rest-api-people)
|
|
87
|
+
8. [Recipes](#recipes)
|
|
88
|
+
9. [Gotchas](#gotchas)
|
|
89
|
+
10. [See Also](#see-also)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 1. SCIM Users (`scim-users`)
|
|
94
|
+
|
|
95
|
+
SCIM 2.0 user provisioning and management. All commands require an `org-id` positional argument.
|
|
96
|
+
|
|
97
|
+
### Endpoints
|
|
98
|
+
|
|
99
|
+
| Method | Path | CLI Command |
|
|
100
|
+
|--------|------|-------------|
|
|
101
|
+
| GET | `/identity/scim/{orgId}/v2/Users` | `scim-users list` |
|
|
102
|
+
| POST | `/identity/scim/{orgId}/v2/Users` | `scim-users create` |
|
|
103
|
+
| GET | `/identity/scim/{orgId}/v2/Users/{userId}` | `scim-users show` |
|
|
104
|
+
| PUT | `/identity/scim/{orgId}/v2/Users/{userId}` | `scim-users update` |
|
|
105
|
+
| PATCH | `/identity/scim/{orgId}/v2/Users/{userId}` | `scim-users update-users` |
|
|
106
|
+
| DELETE | `/identity/scim/{orgId}/v2/Users/{userId}` | `scim-users delete` |
|
|
107
|
+
| GET | `/identity/scim/v2/Users/me` | `scim-users show-me` |
|
|
108
|
+
|
|
109
|
+
### Command Reference
|
|
110
|
+
|
|
111
|
+
| Command | Description | Key Options |
|
|
112
|
+
|---------|-------------|-------------|
|
|
113
|
+
| `list` | Search users with SCIM filters | `--filter`, `--attributes`, `--excluded-attributes`, `--sort-by`, `--sort-order`, `--start-index`, `--count`, `--return-groups`, `--include-group-details`, `--group-usage-types` |
|
|
114
|
+
| `create` | Create a SCIM user | `--user-name` (required), `--display-name`, `--title`, `--active/--no-active`, `--preferred-language`, `--locale`, `--timezone`, `--external-id`, `--nick-name`, `--profile-url`, `--json-body` |
|
|
115
|
+
| `show` | Get a single user by ID | `ORG_ID`, `USER_ID` (positional) |
|
|
116
|
+
| `update` | Full replace (PUT) of user | Same options as `create` plus `USER_ID` positional. **Replaces entire resource.** |
|
|
117
|
+
| `update-users` | Partial update (PATCH) of user | `--json-body` only (SCIM patch operations) |
|
|
118
|
+
| `delete` | Delete a user | `--force` to skip confirmation |
|
|
119
|
+
| `show-me` | Get authenticated user's own SCIM record | No `org-id` required. Requires user-level token. |
|
|
120
|
+
|
|
121
|
+
### CLI Examples
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# List all SCIM users in the org
|
|
125
|
+
wxcli scim-users list YOUR_ORG_ID
|
|
126
|
+
|
|
127
|
+
# Search for a specific user by email
|
|
128
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'userName eq "jsmith@example.com"'
|
|
129
|
+
|
|
130
|
+
# Search users by display name (contains)
|
|
131
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'displayName co "Smith"'
|
|
132
|
+
|
|
133
|
+
# Get specific user attributes only
|
|
134
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'userName sw "j"' --attributes "userName,displayName,emails"
|
|
135
|
+
|
|
136
|
+
# Create a new SCIM user
|
|
137
|
+
wxcli scim-users create YOUR_ORG_ID --user-name "newuser@example.com" --display-name "New User" --active
|
|
138
|
+
|
|
139
|
+
# Create user with full JSON body (for nested fields like name, emails, addresses)
|
|
140
|
+
wxcli scim-users create YOUR_ORG_ID --json-body '{
|
|
141
|
+
"userName": "jdoe@example.com",
|
|
142
|
+
"displayName": "Jane Doe",
|
|
143
|
+
"name": {"givenName": "Jane", "familyName": "Doe"},
|
|
144
|
+
"emails": [{"value": "jdoe@example.com", "type": "work", "primary": true}],
|
|
145
|
+
"active": true
|
|
146
|
+
}'
|
|
147
|
+
|
|
148
|
+
# Get a specific user
|
|
149
|
+
wxcli scim-users show YOUR_ORG_ID USER_ID -o json
|
|
150
|
+
|
|
151
|
+
# Full replace a user (PUT) -- always GET first to avoid data loss
|
|
152
|
+
wxcli scim-users update YOUR_ORG_ID USER_ID --json-body '{ ... full user JSON ... }'
|
|
153
|
+
|
|
154
|
+
# Partial update a user (PATCH) -- change only specific fields
|
|
155
|
+
wxcli scim-users update-users YOUR_ORG_ID USER_ID --json-body '{
|
|
156
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
157
|
+
"Operations": [
|
|
158
|
+
{"op": "replace", "path": "displayName", "value": "Jane M. Doe"},
|
|
159
|
+
{"op": "replace", "path": "title", "value": "Senior Engineer"}
|
|
160
|
+
]
|
|
161
|
+
}'
|
|
162
|
+
|
|
163
|
+
# Deactivate a user via PATCH
|
|
164
|
+
wxcli scim-users update-users YOUR_ORG_ID USER_ID --json-body '{
|
|
165
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
166
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
167
|
+
}'
|
|
168
|
+
|
|
169
|
+
# Delete a user (with confirmation skip)
|
|
170
|
+
wxcli scim-users delete YOUR_ORG_ID USER_ID --force
|
|
171
|
+
|
|
172
|
+
# Get your own SCIM identity (user-level token required)
|
|
173
|
+
wxcli scim-users show-me -o json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Raw HTTP Fallback
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# List SCIM users
|
|
180
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
181
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Users?filter=userName%20eq%20%22user%40example.com%22"
|
|
182
|
+
|
|
183
|
+
# Create a SCIM user
|
|
184
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
185
|
+
-H "Content-Type: application/json" \
|
|
186
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Users" \
|
|
187
|
+
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"user@example.com","displayName":"New User","active":true}'
|
|
188
|
+
|
|
189
|
+
# PATCH a SCIM user (partial update)
|
|
190
|
+
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
|
|
191
|
+
-H "Content-Type: application/json" \
|
|
192
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Users/USER_ID" \
|
|
193
|
+
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"replace","path":"active","value":false}]}'
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
> **Gotcha — PUT Replaces the Entire Resource:**
|
|
197
|
+
> The `scim-users update` and `scim-groups update` commands use HTTP PUT, which replaces the entire resource. If you PUT a user without including their `emails`, `phoneNumbers`, or `addresses`, those fields are removed.
|
|
198
|
+
>
|
|
199
|
+
> **Safe pattern:** Always GET the current resource first, modify the JSON, then PUT the full object back:
|
|
200
|
+
> ```bash
|
|
201
|
+
> # Step 1: GET current state
|
|
202
|
+
> wxcli scim-users show YOUR_ORG_ID USER_ID -o json > user.json
|
|
203
|
+
> # Step 2: Edit user.json to change what you need
|
|
204
|
+
> # Step 3: PUT the modified full object
|
|
205
|
+
> wxcli scim-users update YOUR_ORG_ID USER_ID --json-body "$(cat user.json)"
|
|
206
|
+
> ```
|
|
207
|
+
> **Better alternative:** Use PATCH (`update-users` / `update-groups`) for partial updates whenever possible.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 2. SCIM Groups (`scim-groups`)
|
|
212
|
+
|
|
213
|
+
SCIM 2.0 group provisioning and management. All commands require an `org-id` positional argument.
|
|
214
|
+
|
|
215
|
+
### Endpoints
|
|
216
|
+
|
|
217
|
+
| Method | Path | CLI Command |
|
|
218
|
+
|--------|------|-------------|
|
|
219
|
+
| GET | `/identity/scim/{orgId}/v2/Groups` | `scim-groups list` |
|
|
220
|
+
| POST | `/identity/scim/{orgId}/v2/Groups` | `scim-groups create` |
|
|
221
|
+
| GET | `/identity/scim/{orgId}/v2/Groups/{groupId}` | `scim-groups show` |
|
|
222
|
+
| GET | `/identity/scim/{orgId}/v2/Groups/{groupId}/Members` | *(raw HTTP only — no CLI command)* |
|
|
223
|
+
| PUT | `/identity/scim/{orgId}/v2/Groups/{groupId}` | `scim-groups update` |
|
|
224
|
+
| PATCH | `/identity/scim/{orgId}/v2/Groups/{groupId}` | `scim-groups update-groups` |
|
|
225
|
+
| DELETE | `/identity/scim/{orgId}/v2/Groups/{groupId}` | `scim-groups delete` |
|
|
226
|
+
|
|
227
|
+
> **Note — `GET /Groups/{groupId}/Members`:** This sub-endpoint returns members of a specific group with pagination support. Query params: `startIndex`, `count`, `memberType` (values: `user`, `machine`, `group`). Returns up to **500 members per page**. Preferred over `--include-members` on `list`/`show` when paginating large groups, since `--include-members` returns all members in a single response and can be slow or truncated for large groups.
|
|
228
|
+
>
|
|
229
|
+
> ```bash
|
|
230
|
+
> # Raw HTTP: get members of a SCIM group (first page)
|
|
231
|
+
> curl -s -H "Authorization: Bearer $TOKEN" \
|
|
232
|
+
> "https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID/Members?count=500&startIndex=1"
|
|
233
|
+
>
|
|
234
|
+
> # Filter by member type
|
|
235
|
+
> curl -s -H "Authorization: Bearer $TOKEN" \
|
|
236
|
+
> "https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID/Members?memberType=user&count=500"
|
|
237
|
+
> ```
|
|
238
|
+
|
|
239
|
+
### Command Reference
|
|
240
|
+
|
|
241
|
+
| Command | Description | Key Options |
|
|
242
|
+
|---------|-------------|-------------|
|
|
243
|
+
| `list` | Search groups with SCIM filters | `--filter`, `--attributes`, `--excluded-attributes`, `--sort-by`, `--sort-order`, `--start-index`, `--count`, `--include-members`, `--member-type` |
|
|
244
|
+
| `create` | Create a SCIM group | `--display-name` (required), `--external-id`, `--json-body` |
|
|
245
|
+
| `show` | Get a single group by ID | `--excluded-attributes` |
|
|
246
|
+
| `update` | Full replace (PUT) of group | `--display-name`, `--external-id`, `--json-body`. **Replaces entire resource.** |
|
|
247
|
+
| `update-groups` | Partial update (PATCH) of group | `--json-body` only (SCIM patch operations) |
|
|
248
|
+
| `delete` | Delete a group | `--force` to skip confirmation |
|
|
249
|
+
|
|
250
|
+
### CLI Examples
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# List all SCIM groups
|
|
254
|
+
wxcli scim-groups list YOUR_ORG_ID
|
|
255
|
+
|
|
256
|
+
# Search for a group by name
|
|
257
|
+
wxcli scim-groups list YOUR_ORG_ID --filter 'displayName eq "Engineering"'
|
|
258
|
+
|
|
259
|
+
# List groups with member details
|
|
260
|
+
wxcli scim-groups list YOUR_ORG_ID --include-members true --member-type user
|
|
261
|
+
|
|
262
|
+
# Create a SCIM group
|
|
263
|
+
wxcli scim-groups create YOUR_ORG_ID --display-name "DevOps Team"
|
|
264
|
+
|
|
265
|
+
# Create a group with members via JSON body
|
|
266
|
+
wxcli scim-groups create YOUR_ORG_ID --json-body '{
|
|
267
|
+
"displayName": "DevOps Team",
|
|
268
|
+
"members": [
|
|
269
|
+
{"value": "USER_ID_1", "type": "user"},
|
|
270
|
+
{"value": "USER_ID_2", "type": "user"}
|
|
271
|
+
]
|
|
272
|
+
}'
|
|
273
|
+
|
|
274
|
+
# Add a member to a group via PATCH
|
|
275
|
+
wxcli scim-groups update-groups YOUR_ORG_ID GROUP_ID --json-body '{
|
|
276
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
277
|
+
"Operations": [
|
|
278
|
+
{"op": "add", "path": "members", "value": [{"value": "USER_ID", "type": "user"}]}
|
|
279
|
+
]
|
|
280
|
+
}'
|
|
281
|
+
|
|
282
|
+
# Remove a member from a group via PATCH
|
|
283
|
+
wxcli scim-groups update-groups YOUR_ORG_ID GROUP_ID --json-body '{
|
|
284
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
285
|
+
"Operations": [
|
|
286
|
+
{"op": "remove", "path": "members[value eq \"USER_ID\"]"}
|
|
287
|
+
]
|
|
288
|
+
}'
|
|
289
|
+
|
|
290
|
+
# Delete a group
|
|
291
|
+
wxcli scim-groups delete YOUR_ORG_ID GROUP_ID --force
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Raw HTTP Fallback
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# List SCIM groups
|
|
298
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
299
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups"
|
|
300
|
+
|
|
301
|
+
# Search SCIM groups by name
|
|
302
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
303
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups?filter=displayName%20eq%20%22Engineering%22"
|
|
304
|
+
|
|
305
|
+
# Create a SCIM group
|
|
306
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
307
|
+
-H "Content-Type: application/json" \
|
|
308
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups" \
|
|
309
|
+
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],"displayName":"DevOps Team"}'
|
|
310
|
+
|
|
311
|
+
# Get a SCIM group by ID
|
|
312
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
313
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID"
|
|
314
|
+
|
|
315
|
+
# PUT (full replace) a SCIM group
|
|
316
|
+
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
|
|
317
|
+
-H "Content-Type: application/json" \
|
|
318
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID" \
|
|
319
|
+
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],"displayName":"DevOps Team","members":[{"value":"USER_ID","type":"user"}]}'
|
|
320
|
+
|
|
321
|
+
# PATCH a SCIM group (add member)
|
|
322
|
+
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
|
|
323
|
+
-H "Content-Type: application/json" \
|
|
324
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID" \
|
|
325
|
+
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"add","path":"members","value":[{"value":"USER_ID","type":"user"}]}]}'
|
|
326
|
+
|
|
327
|
+
# Delete a SCIM group
|
|
328
|
+
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
|
|
329
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Groups/GROUP_ID"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 3. SCIM Schemas (`scim-schemas`)
|
|
335
|
+
|
|
336
|
+
Retrieve the SCIM schema definitions that describe available attributes for Users and Groups. Useful for discovering which fields are available and their types before creating or updating resources.
|
|
337
|
+
|
|
338
|
+
### Endpoints
|
|
339
|
+
|
|
340
|
+
| Method | Path | CLI Command |
|
|
341
|
+
|--------|------|-------------|
|
|
342
|
+
| GET | `/Schemas/SCIM2/Group` | `scim-schemas show` |
|
|
343
|
+
| GET | `/Schemas/SCIM2/User` | `scim-schemas show-user` |
|
|
344
|
+
| GET | `/Schemas/SCIM2/{schemaId}` | `scim-schemas show-scim2` |
|
|
345
|
+
|
|
346
|
+
### Command Reference
|
|
347
|
+
|
|
348
|
+
| Command | Description | Key Options |
|
|
349
|
+
|---------|-------------|-------------|
|
|
350
|
+
| `show` | Get the Group schema definition | `-o json` |
|
|
351
|
+
| `show-user` | Get the User schema definition | `-o json` |
|
|
352
|
+
| `show-scim2` | Get a schema by its schema ID | `SCHEMA_ID` (positional), `-o json` |
|
|
353
|
+
|
|
354
|
+
### CLI Examples
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Get the SCIM User schema (discover all available user attributes)
|
|
358
|
+
wxcli scim-schemas show-user -o json
|
|
359
|
+
|
|
360
|
+
# Get the SCIM Group schema
|
|
361
|
+
wxcli scim-schemas show -o json
|
|
362
|
+
|
|
363
|
+
# Get a specific schema by ID (e.g., the Cisco extension schema)
|
|
364
|
+
wxcli scim-schemas show-scim2 "urn:scim:schemas:extension:cisco:webexidentity:2.0:User" -o json
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Key Schema URNs
|
|
368
|
+
|
|
369
|
+
| Schema URN | Description |
|
|
370
|
+
|------------|-------------|
|
|
371
|
+
| `urn:ietf:params:scim:schemas:core:2.0:User` | Core SCIM user attributes |
|
|
372
|
+
| `urn:ietf:params:scim:schemas:core:2.0:Group` | Core SCIM group attributes |
|
|
373
|
+
| `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User` | IETF Enterprise User Extension — carries `costCenter`, `organization`, `division`, `department`, `employeeNumber`, `manager`. Required for provisioning flows that map org-chart attributes from IdPs like Azure AD or Okta; also the source of the `department` attribute used in SCIM search recipes. |
|
|
374
|
+
| `urn:scim:schemas:extension:cisco:webexidentity:2.0:User` | Cisco/Webex extension attributes for users |
|
|
375
|
+
| `urn:scim:schemas:extension:cisco:webexidentity:2.0:Group` | Cisco/Webex extension attributes for groups |
|
|
376
|
+
| `urn:ietf:params:scim:api:messages:2.0:PatchOp` | Schema for PATCH operation payloads |
|
|
377
|
+
| `urn:ietf:params:scim:api:messages:2.0:BulkRequest` | Schema for bulk operation request payloads |
|
|
378
|
+
|
|
379
|
+
### Raw HTTP Fallback
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# Get the SCIM User schema
|
|
383
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
384
|
+
"https://webexapis.com/Schemas/SCIM2/User"
|
|
385
|
+
|
|
386
|
+
# Get the SCIM Group schema
|
|
387
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
388
|
+
"https://webexapis.com/Schemas/SCIM2/Group"
|
|
389
|
+
|
|
390
|
+
# Get a schema by ID (e.g., Cisco extension schema)
|
|
391
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
392
|
+
"https://webexapis.com/Schemas/SCIM2/urn:scim:schemas:extension:cisco:webexidentity:2.0:User"
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## 4. SCIM Bulk Operations (`scim-bulk`)
|
|
398
|
+
|
|
399
|
+
Execute multiple SCIM user/group operations in a single HTTP request. Supports creating, updating, and deleting users and groups in bulk.
|
|
400
|
+
|
|
401
|
+
### Endpoint
|
|
402
|
+
|
|
403
|
+
| Method | Path | CLI Command |
|
|
404
|
+
|--------|------|-------------|
|
|
405
|
+
| POST | `/identity/scim/{orgId}/v2/Bulk` | `scim-bulk create` |
|
|
406
|
+
|
|
407
|
+
### Command Reference
|
|
408
|
+
|
|
409
|
+
| Command | Description | Key Options |
|
|
410
|
+
|---------|-------------|-------------|
|
|
411
|
+
| `create` | Execute a bulk SCIM operation | `ORG_ID` (positional), `--fail-on-errors` (required), `--json-body` |
|
|
412
|
+
|
|
413
|
+
The `--fail-on-errors` parameter specifies the maximum number of individual operation failures before the entire bulk request is aborted.
|
|
414
|
+
|
|
415
|
+
### CLI Examples
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
# Bulk create multiple users
|
|
419
|
+
wxcli scim-bulk create YOUR_ORG_ID --fail-on-errors 5 --json-body '{
|
|
420
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
421
|
+
"failOnErrors": 5,
|
|
422
|
+
"Operations": [
|
|
423
|
+
{
|
|
424
|
+
"method": "POST",
|
|
425
|
+
"path": "/Users",
|
|
426
|
+
"data": {
|
|
427
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
428
|
+
"userName": "alice@example.com",
|
|
429
|
+
"displayName": "Alice Smith",
|
|
430
|
+
"name": {"givenName": "Alice", "familyName": "Smith"},
|
|
431
|
+
"emails": [{"value": "alice@example.com", "type": "work", "primary": true}],
|
|
432
|
+
"active": true
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"method": "POST",
|
|
437
|
+
"path": "/Users",
|
|
438
|
+
"data": {
|
|
439
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
440
|
+
"userName": "bob@example.com",
|
|
441
|
+
"displayName": "Bob Jones",
|
|
442
|
+
"name": {"givenName": "Bob", "familyName": "Jones"},
|
|
443
|
+
"emails": [{"value": "bob@example.com", "type": "work", "primary": true}],
|
|
444
|
+
"active": true
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
]
|
|
448
|
+
}'
|
|
449
|
+
|
|
450
|
+
# Bulk deactivate users
|
|
451
|
+
wxcli scim-bulk create YOUR_ORG_ID --fail-on-errors 10 --json-body '{
|
|
452
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
453
|
+
"failOnErrors": 10,
|
|
454
|
+
"Operations": [
|
|
455
|
+
{
|
|
456
|
+
"method": "PATCH",
|
|
457
|
+
"path": "/Users/USER_ID_1",
|
|
458
|
+
"data": {
|
|
459
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
460
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"method": "PATCH",
|
|
465
|
+
"path": "/Users/USER_ID_2",
|
|
466
|
+
"data": {
|
|
467
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
468
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
]
|
|
472
|
+
}'
|
|
473
|
+
|
|
474
|
+
# Bulk delete users
|
|
475
|
+
wxcli scim-bulk create YOUR_ORG_ID --fail-on-errors 0 --json-body '{
|
|
476
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
477
|
+
"failOnErrors": 0,
|
|
478
|
+
"Operations": [
|
|
479
|
+
{"method": "DELETE", "path": "/Users/USER_ID_1"},
|
|
480
|
+
{"method": "DELETE", "path": "/Users/USER_ID_2"}
|
|
481
|
+
]
|
|
482
|
+
}'
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Raw HTTP Fallback
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
489
|
+
-H "Content-Type: application/json" \
|
|
490
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Bulk" \
|
|
491
|
+
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],"failOnErrors":5,"Operations":[...]}'
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
> **Gotcha — Bulk Operations Can Partially Fail:**
|
|
495
|
+
> A `scim-bulk create` request can succeed for some operations and fail for others. The `--fail-on-errors` parameter controls the threshold: if the number of failed operations exceeds this value, the remaining operations are not attempted. Always check the response body, which contains per-operation `status` codes.
|
|
496
|
+
>
|
|
497
|
+
> Example partial failure response (abridged):
|
|
498
|
+
> ```json
|
|
499
|
+
> {
|
|
500
|
+
> "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkResponse"],
|
|
501
|
+
> "Operations": [
|
|
502
|
+
> {"method": "POST", "location": "/Users/NEW_ID_1", "status": "201"},
|
|
503
|
+
> {"method": "POST", "status": "409", "response": {"detail": "User already exists"}}
|
|
504
|
+
> ]
|
|
505
|
+
> }
|
|
506
|
+
> ```
|
|
507
|
+
|
|
508
|
+
> **Gotcha — 100-Operation Limit Per Bulk Request:**
|
|
509
|
+
> A single bulk request may contain a maximum of **100 operations**. If you need to process more than 100 users or groups, split the work into multiple `scim-bulk create` calls.
|
|
510
|
+
|
|
511
|
+
> **Warning — Bulk DELETE Is Irreversible:**
|
|
512
|
+
> Bulk DELETE operations on users cannot be undone. There is no recycle bin or undo for SCIM deletes — once a user is deleted, their Webex identity, messages, and associated data are gone. Always verify your target user IDs against a dry-run list before issuing bulk DELETE operations.
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## 5. Identity Organization (`identity-org`)
|
|
517
|
+
|
|
518
|
+
Manage identity-level organization settings and generate one-time passwords for users. All commands require an `org-id` positional argument.
|
|
519
|
+
|
|
520
|
+
### Endpoints
|
|
521
|
+
|
|
522
|
+
| Method | Path | CLI Command |
|
|
523
|
+
|--------|------|-------------|
|
|
524
|
+
| GET | `/identity/organizations/{orgId}` | `identity-org show` |
|
|
525
|
+
| PATCH | `/identity/organizations/{orgId}` | `identity-org update` |
|
|
526
|
+
| POST | `/identity/organizations/{orgId}/users/{userId}/actions/generateOtp` | `identity-org generate-otp` |
|
|
527
|
+
|
|
528
|
+
### Command Reference
|
|
529
|
+
|
|
530
|
+
| Command | Description | Key Options |
|
|
531
|
+
|---------|-------------|-------------|
|
|
532
|
+
| `show` | Get identity organization details | `ORG_ID` (positional) |
|
|
533
|
+
| `update` | Update organization settings | `--display-name`, `--preferred-language`, `--json-body` |
|
|
534
|
+
| `generate-otp` | Generate a one-time password for a user | `ORG_ID`, `USER_ID` (positional), `--json-body` |
|
|
535
|
+
|
|
536
|
+
### CLI Examples
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Get identity org details
|
|
540
|
+
wxcli identity-org show YOUR_ORG_ID -o json
|
|
541
|
+
|
|
542
|
+
# Update the org display name
|
|
543
|
+
wxcli identity-org update YOUR_ORG_ID --display-name "Acme Corp"
|
|
544
|
+
|
|
545
|
+
# Set default language for new users
|
|
546
|
+
wxcli identity-org update YOUR_ORG_ID --preferred-language "en_US"
|
|
547
|
+
|
|
548
|
+
# Generate OTP for a user (for first-time login or password reset)
|
|
549
|
+
wxcli identity-org generate-otp YOUR_ORG_ID USER_ID
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Raw HTTP Fallback
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
# Get identity org
|
|
556
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
557
|
+
"https://webexapis.com/identity/organizations/YOUR_ORG_ID"
|
|
558
|
+
|
|
559
|
+
# Update identity org
|
|
560
|
+
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
|
|
561
|
+
-H "Content-Type: application/json" \
|
|
562
|
+
"https://webexapis.com/identity/organizations/YOUR_ORG_ID" \
|
|
563
|
+
-d '{"displayName": "Acme Corp", "preferredLanguage": "en_US"}'
|
|
564
|
+
|
|
565
|
+
# Generate OTP
|
|
566
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
567
|
+
"https://webexapis.com/identity/organizations/YOUR_ORG_ID/users/USER_ID/actions/generateOtp"
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## 6. Groups (Webex REST API) (`groups`)
|
|
573
|
+
|
|
574
|
+
Webex-native group management. Does not require `org-id` -- uses the authenticated token's organization.
|
|
575
|
+
|
|
576
|
+
### Endpoints
|
|
577
|
+
|
|
578
|
+
| Method | Path | CLI Command |
|
|
579
|
+
|--------|------|-------------|
|
|
580
|
+
| GET | `/v1/groups` | `groups list` |
|
|
581
|
+
| POST | `/v1/groups` | `groups create` |
|
|
582
|
+
| GET | `/v1/groups/{groupId}` | `groups show` |
|
|
583
|
+
| PATCH | `/v1/groups/{groupId}` | `groups update` |
|
|
584
|
+
| DELETE | `/v1/groups/{groupId}` | `groups delete` |
|
|
585
|
+
| GET | `/v1/groups/{groupId}/members` | `groups list-members` |
|
|
586
|
+
|
|
587
|
+
### Command Reference
|
|
588
|
+
|
|
589
|
+
| Command | Description | Key Options |
|
|
590
|
+
|---------|-------------|-------------|
|
|
591
|
+
| `list` | List and search groups | `--filter`, `--attributes`, `--sort-by`, `--sort-order`, `--include-members`, `--start-index`, `--count` |
|
|
592
|
+
| `create` | Create a group | `--display-name` (required), `--external-id`, `--json-body` |
|
|
593
|
+
| `show` | Get group details | `GROUP_ID` (positional), `--include-members` |
|
|
594
|
+
| `update` | Update a group (PATCH) | `GROUP_ID` (positional), `--json-body` |
|
|
595
|
+
| `delete` | Delete a group | `GROUP_ID` (positional), `--force` |
|
|
596
|
+
| `list-members` | Get group members with pagination | `GROUP_ID` (positional), `--start-index`, `--count` |
|
|
597
|
+
|
|
598
|
+
### CLI Examples
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
# List all groups
|
|
602
|
+
wxcli groups list
|
|
603
|
+
|
|
604
|
+
# Search groups by name
|
|
605
|
+
wxcli groups list --filter 'displayName eq "Sales Team"'
|
|
606
|
+
|
|
607
|
+
# List groups with members included
|
|
608
|
+
wxcli groups list --include-members true
|
|
609
|
+
|
|
610
|
+
# Create a group
|
|
611
|
+
wxcli groups create --display-name "Support Team"
|
|
612
|
+
|
|
613
|
+
# Create a group with members via JSON body
|
|
614
|
+
wxcli groups create --json-body '{
|
|
615
|
+
"displayName": "Support Team",
|
|
616
|
+
"members": [
|
|
617
|
+
{"id": "PERSON_ID_1", "type": "user"},
|
|
618
|
+
{"id": "PERSON_ID_2", "type": "user"}
|
|
619
|
+
]
|
|
620
|
+
}'
|
|
621
|
+
|
|
622
|
+
# Get group details with members
|
|
623
|
+
wxcli groups show GROUP_ID --include-members true -o json
|
|
624
|
+
|
|
625
|
+
# List group members (paginated)
|
|
626
|
+
wxcli groups list-members GROUP_ID --count 100
|
|
627
|
+
|
|
628
|
+
# Update a group (add/remove members)
|
|
629
|
+
wxcli groups update GROUP_ID --json-body '{
|
|
630
|
+
"members": [
|
|
631
|
+
{"id": "PERSON_ID_1", "type": "user", "operation": "add"},
|
|
632
|
+
{"id": "PERSON_ID_3", "type": "user", "operation": "delete"}
|
|
633
|
+
]
|
|
634
|
+
}'
|
|
635
|
+
|
|
636
|
+
# Delete a group
|
|
637
|
+
wxcli groups delete GROUP_ID --force
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Raw HTTP Fallback
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
# List groups
|
|
644
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
645
|
+
"https://webexapis.com/v1/groups?includeMembers=true"
|
|
646
|
+
|
|
647
|
+
# Get group members
|
|
648
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
649
|
+
"https://webexapis.com/v1/groups/GROUP_ID/members?startIndex=1&count=100"
|
|
650
|
+
|
|
651
|
+
# Create a group
|
|
652
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
653
|
+
-H "Content-Type: application/json" \
|
|
654
|
+
"https://webexapis.com/v1/groups" \
|
|
655
|
+
-d '{"displayName": "Support Team"}'
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## 7. People (Webex REST API) (`people`)
|
|
661
|
+
|
|
662
|
+
Webex-native user management. Does not require `org-id` -- uses the authenticated token's organization. Supports Webex Calling data inclusion via `--calling-data`.
|
|
663
|
+
|
|
664
|
+
### Endpoints
|
|
665
|
+
|
|
666
|
+
| Method | Path | CLI Command |
|
|
667
|
+
|--------|------|-------------|
|
|
668
|
+
| GET | `/v1/people` | `people list` |
|
|
669
|
+
| POST | `/v1/people` | `people create` |
|
|
670
|
+
| GET | `/v1/people/{personId}` | `people show` |
|
|
671
|
+
| PUT | `/v1/people/{personId}` | `people update` |
|
|
672
|
+
| DELETE | `/v1/people/{personId}` | `people delete` |
|
|
673
|
+
| GET | `/v1/people/me` | `people list-me` |
|
|
674
|
+
|
|
675
|
+
### Command Reference
|
|
676
|
+
|
|
677
|
+
| Command | Description | Key Options |
|
|
678
|
+
|---------|-------------|-------------|
|
|
679
|
+
| `list` | List people in the org | `--email`, `--display-name`, `--id` (up to 85 IDs), `--roles`, `--calling-data`, `--location-id`, `--max`, `--exclude-status` |
|
|
680
|
+
| `create` | Create a person | `--display-name`, `--first-name`, `--last-name`, `--extension`, `--location-id`, `--org-id`, `--department`, `--manager`, `--manager-id`, `--title`, `--avatar`, `--json-body` |
|
|
681
|
+
| `show` | Get person details | `PERSON_ID` (positional) |
|
|
682
|
+
| `update` | Update a person (PUT) | `PERSON_ID` (positional), `--display-name`, `--first-name`, `--last-name`, `--nick-name`, `--extension`, `--location-id`, `--department`, `--manager`, `--manager-id`, `--title`, `--avatar`, `--login-enabled/--no-login-enabled`, `--json-body` |
|
|
683
|
+
| `delete` | Delete a person | `PERSON_ID` (positional), `--force` |
|
|
684
|
+
| `list-me` | Get your own details | `--calling-data` |
|
|
685
|
+
|
|
686
|
+
### CLI Examples
|
|
687
|
+
|
|
688
|
+
```bash
|
|
689
|
+
# List all people in the org
|
|
690
|
+
wxcli people list
|
|
691
|
+
|
|
692
|
+
# Search by email
|
|
693
|
+
wxcli people list --email "jsmith@example.com"
|
|
694
|
+
|
|
695
|
+
# Search by display name prefix
|
|
696
|
+
wxcli people list --display-name "John"
|
|
697
|
+
|
|
698
|
+
# List people with Webex Calling details
|
|
699
|
+
wxcli people list --calling-data true --location-id LOCATION_ID
|
|
700
|
+
|
|
701
|
+
# List people by multiple IDs
|
|
702
|
+
wxcli people list --id "ID1,ID2,ID3"
|
|
703
|
+
|
|
704
|
+
# Get a specific person
|
|
705
|
+
wxcli people show PERSON_ID -o json
|
|
706
|
+
|
|
707
|
+
# Create a new person (emails must be passed via --json-body)
|
|
708
|
+
wxcli people create --json-body '{
|
|
709
|
+
"emails": ["newuser@example.com"],
|
|
710
|
+
"displayName": "New User",
|
|
711
|
+
"firstName": "New",
|
|
712
|
+
"lastName": "User",
|
|
713
|
+
"orgId": "YOUR_ORG_ID"
|
|
714
|
+
}'
|
|
715
|
+
|
|
716
|
+
# Update a person's department and title
|
|
717
|
+
wxcli people update PERSON_ID --department "Engineering" --title "Staff Engineer"
|
|
718
|
+
|
|
719
|
+
# Disable a person's login
|
|
720
|
+
wxcli people update PERSON_ID --no-login-enabled
|
|
721
|
+
|
|
722
|
+
# Delete a person
|
|
723
|
+
wxcli people delete PERSON_ID --force
|
|
724
|
+
|
|
725
|
+
# Get your own details (with calling data)
|
|
726
|
+
wxcli people list-me --calling-data true -o json
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### Raw HTTP Fallback
|
|
730
|
+
|
|
731
|
+
```bash
|
|
732
|
+
# List people by email
|
|
733
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
734
|
+
"https://webexapis.com/v1/people?email=jsmith%40example.com"
|
|
735
|
+
|
|
736
|
+
# Get person with calling data
|
|
737
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
738
|
+
"https://webexapis.com/v1/people/PERSON_ID?callingData=true"
|
|
739
|
+
|
|
740
|
+
# Create a person
|
|
741
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
|
742
|
+
-H "Content-Type: application/json" \
|
|
743
|
+
"https://webexapis.com/v1/people" \
|
|
744
|
+
-d '{"emails":["user@example.com"],"displayName":"New User","firstName":"New","lastName":"User"}'
|
|
745
|
+
|
|
746
|
+
# Update a person (PUT -- sends full replacement)
|
|
747
|
+
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
|
|
748
|
+
-H "Content-Type: application/json" \
|
|
749
|
+
"https://webexapis.com/v1/people/PERSON_ID" \
|
|
750
|
+
-d '{ ... full person JSON ... }'
|
|
751
|
+
|
|
752
|
+
# Get my own details
|
|
753
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
754
|
+
"https://webexapis.com/v1/people/me?callingData=true"
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
> **Gotcha — People API: emails Must Use --json-body:**
|
|
758
|
+
> The `people create` command does not have a `--emails` CLI option. The `emails` field (an array of objects) is too complex for a simple CLI flag. Use `--json-body` to pass the emails array:
|
|
759
|
+
> ```bash
|
|
760
|
+
> wxcli people create --json-body '{"emails": ["user@example.com"], "displayName": "User Name"}'
|
|
761
|
+
> ```
|
|
762
|
+
|
|
763
|
+
> **Gotcha — People API: update is PUT (Full Replace):**
|
|
764
|
+
> Like the SCIM PUT, `people update` uses HTTP PUT. It replaces the entire person record. The CLI does **not** do a GET-merge-PUT for flag-based options -- it sends only the specified fields in the PUT body, which means unspecified fields may be cleared by the API. Always use `--json-body` with the full person record for safe updates, or use the GET-modify-PUT pattern shown in the SCIM section above.
|
|
765
|
+
|
|
766
|
+
> **Gotcha — `callingData=true` Caps Results at 100 Per Page:**
|
|
767
|
+
> When `--calling-data true` is specified on `people list`, the API limits results to **100 per page** (down from the normal 1000). If `--location-id` is also specified alongside `--calling-data true`, the cap drops further to **50 per page**. Paginate using `--start-index` (or the `@odata.nextLink` in the raw response) to retrieve the full result set.
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
771
|
+
## Recipes
|
|
772
|
+
|
|
773
|
+
### SCIM Bulk User Import
|
|
774
|
+
|
|
775
|
+
Import multiple users from a CSV/list in a single API call:
|
|
776
|
+
|
|
777
|
+
```bash
|
|
778
|
+
# Build a bulk request JSON file, then submit
|
|
779
|
+
wxcli scim-bulk create YOUR_ORG_ID --fail-on-errors 5 --json-body '{
|
|
780
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
781
|
+
"failOnErrors": 5,
|
|
782
|
+
"Operations": [
|
|
783
|
+
{
|
|
784
|
+
"method": "POST",
|
|
785
|
+
"path": "/Users",
|
|
786
|
+
"data": {
|
|
787
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
788
|
+
"userName": "user1@example.com",
|
|
789
|
+
"displayName": "User One",
|
|
790
|
+
"name": {"givenName": "User", "familyName": "One"},
|
|
791
|
+
"emails": [{"value": "user1@example.com", "type": "work", "primary": true}],
|
|
792
|
+
"active": true
|
|
793
|
+
}
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"method": "POST",
|
|
797
|
+
"path": "/Users",
|
|
798
|
+
"data": {
|
|
799
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
800
|
+
"userName": "user2@example.com",
|
|
801
|
+
"displayName": "User Two",
|
|
802
|
+
"name": {"givenName": "User", "familyName": "Two"},
|
|
803
|
+
"emails": [{"value": "user2@example.com", "type": "work", "primary": true}],
|
|
804
|
+
"active": true
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
]
|
|
808
|
+
}'
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
Check the response for per-operation status. Each operation in the response has its own `status` code (e.g., `201` for created, `409` for conflict/duplicate).
|
|
812
|
+
|
|
813
|
+
### Search Users by Email or Department
|
|
814
|
+
|
|
815
|
+
```bash
|
|
816
|
+
# SCIM: exact email match
|
|
817
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'userName eq "target@example.com"'
|
|
818
|
+
|
|
819
|
+
# SCIM: users whose email contains a domain
|
|
820
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'userName co "@acme.com"'
|
|
821
|
+
|
|
822
|
+
# People API: search by email
|
|
823
|
+
wxcli people list --email "target@example.com"
|
|
824
|
+
|
|
825
|
+
# People API: search by name prefix
|
|
826
|
+
wxcli people list --display-name "John"
|
|
827
|
+
|
|
828
|
+
# SCIM: search users by department (Enterprise Extension attribute)
|
|
829
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'department eq "Engineering"'
|
|
830
|
+
|
|
831
|
+
# SCIM: search users whose department starts with "Eng"
|
|
832
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'department sw "Eng"'
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
### Bulk Deactivate Stale Users
|
|
836
|
+
|
|
837
|
+
Deactivate users who should no longer have Webex access. Use PATCH for efficiency (no need to send the full user record):
|
|
838
|
+
|
|
839
|
+
```bash
|
|
840
|
+
# Step 1: Identify users to deactivate (list and filter externally)
|
|
841
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'active eq true' -o json > active_users.json
|
|
842
|
+
|
|
843
|
+
# Step 2: For each user to deactivate, PATCH their active status
|
|
844
|
+
wxcli scim-users update-users YOUR_ORG_ID USER_ID --json-body '{
|
|
845
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
846
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
847
|
+
}'
|
|
848
|
+
|
|
849
|
+
# Or use bulk operations for many users at once
|
|
850
|
+
wxcli scim-bulk create YOUR_ORG_ID --fail-on-errors 10 --json-body '{
|
|
851
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
852
|
+
"failOnErrors": 10,
|
|
853
|
+
"Operations": [
|
|
854
|
+
{"method": "PATCH", "path": "/Users/USER_ID_1", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}},
|
|
855
|
+
{"method": "PATCH", "path": "/Users/USER_ID_2", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}}
|
|
856
|
+
]
|
|
857
|
+
}'
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
### Group Membership Management
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
# Webex Groups API: list members of a group
|
|
864
|
+
wxcli groups list-members GROUP_ID
|
|
865
|
+
|
|
866
|
+
# Webex Groups API: add a member
|
|
867
|
+
wxcli groups update GROUP_ID --json-body '{
|
|
868
|
+
"members": [{"id": "PERSON_ID", "type": "user", "operation": "add"}]
|
|
869
|
+
}'
|
|
870
|
+
|
|
871
|
+
# SCIM Groups: add members via PATCH
|
|
872
|
+
wxcli scim-groups update-groups YOUR_ORG_ID SCIM_GROUP_ID --json-body '{
|
|
873
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
874
|
+
"Operations": [
|
|
875
|
+
{"op": "add", "path": "members", "value": [{"value": "SCIM_USER_ID", "type": "user"}]}
|
|
876
|
+
]
|
|
877
|
+
}'
|
|
878
|
+
|
|
879
|
+
# SCIM Groups: remove a specific member
|
|
880
|
+
wxcli scim-groups update-groups YOUR_ORG_ID SCIM_GROUP_ID --json-body '{
|
|
881
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
882
|
+
"Operations": [
|
|
883
|
+
{"op": "remove", "path": "members[value eq \"SCIM_USER_ID\"]"}
|
|
884
|
+
]
|
|
885
|
+
}'
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### OTP Generation
|
|
889
|
+
|
|
890
|
+
Generate a one-time password for a user who needs to sign in for the first time or has been locked out:
|
|
891
|
+
|
|
892
|
+
```bash
|
|
893
|
+
# Generate OTP for a user
|
|
894
|
+
wxcli identity-org generate-otp YOUR_ORG_ID USER_ID
|
|
895
|
+
|
|
896
|
+
# The response contains the OTP value -- share it securely with the user
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## Gotchas
|
|
902
|
+
|
|
903
|
+
### /me Endpoints Require User-Level Tokens
|
|
904
|
+
|
|
905
|
+
`scim-users show-me` and `people list-me` hit the `/me` endpoint, which returns the identity of the authenticated user. These commands fail with admin service-app tokens because service apps do not represent a person. Use a user-level OAuth token (authorization code grant flow) instead.
|
|
906
|
+
|
|
907
|
+
### orgId Requirement on SCIM Commands
|
|
908
|
+
|
|
909
|
+
All SCIM commands (`scim-users`, `scim-groups`, `scim-bulk`) require `ORG_ID` as a positional argument because the org ID is part of the URL path (`/identity/scim/{orgId}/v2/...`). It cannot be omitted or inferred from the token. The Webex REST API commands (`people`, `groups`) do not require it -- they use the org implied by the token.
|
|
910
|
+
|
|
911
|
+
### Scope Troubleshooting for Identity Scopes
|
|
912
|
+
|
|
913
|
+
SCIM endpoints use `identity:*` scopes, not the `spark-admin:*` scopes used by People and Groups. If you get a 403 on SCIM endpoints, check:
|
|
914
|
+
|
|
915
|
+
1. Your integration/service-app has `identity:people_rw` or `identity:people_read` granted.
|
|
916
|
+
2. For `identity-org` endpoints, you need `identity:organizations_rw` or `identity:organizations_read`.
|
|
917
|
+
3. For OTP generation, you need `Identity:one_time_password` (note the capital "I" in `Identity`). An alternative scope is `Identity:Config`.
|
|
918
|
+
4. These identity scopes must be explicitly requested during OAuth authorization. They are separate from the `spark-admin:people_*` scopes.
|
|
919
|
+
|
|
920
|
+
### SCIM Filter URL Encoding
|
|
921
|
+
|
|
922
|
+
SCIM filter values must be URL-encoded when used in raw HTTP requests. The CLI handles this automatically for the `--filter` parameter, but if you are using `curl` directly, you must encode the filter:
|
|
923
|
+
|
|
924
|
+
```bash
|
|
925
|
+
# CLI handles encoding automatically
|
|
926
|
+
wxcli scim-users list YOUR_ORG_ID --filter 'userName eq "user@example.com"'
|
|
927
|
+
|
|
928
|
+
# Raw curl requires manual encoding
|
|
929
|
+
curl -s -H "Authorization: Bearer $TOKEN" \
|
|
930
|
+
"https://webexapis.com/identity/scim/YOUR_ORG_ID/v2/Users?filter=userName%20eq%20%22user%40example.com%22"
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
### Bracket Filter Syntax — No Space Before `[`
|
|
934
|
+
|
|
935
|
+
The official docs show `phoneNumbers [ type eq "mobile" and value eq "..." ]` with a space before `[`. This does not parse correctly. The working syntax has no space:
|
|
936
|
+
|
|
937
|
+
```
|
|
938
|
+
phoneNumbers[type eq "alternate1" and value eq "+19197010928"]
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
URL encoded:
|
|
942
|
+
```
|
|
943
|
+
phoneNumbers%5Btype%20eq%20%22alternate1%22%20and%20value%20eq%20%22%2B19197010928%22%5D
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
### `phoneNumbers.value` Dot Notation Not Implemented
|
|
947
|
+
|
|
948
|
+
The supported attributes table lists `phoneNumbers.value` with `eq`, `sw`, `ew` operators. In practice this returns:
|
|
949
|
+
|
|
950
|
+
```json
|
|
951
|
+
{"status": "400", "scimType": "invalidFilter", "details": "The user's attribute phoneNumbers.value in request can not find correspond table name."}
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
Use the bracket filter syntax instead: `phoneNumbers[type eq "alternate1" and value eq "..."]`.
|
|
955
|
+
|
|
956
|
+
### `+` in Phone Number Filter Values Must Be Encoded as `%2B`
|
|
957
|
+
|
|
958
|
+
The SCIM server decodes `+` in query strings as a space (form encoding). A filter like `value eq "+19197010928"` with a literal `+` in the URL will be received by the server as `value eq " 19197010928"` and return zero results.
|
|
959
|
+
|
|
960
|
+
Always encode `+` as `%2B` in filter values:
|
|
961
|
+
|
|
962
|
+
```
|
|
963
|
+
# Wrong — + decoded as space, zero results
|
|
964
|
+
filter=phoneNumbers%5Btype%20eq%20%22alternate1%22%20and%20value%20eq%20%22+19197010928%22%5D
|
|
965
|
+
|
|
966
|
+
# Correct — %2B preserved as literal +
|
|
967
|
+
filter=phoneNumbers%5Btype%20eq%20%22alternate1%22%20and%20value%20eq%20%22%2B19197010928%22%5D
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
### SCIM from WxCC Flow Designer HTTP Request Nodes
|
|
971
|
+
|
|
972
|
+
The SCIM API requires `identity:people_read` scope — separate from `spark-admin:people_read`. A PAT from developer.webex.com works for testing but expires after 12 hours. For production, use an OAuth Integration or Service App with `identity:people_read` explicitly selected.
|
|
973
|
+
|
|
974
|
+
**Two-node pattern to look up a user by alternate1 phone number and retrieve their profile:**
|
|
975
|
+
|
|
976
|
+
**Node 1 — Search by phone number:**
|
|
977
|
+
- URL: `https://webexapis.com/identity/scim/{orgId}/v2/Users`
|
|
978
|
+
- Query param key: `filter`
|
|
979
|
+
- Query param value (with `DNIS` variable containing digits only, no `+`): `phoneNumbers%5Btype%20eq%20%22alternate1%22%20and%20value%20eq%20%22%2B{{DNIS}}%22%5D`
|
|
980
|
+
- JSONPath to extract user ID: `$.Resources[0].id` → store in e.g. `StoreUserPersonId`
|
|
981
|
+
|
|
982
|
+
**Node 2 — Get full profile by ID:**
|
|
983
|
+
- URL: `https://webexapis.com/identity/scim/{orgId}/v2/Users/{{StoreUserPersonId}}`
|
|
984
|
+
- No filter needed
|
|
985
|
+
- JSONPath to extract alternate1 value: `$.phoneNumbers[?(@.type=='alternate1')].value`
|
|
986
|
+
|
|
987
|
+
**Stripping `+` from DNIS in Flow Designer:**
|
|
988
|
+
|
|
989
|
+
DNIS arrives in E.164 format (e.g. `+19197010928`). Strip the `+` using a Set Variable node before the HTTP node:
|
|
990
|
+
|
|
991
|
+
```
|
|
992
|
+
{{NewContact.DNIS | slice(1)}}
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
- `| slice(1)` works in WxCC Flow Designer (Pebble)
|
|
996
|
+
- `| replace("+", "%2B")` does NOT work — `+` is a regex special character and fails silently
|
|
997
|
+
- `.substring(1)` does NOT work in Flow Designer expression context
|
|
998
|
+
- Hardcode `%2B` in the filter template and substitute only the digits via `{{DNIS}}`
|
|
999
|
+
|
|
1000
|
+
---
|
|
1001
|
+
|
|
1002
|
+
## See Also
|
|
1003
|
+
|
|
1004
|
+
- [provisioning.md](provisioning.md) -- For Webex Calling user provisioning (licenses, extensions, locations)
|
|
1005
|
+
- [person-call-settings-handling.md](person-call-settings-handling.md) -- For calling-specific person settings (forwarding, DND, sim ring)
|
|
1006
|
+
- [person-call-settings-behavior.md](person-call-settings-behavior.md) -- For calling behavior, hoteling, numbers
|
|
1007
|
+
- [authentication.md](authentication.md) -- OAuth flows, token types, scope management
|